Могу ли я заставить пользователя iPhone обновить приложение?
можно ли заставить пользователя обновить, как только в iTunes Store появится новая версия моего приложения?
в настоящее время я работаю на приложение. Однако я хочу принудительно обновлять каждый раз, когда я загружаю более новую версию, потому что обновление будет иметь больше функций, и я хочу отказаться от предыдущей версии. Возможно ли это по умолчанию с iPhone или мне нужно написать собственную реализацию, чтобы проверить текущую версию и сравнить ее с магазин?
13 ответов
единственный способ, которым система обрабатывает обновления вашего приложения, - это запрос пользователю, что обновление доступно в стандартном приложении AppStore.
Кроме того, автономное приложение не знает о доступных обновлениях, поэтому вам нужно будет реализовать веб-службу, где приложение может проверить, действительна ли текущая версия.
И я не уверен, что это соответствует правилам Apple в приложениях, например (не могу найти доказательство-ссылку), вы не можете загружать пробные версии для приложение.
* EDIT* Этот ответ больше не верен. См. другие ответы upvoted для текущей истины.
Я сделал эту функцию, получив версию из itunes webservice и сравнивая с текущей версией.. Ниже приведен мой код
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];
}
и поместите идентификатор приложения в ссылку 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..
вы можете определить, если приложение нуждается в обновлении, а затем принять некоторые пользовательские действия, такие как оповещение пользователя доступно обновление. Вот фрагмент кода, который обнаруживает, что обновление доступно.
-(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;
}
Если вам абсолютно необходимо, вы можете запустить App Store, чтобы ваши пользователи могли получить последнюю версию оттуда. Я бы рекомендовал сделать это факультативным или, по крайней мере, сначала представить диалог.
// 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]];
этот вопрос был первоначально опубликован 7 лет назад, и хотя некоторые из ответов остаются актуальными, вот более современный подход.
Я рекомендую https://github.com/ArtSabintsev/Siren которое Свифт 3 совместимое и может быть установлено с Кокоаподс или Карфагеном.
CocoaPods, Swift 3 поддержка:
pod 'Siren'
Карфаген:
github "ArtSabintsev/Siren"
твой бизнес план не должен содержать фразу "пользователь". Люди злятся, когда ты заставляешь их что-то делать. Представьте себе пользователя в спешке, который открывает ваше изящное маленькое приложение однажды утром только для того, чтобы обнаружить, что вы заставляете его обновить, прежде чем он сможет использовать приложение для того, что ему нужно. Представьте, что он застрял в дебрях, чтобы использовать Edge для загрузки. Он не будет счастлив.
Если вы будете следовать этому плану достаточно долго, одно из ваших обновлений неизбежно введет заметный баг. Если вы заставите пользователей использовать багги-версию, они взбунтуются.
Я был обусловлен опытом, чтобы съежиться всякий раз, когда я вижу "больше функций", используемых для описания новой версии программного обеспечения, потому что это неизбежно означает функцию вздутия. Дизайнеры, как правило, продолжают прививать все больше и больше функций в приложения, пока одно приложение не сделает все. Это особенно опасно на платформе, такой как iPhone, где создание одного приложения для многих вещей быстро перегружает интерфейс и отзывчивость приложения.
Edit01: мой комментарий здесь Как обновить приложение после того, как пользователи платят за обновление также может иметь отношение к вашим планам. Если ваш дизайн обновления вырезает Apple из цикла доходов, это не стартер.
обновление:
просто уточнить на основе комментария ниже: да, иногда вам нужно требовать от пользователей обновления. Однако, это сильно отличается от проектирование приложение С самого начала чтобы заставить пользователей обновить каждый раз, когда разработчик выпускает новую версию.
такой дизайн предназначен, чтобы сделать жизнь разработчика легко, а не пользователя. Каждый раз, когда пользователь должен тратить время на обновление для выгоды, которую он не просил и, возможно, не хочет, вы взяли время и ресурсы от клиента. Дизайн, который разгружает время и усилия от разработчика до пользователь-плохой дизайн, потому что люди в конечном итоге покупают программное обеспечение для своей выгоды. Когда вы уменьшаете это преимущество, вы уменьшаете максимальную рентабельность программного обеспечения.
таким образом, ни один дизайнер не должен разрабатывать программное обеспечение, которое заставляет пользователей делать то, что пользователь не хочет, если это не является абсолютной технической необходимостью. Это, конечно, эмпирическое правило, но оно очень хорошее.
система принудительного обновления должны быть частью каждого приложения, которое зависит от чего-то внешнего для этого приложения. И Apple, и Google утверждают, что если приложение использует что-то внешнее, то этот внешний API должен жить вечно, никогда не меняться и т. д., п. но это просто нереально. И если это так, Если службы, от которых зависит приложение, могут измениться, то там должны быть способ для приложения, чтобы проверить и увидеть, если он должен ограничивать функциональность и подскажите пользователю получить последнюю версию или вещи просто загадочно не удастся.
Это может и должно быть то, что Apple и Google предоставляют, но они не так каждое приложение за пределами нескольких игр должно построить это, так...
Я начал проект с открытым исходным кодом на основе rails (Apache 2.0), чтобы создать решение этой проблемы. Это называется Application - [Ctrl], и это очень много работы, но вы можете использовать его, и я приветствую пожертвования любого рода. Если я смогу получить это и работать в свободное время, я предоставлю это всем разработчикам приложений с очень разумным уровнем бесплатного обслуживания, и, конечно, каждая компания всегда сможет развернуть свое собственное развертывание.
Это здесь, на GitHub:https://github.com/SlalomDigital/ApplicationCtrl
внести свой вклад и помочь мне решить эту проблему навсегда!
мое обновление приложения в App store было просто отклонено именно по этой причине. Мы добавили функцию для проверки установленной версии против текущей версии, и если это не поддерживаемая версия, мы заставляем их обновлять.
Apple отвергла это.
Итак, вернемся к конструкции доски!
другие ответы указывают на то, что необходимо самостоятельно реализовать функцию принудительного обновления. Жаль, правда, жаль, что это так. Мое первое обновление для приложения iOS должно быть выпущено завтра, и, к счастью это не будет проблемой, так как мы только внесли изменения в приложение. Однако, когда мы в конечном итоге изменим структуру наших веб-сервисов, было бы очень полезно возможность принудительного обновления, так что наш сервер не должен поддерживать каждое приложение версия.
однако существует альтернатива принудительным обновлениям, которая, по-видимому, не упоминается в этом потоке. Вы можете иметь каждый вызов webservice, который создает данные, присоединить схему к данным, что говорит приложение, как эти данные должны быть deserialised в вашем приложении. Это позволяет изменять структуру данных, создаваемых get-запросами, без нарушения десериализации в приложении. Конечно, это предполагает, что интерпретатор, который вы пишете, сам по себе не изменится, но это несколько разумное предположение, когда оно созреет.
запросы Post могут быть "схемой" через взаимодействие. При этом я имею в виду, что перед каждым post-запросом вы просите Инструкции о том, как вызвать обновленный веб-сервис. Вы обрабатываете инструкции, используя для этого прикрепленную схему, а затем выполняете фактический вызов веб-службы. По сути, это означает, что для каждого запроса post требуется 2 запроса, но это может быть хорошо.
, нет если вы реализуете принудительное обновление или интерпретацию схемы, функциональность должна присутствовать в приложении с 1 дня, когда оно попадает в App Store. Иначе ты окажешься в таком же положении. Вся эта сложность была бы излишней, если бы Apple внедрила принудительное обновление для американских разработчиков. Интерпретация схемы по-прежнему была бы улучшением удобства использования, если бы существовало принудительное обновление. Но меня немного беспокоит, что Apple не имеет принудительного обновления, потому что, по крайней мере, с ним можно представить собственные меры по обновлению anti-break после выпуска приложения.Привет всем в будущем я нашел этот учебник, который должен помочь кому-нибудь, это помогло мне.
Edit (ваш код будет выглядеть примерно так, как показано ниже):
// 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;
}
In the:
if (![appStoreVersion isEqualToString:currentVersion]){
NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
return YES;
}
часть кода Вы устанавливаете, что вы хотите сделать, если он не равен, это где вы отправляете пользователя в app store, чтобы загрузить последнюю версию.
вы можете использовать ниже url, чтобы получить информацию из любого приложения Вы просто знаете свой Apple ID вашего приложения.
вы можете получить этот идентификатор Apple ID в itunesconnect.com
>приложения>приложения информационную страницу
конечно, нет никакого способа. Пользователь должен принять решение, если он хочет загрузить новую версию приложения или нет.
AppStore будет отображаться, если есть новые версии, поэтому я также не думаю, что Apple позволит это. Также я не знаю, как вы это сделаете? Вы можете проверить это через интернет-соединение, но это не так, как нравится Apple, и поэтому у вас не будет возможности сделать это.