Bir iPhone uygulamasını programlıyorum ve belirli kullanıcı işlemleri nedeniyle uygulamayı çıkmaya zorlamam gerekiyor. Uygulamanın ayrılan belleği temizledikten sonra, uygulamayı sonlandırmak için çağrılacak uygun yöntem nedir?
Bir iPhone uygulamasını programlıyorum ve belirli kullanıcı işlemleri nedeniyle uygulamayı çıkmaya zorlamam gerekiyor. Uygulamanın ayrılan belleği temizledikten sonra, uygulamayı sonlandırmak için çağrılacak uygun yöntem nedir?
Yanıtlar:
Denedin exit(0)
mi
Alternatif olarak, [[NSThread mainThread] exit]
daha uygun bir çözüm gibi görünsem de denemedim.
İPhone'da bir uygulamadan çıkma kavramı yoktur. Bir uygulamanın sonlandırılması gereken tek işlem, telefondaki Ana Ekran düğmesine dokunmaktır ve bu, geliştiricilerin erişebileceği bir şey değildir.
Apple'a göre, uygulamanız kendi kendine sonlandırılmamalıdır. Kullanıcı Ana Ekran düğmesine basmadığından, Ana ekrana herhangi bir dönüş, uygulamanızın çöktüğü izlenimini kullanıcıya verir. Bu kafa karıştırıcı, standart dışı bir davranıştır ve kaçınılmalıdır.
çıkış (0) kullanıcıya kilitlenme olarak görünür, bu nedenle kullanıcıya bir onay mesajı gösterin. Onaylandıktan sonra askıya alma (ana sayfa düğmesi programlı olarak basın) ve uygulama animasyonla arka plana giderken 2 saniye bekleyin ve ardından kullanıcının görünümünün arkasından çıkın
-(IBAction)doExit
{
//show confirmation message to user
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Confirmation"
message:@"Do you want to exit?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != 0) // 0 == the cancel button
{
//home button press programmatically
UIApplication *app = [UIApplication sharedApplication];
[app performSelector:@selector(suspend)];
//wait 2 seconds while app is going background
[NSThread sleepForTimeInterval:2.0];
//exit app when app is in background
exit(0);
}
}
exit(0)
önemli değil. Nokta uygulamanızın "bırakma davranışı" olmasıdır. Çok önemli 3. taraflarca yapılan birkaç uygulama dışında, AppStore'da davranıştan çıkmak yasaktır. Ayrıca, ev düğmesi davranışını taklit etmek de reddedilebilir.
Soru-Cevap bölümüne buradan bakın: https://developer.apple.com/library/content/qa/qa1561/_index.html
S: iOS uygulamamdan programlı olarak nasıl çıkarım?
Bir iOS uygulamasını zarif bir şekilde sonlandırmak için herhangi bir API sağlanmamıştır.
İOS'ta kullanıcı uygulamaları kapatmak için Ana Ekran düğmesine basar. Uygulamanızın amaçlanan işlevini sağlayamadığı koşullar varsa, önerilen yaklaşım kullanıcı için sorunun doğasını ve kullanıcının yapabileceği olası eylemleri belirten bir uyarı göstermektir - WiFi'yi açma, Konum Servislerini etkinleştirme vb. Kullanıcının kendi takdirine bağlı olarak uygulamayı sonlandırmasına izin ver.
UYARI:
exit
İşlevi çağırmayın . Aramaexit
yapan uygulamalar, zarif bir sonlandırma yapmak ve Ana ekrana geri animasyon uygulamak yerine kullanıcıya çökmüş gibi görünecektir.Buna ek olarak, veriler kaydedilemeyebilir, çünkü exit komutunu çağırırsanız
-applicationWillTerminate:
benzerUIApplicationDelegate
yöntemler çağrılmaz.Geliştirme veya test sırasında uygulamanızı sonlandırmanız gerekiyorsa,
abort
işlev veyaassert
makro önerilir
Bu gerçekten programdan çıkmanın bir yolu değil, insanları bırakmaya zorlamanın bir yolu.
UIAlertView *anAlert = [[UIAlertView alloc] initWithTitle:@"Hit Home Button to Exit" message:@"Tell em why they're quiting" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[anAlert show];
İnfo.plist'inize gidin ve "Uygulama arka planda çalışmaz" anahtarını kontrol edin. Bu kez kullanıcı ana sayfa düğmesini tıkladığında uygulama tamamen çıkar.
Ekle UIApplicationExitsOnSuspend
mülk application-info.plist
için true
.
Bazı testlerden sonra şunları söyleyebilirim:
[UIApplication sharedApplication]
uygulama çöktü gibi görünen neden olur, ama bunu - (void)applicationWillTerminate:(UIApplication *)application
yapmadan önce arayacaktır ;exit(0);
da uygulamayı sonlandırmak, ancak (sıçrama tahtası en simgeler görünür etkisi dışarı yakınlaştırma, beklenen sever) "normal" bakacağız, AMA demeyeceksin - (void)applicationWillTerminate:(UIApplication *)application
temsilci yöntemi.Benim tavsiyem:
- (void)applicationWillTerminate:(UIApplication *)application
Temsilciyi el ile arayın .exit(0);
.ApplicationDelegate'iniz, kullanıcı tarafından kasıtlı olarak bırakıldığından haberdar edilir:
- (void)applicationWillResignActive:(UIApplication *)application {
Bu bildirimi aldığımda sadece
exit(0);
Hangi tüm işi yapar. Ve en iyi şey, kullanıcıların istifa etmeyi amaçlamasıdır, bu yüzden orada çağırmak için bir sorun olmamalıdır.
Ses Uygulamamda, müzik çalmaya devam ederken insanlar cihazlarını senkronize ettikten sonra uygulamadan çıkmak gerekiyordu. Senkronizasyon tamamlanır tamamlanmaz bir bildirim alırım. Ancak bundan hemen sonra uygulamayı bırakmak aslında bir çökme gibi görünecektir.
Bunun yerine bir sonraki arka plan eyleminde uygulamayı GERÇEKTEN bırakmak için bir bayrak ayarladım. Bir senkronizasyondan sonra uygulamayı yenilemek için iyidir.
Uygulamam son zamanlarda reddedildi bc Belgelenmemiş bir yöntem kullandım. Kelimenin tam anlamıyla:
"Maalesef özel bir API kullandığından App Store'a eklenemez. İPhone Geliştirici Programı Lisans Sözleşmesi bölüm 3.3.1'de belirtildiği gibi herkese açık olmayan API'ların kullanılması yasaktır:
"3.3.1 Uygulamalar, Belgeli API'leri yalnızca Apple tarafından belirtilen şekilde kullanabilir ve herhangi bir özel API kullanmamalı veya çağırmamalıdır."
Uygulamanıza dahil edilen herkese açık olmayan API, terminateWithSuccess "
Apple diyor ki:
"Uyarı: çıkış işlevini çağırma. Çıkış çağıran uygulamalar, zarif bir sonlandırma yapmak ve Ana ekrana geri animasyon uygulamak yerine kullanıcıya çökmüş gibi görünür."
Bunun kötü bir varsayım olduğunu düşünüyorum. Kullanıcı bir çık düğmesine basarsa ve "Uygulama şimdi sonlandırılır." Apple, bir uygulamadan çıkmak için geçerli bir yol sağlamalıdır (çıkış (0) değil).
Bu iyi bir cevap aldı ama biraz genişlemeye karar verdi:
Apple'ın iOS İnsan Arabirim Yönergeleri'ni iyi okumadan uygulamanızın AppStore'a kabul edilmesini sağlayamazsınız. (size karşı herhangi bir şey yaptığınız için reddetme hakkını saklı tutarlar ) "Programlı Olarak Çıkma" bölümü http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices. html , bu durumda nasıl davranmanız gerektiği konusunda kesin bir kılavuzdur.
Apple platformunda herhangi bir sorunla karşılaşırsanız, kolayca bir çözüm bulamazsanız, HIG'ye danışın. Apple bunu yapmanızı istemiyor ve genellikle (Apple değilim, bu yüzden her zaman garanti edemiyorum) belgelerinde bunu söylüyorlar.
Hımm, eğer uygulamanız bir internet bağlantısı gerektiriyorsa, uygulamadan 'çıkmanız gerekebilir'. Bir uyarı görüntüleyebilir ve ardından böyle bir şey yapabilirsiniz:
if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) {
[[UIApplication sharedApplication] performSelector:@selector(terminate)];
} else {
kill(getpid(), SIGINT);
}
Apple, bu işlevlerin kullanımını şiddetle tavsiye etmediğinden exit(0)
, abort()
işlevleri kullanarak uygulamadan çıkamıyoruz. Yine de bu işlevleri geliştirme veya test amacıyla kullanabilirsiniz.
Geliştirme veya test sırasında uygulamanızı sonlandırmak gerekiyorsa, iptal etme işlevi veya iddia makrosu önerilir
Daha fazla bilgi için lütfen bu Apple Soru-Cevap dizisini bulun .
Bu fonksiyonun kullanımı gibi uygulama çöküyor gibi bir izlenim yaratmak. Bu nedenle, bazı işlevlerin kullanılamaması nedeniyle uygulamayı kapatma konusunda farkında kullanıcıya sonlandırma mesajı ile Uyarı görüntüleyebileceğimiz gibi bazı önerilerim var.
Ancak Uygulamayı Başlatma ve Durdurma için iOS İnsan Arayüzü Kılavuzu , Uygulamayı sonlandırmak için Asla Çık veya Kapat düğmesini kullanmamayı önerir . Bunun yerine, durumu açıklamak için uygun mesajı görüntülemeyi önerirler.
Bir iOS uygulaması hiçbir zaman Kapat veya Çık seçeneğini görüntülemez. Kullanıcılar başka bir uygulamaya geçtiklerinde, Ana ekrana döndüklerinde veya cihazlarını uyku moduna aldıklarında uygulamayı kullanmayı bırakırlar.
Bir iOS uygulamasından asla programlı olarak çıkmayın. İnsanlar bunu bir çökme olarak yorumlama eğilimindedir. Bir şey uygulamanızın amaçlandığı gibi çalışmasını engelliyorsa, kullanıcılara durum hakkında bilgi vermeniz ve bu konuda ne yapabileceklerini açıklamanız gerekir.
Yukarıdakilere ek olarak, iyi, cevap Sadece eklemek istedim, hafızanızı temizlemeyi düşünün.
Uygulamanız çıktıktan sonra, iPhone OS uygulamanızın geride bıraktığı her şeyi otomatik olarak temizler, böylece tüm belleği manuel olarak boşaltmak uygulamanızın çıkması için gereken süreyi artırabilir.
- (IBAction)logOutButton:(id)sender
{
//show confirmation message to user
CustomAlert* alert = [[CustomAlert alloc] initWithTitle:@"Confirmation" message:@"Do you want to exit?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
alert.style = AlertStyleWhite;
[alert setFontName:@"Helvetica" fontColor:[UIColor blackColor] fontShadowColor:[UIColor clearColor]];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != 0) // 0 == the cancel button
{
//home button press programmatically
UIApplication *app = [UIApplication sharedApplication];
[app performSelector:@selector(suspend)];
//wait 2 seconds while app is going background
[NSThread sleepForTimeInterval:2.0];
//exit app when app is in background
NSLog(@"exit(0)");
exit(0);
}
}
Yukarıda anlatılan [[NSMutableArray new] addObject: nil] yaklaşımını, bir anlatım çıkışı (0) işlev çağrısı yapmadan uygulamadan çıkmaya (çökmeye) zorlamak için kullandım.
Neden? Uygulamam, ortadaki adam saldırılarını önlemek için tüm ağ API çağrılarında sertifika sabitleme kullandığından. Bunlar, finansal uygulamamın başlangıçta yaptığı başlatma çağrılarını içerir.
Sertifika kimlik doğrulaması başarısız olursa, tüm başlatma çağrılarım hata veriyor ve uygulamamı belirsiz bir durumda bırakıyor. Kullanıcının eve gitmesine ve ardından uygulamaya geri dönmesine izin vermek, uygulamanın işletim sistemi tarafından temizlenmediği sürece hala başlatılmamış ve güvenilmez olduğu için yardımcı olmaz.
Bu nedenle, bu durumda, kullanıcıyı uygulamanın güvenli olmayan bir ortamda çalıştığını bildiren bir uyarı almanın en iyi olduğunu düşündük ve daha sonra "Kapat" a bastıklarında, yukarıda belirtilen yöntemi kullanarak uygulamayı kapatmaya zorlayın.
[[UIApplication sharedApplication] terminateWithSuccess];
İyi çalıştı ve otomatik çağrılar
- (void)applicationWillTerminateUIApplication *)application delegate.
derleme zamanı uyarısını kaldırmak için bu kodu ekleyin
@interface UIApplication(MyExtras)
- (void)terminateWithSuccess;
@end
exit(0)
Hemen uygulamadan çıkacağından ve uygulamanızın çöktüğü gibi görüneceğinden işlevi doğrudan çağırmamalısınız . Kullanıcılara bir onay uyarısı göstermek ve bunu kendileri yapmalarına izin vermek daha iyidir.
func askForQuit(_ completion:@escaping (_ canQuit: Bool) -> Void) {
let alert = UIAlertController(title: "Confirmation!", message: "Do you want to quit the application", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
completion(true)
}))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.cancel, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
completion(false)
}))
self.present(alert, animated: true, completion: nil)
}
/// Will quit the application with animation
func quit() {
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
/// Sleep for a while to let the app goes in background
sleep(2)
exit(0)
}
self.askForQuit { (canQuit) in
if canQuit {
self.quit()
}
}
Kullanıcı bir uygulamanın ne zaman çıkacağına karar vermelidir. Bir uygulamadan çıkıldığında bunun iyi bir kullanıcı etkileşimi olduğunu düşünmüyorum. Bu nedenle güzel bir API yok, sadece ev düğmesinin bir tane var.
Bir hata varsa: Daha iyi uygulayın veya kullanıcıyı bilgilendirin. Yeniden başlatma gerekiyorsa: Kullanıcıyı bilgilendirme işlemini daha iyi uygulayın.
Kulağa aptalca geliyor, ancak kullanıcının karar vermesine ve bildirmesine izin vermeden uygulamadan çıkmak kötü bir uygulamadır. Ve Apple, kullanıcı etkileşimi için bir ana sayfa düğmesi olduğundan, aynı işlev için 2 şey olmamalıdır (bir uygulamadan çıkılması).
Ana ekran düğmesinden başka bir uygulamadan çıkmak gerçekten iOS-esque olmayan bir yaklaşımdır.
Yine de, özel bir şey kullanmayan bu yardımcıyı yaptım:
void crash()
{ [[NSMutableArray new] addObject:NSStringFromClass(nil)]; }
Ama yine de benim durumumda üretim amaçlı değildi. Çökme raporlarını test etmek veya bir Temel Veri sıfırlandıktan sonra hızlı bir şekilde yeniden başlatmak içindir. Üretim kodunda işlev bırakılırsa reddedilmemeyi güvenli hale getirdi.
İPadOS 13'te artık aşağıdaki gibi tüm sahne oturumlarını kapatabilirsiniz:
for session in UIApplication.shared.openSessions {
UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
}
Bu, applicationWillTerminate(_ application: UIApplication)
uygulama temsilcinizi arayacak ve sonunda uygulamayı sonlandıracaktır.
Ancak iki şeye dikkat edin:
Bu kesinlikle tüm sahneleri kapatmak için kullanılmaz . (bkz. https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/multiple-windows/ )
Bir iPhone'daki iOS 13'te derlenir ve iyi çalışır, ancak hiçbir şey yapmıyor gibi görünüyor.
İOS / iPadOS 13'teki sahneler hakkında daha fazla bilgi: https://developer.apple.com/documentation/uikit/app_and_environment/scenes
Arka planda da çalışan, örneğin konum güncellemelerini almak için (bunun için konum güncellemeleri arka plan özelliğini kullanarak) bir uygulamadan çıkmak uygun olabilir .
Örneğin, kullanıcının konum tabanlı uygulamanızın oturumunu kapattığını ve ana sayfa düğmesini kullanarak uygulamayı arka plana ittiğini varsayalım. Bu durumda uygulamanız çalışmaya devam edebilir, ancak uygulamadan tamamen çıkmak mantıklı olabilir. Kullanıcı için iyi (kullanması gerekmeyen bellek ve diğer kaynakları serbest bırakır) ve uygulama kararlılığı için iyi olur (örneğin, uygulamanın mümkün olduğunda periyodik olarak yeniden başlatılmasını sağlamak bellek sızıntılarına ve diğer düşük belleğe karşı bir güvenlik ağıdır sorunlar).
Bu (muhtemelen olmasa da, aşağıya bakın :-) gibi bir şeyle elde edilebilir:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if (/* logged out */) {
exit(0);
} else {
// normal handling.
}
}
Uygulama daha sonra arka plandan çıkacağından, kullanıcıya yanlış görünmeyecek ve bir sonraki çalıştırışlarında kullanıcı arayüzünün geri yüklenmesi koşuluyla bir çökmeye benzemeyecektir. Diğer bir deyişle, kullanıcı, uygulama arka planda olduğunda uygulamanın sistem tarafından başlatılan sonlandırılmasından farklı görünmez.
Yine de, sistemin uygulamanın sonlandırılabileceğini bilmesini sağlamak için daha standart bir yaklaşım kullanılması tercih edilir. Örneğin, bu durumda, mevcutsa bir harita görünümünde geçerli konumu gösterme de dahil olmak üzere konum güncellemeleri isteğini durdurarak GPS'in kullanılmadığından emin olarak. Bu şekilde sistem [[UIApplication sharedApplication] backgroundTimeRemaining]
, uygulama arka plana girdikten sonra uygulamayı birkaç dakika (yani ) sonlandırır . Bu, uygulamayı sonlandırmak için kod kullanmak zorunda kalmadan aynı faydaları elde edecektir.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if (/* logged out */) {
// stop requesting location updates if not already done so
// tidy up as app will soon be terminated (run a background task using beginBackgroundTaskWithExpirationHandler if needed).
} else {
// normal handling.
}
}
Ve elbette, http://developer.apple.com/iphone/library/qa/qa2008/qa1561.htmlexit(0)
referansını veren diğer yanıtlara göre, kullanım ön planda çalışan ortalama üretim uygulaması için asla uygun olmaz.