代码之家  ›  专栏  ›  技术社区  ›  Nareshkumar

我可以强制iPhone用户升级应用程序吗?

  •  44
  • Nareshkumar  · 技术社区  · 15 年前

    在iTunes商店中有新版本的应用程序后,是否可以强制用户升级?

    我目前正在处理一个申请。但是,每当上载较新版本时,我都要强制升级,因为升级将具有更多功能,并且我要放弃以前的版本。在iPhone的默认情况下,这是可能的,还是我必须编写自己的实现来检查当前版本并将其与商店进行比较?

    13 回复  |  直到 7 年前
        1
  •  4
  •   Michael Eakins    7 年前

    系统处理应用程序更新的唯一方法是提示用户在标准AppStore应用程序中提供更新。
    另外,独立应用程序不知道可用的更新,因此需要实现Web服务,应用程序可以在其中检查当前版本是否有效。
    我不确定这是否符合苹果的应用程序规则,比如(虽然找不到证明链接),你不能上传应用程序的试用版。

    *编辑* 这个答案不再是真的了。请参阅其他对当前真相的乐观回答。

        2
  •  34
  •   Dilip Rajkumar    13 年前

    我通过从iTunesWebService获取版本并与当前版本进行比较来完成此功能。以下是我的代码

            NSString *version = @"";
            NSURL *url = [NSURL URLWithString:@"http://itunes.apple.com/lookup?id=<Your app ID>"];
            versionRequest = [ASIFormDataRequest requestWithURL:url];
            [versionRequest setRequestMethod:@"GET"];
            [versionRequest setDelegate:self];
            [versionRequest setTimeOutSeconds:150];
            [versionRequest addRequestHeader:@"Content-Type" value:@"application/json"]; 
            [versionRequest startSynchronous];
    
            //Response string of our REST call
            NSString* jsonResponseString = [versionRequest responseString];
    
            NSDictionary *loginAuthenticationResponse = [jsonResponseString objectFromJSONString];
    
            NSArray *configData = [loginAuthenticationResponse valueForKey:@"results"];
    
            for (id config in configData) 
            {
                version = [config valueForKey:@"version"];
            }
       //Check your version with the version in app store
            if (![version isEqualToString:[itsUserDefaults objectForKey:@"version"]]) 
            {
                ProAlertView *createUserResponseAlert = [[ProAlertView alloc] initWithTitle:@"New Version!!" message: @"A new version of app is available to download" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: @"Download", nil];
            [createUserResponseAlert show]; 
            [createUserResponseAlert release];
            }
    

    并将应用程序ID放到iTunes链接中,请参见下面的代码。

    - (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
        // the user clicked one of the OK/Cancel buttons
        if (buttonIndex == 1)
        {
            NSString *iTunesLink = @"itms-apps://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftwareUpdate?id=<appid>&mt=8";
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
        }
    }
    

    注意:您需要jsonkit框架工作和asiHTTP框架工作来进行WebService调用。

        3
  •  20
  •   datinc    10 年前

    您可以检测应用程序是否需要更新,然后采取一些自定义操作,如提醒用户更新可用。下面是一个代码段,用于检测是否有可用的更新。

    -(BOOL) needsUpdate{
        NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
        NSString* appID = infoDictionary[@"CFBundleIdentifier"];
        NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/lookup?bundleId=%@", appID]];
        NSData* data = [NSData dataWithContentsOfURL:url];
        NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    
        if ([lookup[@"resultCount"] integerValue] == 1){
            NSString* appStoreVersion = lookup[@"results"][0][@"version"];
            NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];
            if (![appStoreVersion isEqualToString:currentVersion]){
                NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
                return YES;
            }
        }
        return NO;
    }
    
        4
  •  18
  •   BadPirate    14 年前

    如果你必须这样做,你可以启动应用商店,这样你的用户就可以从那里得到最新的版本。我建议让这个选项成为可选的,或者至少先展示一个对话。

    // iTunesLink should be your applications link
    NSString *iTunesLink = @"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&mt=8";
    
    
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
    
        5
  •  9
  •   Juan Carlos Méndez    8 年前

    这个问题最初是7年前发布的,虽然有些答案仍然相关,但这里有一个更为新的方法。

    我推荐 https://github.com/ArtSabintsev/Siren 这是斯威夫特3兼容,可以安装可可或迦太基。

    Cocoapods,Swift 3支持:

    pod 'Siren'

    Carthage:

    github "ArtSabintsev/Siren"

        6
  •  5
  •   Aaron Cooley    10 年前

    用于强制升级的系统 应该 成为每个依赖于该应用程序外部事物的应用程序的一部分。苹果和谷歌都声称,如果一个应用程序使用外部的东西,那么外部的API应该永远存在,永远不会改变,等等,但这是不现实的。如果是这样,如果应用所依赖的服务可以改变,那么 必须 这是应用程序检查和查看是否应该限制功能并提示用户获取最新版本的一种方法,否则事情就会神秘地失败。

    这可能也是苹果和谷歌提供的东西,但它们并不是所有游戏以外的应用都需要构建它,所以…

    我已经启动了一个基于Rails的开源(Apache2.0)项目来创建这个问题的解决方案。它被称为应用程序[ctrl],这是一项正在进行的工作,但欢迎您使用它,我欢迎任何形式的贡献。如果我能在空闲时间启动并运行这个程序,我会向所有应用程序开发人员提供一些非常合理的免费服务,当然,每家公司都可以自行启动它的部署。

    它在Github上: https://github.com/SlalomDigital/ApplicationCtrl

    贡献并帮助我永远解决这个问题!

        7
  •  4
  •   Community CDub    8 年前

    您的业务/设计计划不应包含“强制用户”这一短语。当你让他们做某事时,人们会生气。想象一下,有一天早上,一个用户匆匆打开你漂亮的小应用,却发现你强迫他升级,然后他才能使用这个应用来满足他的需要。想象一下,他被困在野外,不得不用边缘下载。他不会高兴的。

    如果您遵循这个计划足够长的时间,其中一个升级将不可避免地引入一个明显的bug。如果你强迫用户使用有缺陷的版本,他们会反抗。

    每当我看到用来描述新版本软件的“更多特性”时,我都会被经验所束缚,因为这必然意味着特性膨胀。设计师倾向于不断地将越来越多的功能移植到应用程序上,直到一个应用程序完成了所有的工作。在iPhone这样的平台上,让一个应用程序对许多事情的处理迅速压倒了界面和应用程序的响应能力,这一点尤其危险。

    edit01:我的评论在这里 How to Update an Application After Users Pay For Upgrade 也可能与你的计划有关。如果你的升级设计将苹果排除在收入循环之外,那它是不可能的。

    更新:

    只是根据下面的评论来澄清:是的,有时候你需要用户升级。但是,这与 设计 应用程序 从一开始 每次开发人员发布新版本时强制用户升级。

    这样的设计是为了让开发人员的生活更轻松,而不是让用户的生活更轻松。每当用户为了他们没有要求或者可能不想要的利益而花时间进行升级时,您都会占用客户的时间和资源。将时间和精力从开发人员转移到用户身上的设计是糟糕的设计,因为人们最终购买软件是为了自己的利益。当你降低收益时,你会降低软件的最终盈利能力。

    因此,任何设计人员都不应该设计强迫用户做用户不想做的事情的软件,除非它是绝对的技术需求。这当然是一个经验法则,但它是一个非常好的法则。

        8
  •  4
  •   Steig    8 年前

    我对应用商店的应用更新正是因为这个原因被拒绝的。我们添加了一个功能来对照当前版本检查已安装的版本,如果它不是受支持的版本,我们将强制它们更新。

    苹果拒绝了这一点。

    回到设计板上!

        9
  •  3
  •   kubi    15 年前

    没有自动化的方法,你必须手动写一些东西。

        10
  •  3
  •   Emil Sørensen Rais    9 年前

    其他答案表明,必须自己实现强制更新功能。 真可惜,我真希望不是这样。 我对iOS应用程序的第一次更新将于明天发布,幸运的是 这不会有问题,因为我们只对应用程序进行了更改。 然而,当我们最终改变Web服务的结构时,它对 能够强制更新,这样我们的服务器就不必支持每个应用程序版本。

    但是,除了强制更新之外,还有一种选择,在这个线程中似乎没有提到这一点。 您可以让每个生成数据的WebService调用在数据上附加一个模式, 它告诉应用程序如何在应用程序中反序列化数据。 这使您能够更改由GET请求生成的数据的结构,而不必破坏应用程序中的反序列化。 当然,这假设您所写的解释器本身不会改变,但当它成熟时,这是一个合理的假设。

    POST请求可以通过交互“模式化”。 有了这个,我的意思是,在您提出每个帖子请求之前,您都会询问如何调用最新的Web服务的说明。 您使用附加的模式来处理这些指令,然后实际调用WebService。 本质上,这意味着每个POST请求都需要2个请求,但这也可以。

    但是,无论您是否实施强制更新或模式解释,功能都必须在应用程序到达应用程序商店时从第1天起出现在应用程序中。 否则你就一团糟了。如果苹果为美国开发者实施强制更新,那么所有这些复杂性都是不必要的。 如果存在强制更新,模式解释仍然是可用性的改进。 但苹果没有强制更新,这让我有点恼火,因为至少有了它,人们可以在应用发布后引入自己的反中断更新措施。

        11
  •  1
  •   C-H-E-F    8 年前

    大家好,以后我发现这个教程可以帮助任何人,它帮助了我。

    http://codewithchris.com/tutorial-how-to-implement-in-app-update-functionality-in-your-iphoneipad-app/

    编辑(您的代码看起来与下面类似):

    // Try to get version 
    NSString *versionNumber = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    
    NSURL *updateUrl = [NSURL URLWithString:@"http://yourdomain.com/yourupdatefile.xml"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:updateUrl
                                                cachePolicy:NSURLCacheStorageNotAllowed
                                            timeoutInterval:20.0];
    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
                                         returningResponse:&response
                                                     error:&error];
    // Check no error, then parse data
    if (error == nil)
    {
        // Parse response into a dictionary
        NSPropertyListFormat format;
        NSString *errorStr = nil;
        NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:data
                                                                    mutabilityOption:NSPropertyListImmutable
                                                                              format:&format
                                                                    errorDescription:&errorStr];        
        if (errorStr == nil)
        {
            @try {
    
                // Try to see if the current app version exists in the update xml
                NSString *itunesUrl = [dictionary objectForKey:versionNumber];
    
                if (itunesUrl)
                {
                    // Show dialog to ask user to update!
                }
                else {
                    // Version not in XML
                }
            } @catch (NSException *e) {
                // Error with retrieving the key
            }
        }
        else {
            // Error with parsing data into dictionary
        }
    }
    

    然而,经过进一步的研究,我发现如果您不使用服务器,这是一个很好的解决方案。

    -(BOOL) needsUpdate{
        NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
        NSString* appID = infoDictionary[@"CFBundleIdentifier"];
        NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/lookup?bundleId=%@", appID]];
        NSData* data = [NSData dataWithContentsOfURL:url];
        NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    
        if ([lookup[@"resultCount"] integerValue] == 1){
            NSString* appStoreVersion = lookup[@"results"][0][@"version"];
            NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];
            if (![appStoreVersion isEqualToString:currentVersion]){
                NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
                return YES;
            }
        }
        return NO;
    }
    

    在:

    if (![appStoreVersion isEqualToString:currentVersion]){
                    NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
                    return YES;
                }
    

    如果代码不相等,您设置要执行的操作的代码部分,这是您将用户发送到应用商店下载最新版本的地方。

        12
  •  0
  •   Ruchin Somal    8 年前

    您可以使用以下URL获取任何应用程序的信息 你只知道你的应用程序的苹果ID。

    你可以在 itunesconnect.com >您的应用程序>应用程序信息页

    得到: http://itunes.apple.com/lookup?id=

        13
  •  -10
  •   Tim    15 年前

    当然没有办法。用户应该决定是否要下载应用程序的更新版本。

    如果有新版本,AppStore会显示,所以我也不认为苹果会允许这样做。我也不知道你会怎么做?你可以通过网络连接来检查它,但这不是苹果喜欢的方式,所以你没有机会这样做。

    推荐文章