我可以强制iPhone用户升级应用程序吗?
一旦在iTunes Store中有新版本的应用程序可用,是否可以强制用户进行升级?
我目前正在处理一个应用程序。 不过,我想强制升级,只要我上传一个新版本,因为升级将有更多的function,我想放弃以前的版本。 这是可能的iPhone默认情况下,或者我必须写我自己的实现来检查当前版本,并将其与商店进行比较?
系统处理应用程序更新的唯一方法是提示用户在标准AppStore应用程序中可以使用该更新。
此外,独立应用程序不知道可用的更新,因此您需要实现您的Web服务,应用程序可以检查当前版本是否有效。
而且我不确定这是否符合Apple关于应用程序的规则,例如(虽然找不到证据链接),但不能上传应用程序的试用版本。
*编辑*这个答案不再是真实的。 查看当前真相的其他有争议的答案。
我已经通过从iTunes Web服务获取版本,并与当前版本进行比较来完成此function。以下是我的代码
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电话。
如果你绝对必须的话,你可以启动App Store,让你的用户可以从那里获得最新版本。 我会build议做这个select,或者至less提出一个对话。
// 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]];
您可以检测应用程序是否需要更新,然后执行一些自定义操作,例如提醒用户更新可用。 这是检测更新是否可用的代码片段。
-(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; }
您的业务/devise计划不应包含“强制用户”一词。 当你让他们做某事时,人们会生气。 想象一下,用户急于在一天早晨打开你漂亮的小应用程序,只发现你迫使他升级,然后才能使用应用程序来满足他的需求。 想象一下,他在野外必须使用Edge进行下载。 他不会高兴的。
如果你遵循这个计划足够长的时间,你的一个升级将不可避免地引入一个明显的错误。 如果你强迫用户使用越野车版本,他们将反抗。
每当我看到用于描述新版本软件的“更多function”时,我总是受到经验的限制,因为这不可避免地意味着function膨胀。 devise师倾向于将越来越多的function移植到应用程序上,直到一个应用程序完成一切。 在iPhone这样的平台上,这使得一个应用程序做了很多事情迅速地压倒了应用程序的界面和响应能力,这是非常危险的。
Edit01:这里我的评论如何在用户付费升级后更新应用程序也可能与您的计划有关。 如果您的升级devise将苹果从收入循环中解脱出来,那么它就是一个非起步者。
更新:
只是为了澄清根据下面的评论:是的,有时你不得不要求用户升级。 但是,这与从一开始就devise应用程序有很大的不同,因为每次开发人员发布新版本时都要强制用户进行升级。
这样的devise旨在使开发者的生活变得轻松而不是用户的生活。 每当用户不得不花费时间进行升级以获得他们没有要求或可能不想要的好处时,您就已经花费了客户的时间和资源。 将开发人员的时间和精力从开发者转移到用户的devise是不好的devise,因为人们为了自己的利益最终购买软件。 当你减less这个收益时,你会降低软件的最终收益率。
所以,没有devise师应该devise软件来强制用户去做一些用户不希望的事情,除非它是绝对的技术需求。 这当然是一个经验法则,但它是一个非常好的。
有没有自动的方式来做到这一点,你将不得不手动写一些东西。
强制升级的系统应该是每个应用程序的一部分,这些应用程序依赖于该应用程序的外部。 苹果和谷歌都声称,如果一个应用程序使用外部的东西,那么外部的API应该永远活着,永远不会改变等等,但这是不切实际的。 如果是这样的话,如果应用程序依赖的服务可以改变,那么必须有一种方式让应用程序检查它是否应该限制function,并提示用户获得最新版本,否则事情就会神秘地失败。
这可能,也应该是苹果和谷歌提供的东西,但他们并不是每个应用程序在几个游戏之外需要build立这个,所以…
我已经开始了一个基于rails的开源(Apache 2.0)项目来为这个问题创build一个解决scheme。 这就是所谓的应用程序 – [Ctrl],这是一个正在进行的工作,但欢迎您使用它,我欢迎任何forms的贡献。 如果我可以在业余时间把这件事情搞清楚,我会把这个提供给所有的应用程序开发人员,提供一些非常合理的免费服务,当然,每个公司总是能够启动它自己的部署。
它在GitHub上: https : //github.com/SlalomDigital/ApplicationCtrl
贡献并帮助我解决这个问题!
这个问题最初是7年前发布的,尽pipe一些答案仍然相关,但这是一个更新的方法。
我推荐使用Swift 3兼容的https://github.com/ArtSabintsev/Siren ,可以使用Cocoapods或Carthage进行安装。
CocoaPods,Swift 3支持:
pod 'Siren'
迦太基:
github "ArtSabintsev/Siren"
其他答案表明,必须自己实现强制更新function。 真是太遗憾了,我希望不是这样。 我第一次更新到iOS应用程序将在明天发布,幸运的是,这不会成为问题,因为我们只对应用程序进行了更改。 然而,当我们最终改变我们的Web服务的结构时,能够强制更新将是非常有用的,这样我们的服务器就不必支持每一个应用程序版本。
有一个替代强制更新,但似乎没有在这个线程中提到。 您可以让每个产生数据的Web服务调用都附加一个模式到数据,告诉应用程序应该如何在您的应用程序中反序列化数据。 这使您可以更改由get-requests生成的数据的结构,而不会破坏应用程序中的反序列化。 当然这假设你所写的解释者本身不会自己改变,但当它成熟时,这是一个合理的假设。
邮寄请求可以通过交互来“模式化”。 有了这个,我的意思是说,在你做出每一个请求之前,你都要询问如何调用最新的web服务。 您使用附加的模式处理指令,然后对Web服务进行实际调用。 基本上这意味着每个post请求都需要2个请求,但是可以。
但是,无论您是否实施强制更新或模式解释,function都必须在应用程序从第1天开始到达应用程序商店时出现。 否则,你陷入了同样的混乱。 如果苹果为我们的开发者实施强制更新,所有这些复杂性都是不必要的。 如果强制更新存在,模式解释仍然是一个可用性改进。 但是,苹果并没有强迫更新,至less有一点让我感到不安,因为至less在这个版本中,应用程序发布之后,可以引入自己的反间谍更新措施。
我的应用程序更新到应用程序商店刚刚被拒绝正是由于这个原因。 我们添加了一个function来检查当前版本的安装版本,如果它不是受支持的版本,我们强制它们更新。
苹果拒绝了这个。
所以回到devise委员会!
您好,今后任何人,我发现这个教程应该帮助任何人,它帮助了我。
编辑(你的代码看起来类似于下面的内容):
// 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 } }
然而,经过进一步的研究,我发现这是一个很好的解决scheme,如果你不使用服务器。
-(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; }
你设置的代码的一部分,如果你不想要做什么,这是你发送用户到app store下载最新版本的地方。
您可以使用以下url获取任何应用程序的信息您只知道您的应用程序的Apple ID。
您可以在itunesconnect.com
>您的应用>应用信息页面中获取此Apple ID
GET: http : //itunes.apple.com/lookup?id=
当然没有办法。 如果用户想下载新版本的应用程序,用户应该做出决定。
AppStore会显示是否有新版本,所以我也不认为苹果会允许这个。 我也不知道你会怎么做? 您可以通过互联网连接进行检查,但这不是苹果喜欢的方式,所以您不会有机会这样做。