Принудительное приложение iphone для программной перезагрузки
Я пытаюсь заставить приложение для iPhone перезапускаться программно при нажатии кнопки "Выход".
Кто-нибудь получил образец кода для обмена? Я прочитал, что это возможно, изменив файл main.m, но не смог найти код, связанный с этим.
Любая помощь будет оценена.
Ответы
Ответ 1
Прежде всего, хотя можно убить приложение, это запрещено Apple, и оно будет отклонено. Даже если он не был отклонен, невозможно перезапустить приложение после его убийства. Вам просто нужно найти способ reset вашего приложения через ваш код, как сказал Jason Coco
. Это может быть больше работы, но не стоит отказываться от Apple.
Ответ 2
Примечание:
Хотя на этот вопрос ответили как "невозможно", я думаю, что это правильный вопрос для нового разработчика iOS, и есть что-то, что они могут сделать, что, вероятно, они хотят.
Существует способ "перезапустить" ваше приложение с точки зрения пользователя, которое не перезапускается или не выходит из приложения iOS. Как указано в других ответах, приложение iOS никогда не должно явно выходить из него, потому что это запрещено в iOS.
Мой ответ:
Если вы хотите, чтобы ваше приложение возвращалось в состояние, в котором оно было запущено, это не на 100% возможно, но я объясню, как получить большую часть пути, который должен быть достаточным для всех допустимых целей.
Первое, что нужно сделать, это воссоздать контроллер корневого представления. Я рекомендую сделать это из метода в делегате приложения следующим образом:
- (void)resetAppToFirstController
{
self.window.rootViewController = [[MyMainViewController alloc] initWithNibName:nil bundle:nil];
}
Во многих случаях этого будет достаточно, но любое приложение-состояние, которое у вас есть, также должно быть reset в этом методе. Например, выведите пользователя из системы, reset любое непостоянное состояние и аннулируйте (освободите) все объекты, которые вы можете. Этот метод также можно использовать для первоначального создания вашего первого контроллера вида с application:didFinishLaunchingWithOptions
.
Классы Framework и Singletons:
Вы не сможете полностью reset состояние любых фреймворческих синглетонов или экземпляров для каждого приложения, например:
[UIApplication sharedApplication];
[NSNotificationCenter defaultCenter];
[NSUserDefaults standardUserDefaults];
[UIScreen screens];
// etc...
Это, вероятно, отлично, так как вы не должны сохранять какое-либо непостоянное состояние в них в любом случае (кроме NSNotificationCenter
, но все зарегистрированные наблюдатели должны были быть удалены при выпуске объектов). Если вы хотите инициализировать или reset любое состояние каркаса, вы можете сделать это в том же методе resetAppToFirstController
. Во всяком случае, не нужно будет воссоздавать их или объект window
.
Если у вас есть какие-либо из ваших собственных синглонов, вы можете воссоздать их, сохранив их в классе singleton-holder (который сам по себе является реальным синглом). Концептуально это простой одноэлементный класс со свойствами для каждого из ваших других синглетонов и метод reset
для аннулирования и освобождения всех. Ваши другие синглтоны должны использовать этот класс (вместо статической или глобальной переменной) для хранения экземпляров singleton. Будьте осторожны, если вы используете какие-либо сторонние библиотеки, так как они могут также использовать синглтоны, и вам нужно будет обеспечить, чтобы они также использовали ваш сингл-держатель, чтобы вы могли reset их по мере необходимости. Я думаю, что этот метод является хорошей практикой в любом случае, потому что в некоторых случаях (например, модульное тестирование) вам нужны объекты, которые обычно являются одиночными, чтобы уйти и повторно инициализировать до первозданного состояния. Тем не менее, вы не хотите связывать реализации singleton с вашим одноэлементным держателем, поэтому хорошим способом реализовать это является использование NSMutableDictionary
в качестве ассоциированного объекта на [UIApplication sharedApplication]
с именами одноэлементного класса в качестве ключей. Тем не менее, я немного отклоняюсь от темы, поскольку это более сложный метод, выходящий за рамки этого вопроса.
Вышеприведенное должно быть достаточным для "reset" вашего приложения в отношении пользователя. Вы даже можете снова отобразить заставку, если хотите, как ваш первый контроллер представления.
Ответ 3
попробуйте это, он работает для меня.
-(void)restart
{
MyAppDelegate *appDelegate = (MyAppDelegate *)([UIApplication sharedApplication].delegate);
[appDelegate.navigationController popToRootViewControllerAnimated:NO];
UIViewController *topViewController = appDelegate.navigationController.topViewController;
Class class = [topViewController class];
NSString *nibName = topViewController.nibName;
UIViewController *rootViewcontroller = (UIViewController *)([[class alloc] initWithNibName:nibName bundle:nil]);
[appDelegate.navigationController.view removeFromSuperview];
appDelegate.navigationController.viewControllers = [NSArray arrayWithObject:rootViewcontroller];
[appDelegate.window addSubview:appDelegate.navigationController.view];
[appDelegate.window makeKeyAndVisible];
}
Ответ 4
Objective-C:
exit(0);
Swift:
exit(0)
У меня есть это на двух живых приложениях, и они не были отклонены. Одно из моих приложений даже имеет эту строку кода как функцию на домашней странице моего приложения. Он расположен в верхнем правом углу, где кнопка Twitter находится в Твиттере. Поэтому не беспокойтесь о том, что Apple отвергнет, если это не похоже на неожиданный сбой.
![введите описание изображения здесь]()
Ответ 5
Вот как вы можете это сделать на симуляторе, используя частный API:
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", scheme, endpointString]];
Class pClass = NSClassFromString(@"BKSSystemService");
id service = [[pClass alloc] init];
SEL pSelector = NSSelectorFromString(@"openURL:application:options:clientPort:withResult:");
NSMethodSignature *signature = [service methodSignatureForSelector:pSelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = service;
NSString *app = @"com.apple.mobilesafari";
[invocation setSelector:pSelector];
[invocation setArgument:&URL atIndex:2];
[invocation setArgument:&app atIndex:3];
unsigned int i = [service performSelector:NSSelectorFromString(@"createClientPort")];
[invocation setArgument:&i atIndex:5];
[invocation invoke];
exit(0);
Это также должно работать на jailbroken приложениях с соответствующими правами.
Для других приложений может использоваться простая страница html:
NSString *format = @"https://dl.dropboxusercontent.com/s/rawt1ov4nbqh4yd/launchApp.html?scheme=%@&URL=%@";
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:format, scheme, endpointString]];
[[UIApplication sharedApplication] openURL:URL];
exit(0);
К сожалению, в этом случае необходимо подключение к Интернету.
Ответ 6
Я выхожу во время -applicationWillResignActive: если приложение находится на стартовом экране, и Apple приняло его на долгие годы. Для пользователя это не будет похоже на сбой. В следующий раз пользователь запустит приложение из значка. Дополнительная проверка, которая не выходит из приложения, если она была запущена сегодня, может быть полезна для пользователей в некоторых случаях.
- (void)applicationWillResignActive:(UIApplication *)application
{
// called if phone-call comes in!
if([gameController isGameFinished])
exit(0);
}
Ответ 7
Поместите это в UIAlertAction, спрашивая пользователя "Сохранить и выйти". Он оживит выход (0), так что, по крайней мере, он выглядит запланированным.
- (void)saveAndQuit
{
[UIView animateWithDuration:0.8 animations:^{
self.window.alpha = 0.0; // fade out...
// ... while pinching to a point
self.window.transform = CGAffineTransformScale(
CGAffineTransformMakeTranslation( 0, 0 ), 0.1, 0.1 );
} completion:^(BOOL finished) {
exit(0);
}];
}