iOS 8 Uygulama Uzantıları Üzerine Bir Eğitim
Yayınlanan: 2022-03-11Daha önce çok az kişi denemişti (buna bir göz atın), ancak bir Akıllı Telefon ve mobil işletim sisteminin nasıl görünmesi gerektiğini tanımlayan ilk iPhone'lu Apple oldu. Apple, donanım ve kullanıcı deneyiminde inanılmaz bir atılım yaptı. Ancak, bir mobil işletim sisteminin nasıl çalışması gerektiği ve bir Akıllı Telefon uygulamalarının nasıl yapılması gerektiği konusunda da standartlar belirlediklerini sıklıkla unutuyoruz.
Uygulamalar arasına beton duvarlar inşa etmek, onları tamamen izole ve birbirlerinden habersiz hale getirmek, onları güvende tutmanın ve verilerini korumanın en iyi yöntemiydi. Tüm etkinlikler iOS tarafından yakından izlendi ve bir uygulamanın kapsamı dışında yapabileceği yalnızca birkaç eylem vardı.
“Çaresizlik en iyi korumadır!” - ama eğlence bunun neresinde?
Onları bir süre aldı; Bana sorarsanız çok uzun ama iOS 8 ile Apple biraz eğlenmeye karar verdi. iOS 8, Uygulama Uzantıları adlı yeni bir konsept tanıttı. Bu yeni özellik, uygulamalar arasındaki duvarları yıkmadı, ancak bazı uygulamalar arasında yumuşak ancak somut temas sağlayan birkaç kapı açtı. En son güncelleme, iOS geliştiricilerine iOS ekosistemini özelleştirme seçeneği verdi ve biz de bu yolun açıldığını görmek için sabırsızlanıyoruz.
iOS 8 Uygulama Uzantıları Nelerdir ve Nasıl Çalışırlar?
Basit bir ifadeyle, iOS 8 Uygulama Uzantıları, uygulamanızı başlatmadan veya ekranda göstermeden yeni bir etkileşim yöntemi sağlar.
Beklendiği gibi, Apple her şeyin üstünde kaldıklarından emin oldu, bu nedenle uygulamanızın sağlayabileceği sadece birkaç yeni giriş noktası var:
- Bugün (widget olarak da adlandırılır) - Bildirim Merkezi'nin Bugün görünümünde görüntülenen bir uzantı, kısa bilgiler gösterir ve hızlı görevlerin gerçekleştirilmesine olanak tanır.
- Share - uygulamanızın sosyal ağlarda ve diğer paylaşım hizmetlerinde kullanıcılarla içerik paylaşmasını sağlayan bir uzantı.
- Eylem - Kullanıcıların bir ana bilgisayar uygulamasından kaynaklanan içeriği görüntülemesine veya dönüştürmesine izin vermek için Eylem sayfasında özel eylem düğmeleri oluşturmaya izin veren bir uzantı.
- Fotoğraf Düzenleme - kullanıcıların Fotoğraflar uygulamasında bir fotoğrafı veya videoyu düzenlemesine olanak tanıyan bir uzantı.
- Belge Sağlayıcı - diğer uygulamaların, uygulamanız tarafından yönetilen belgelere erişmesine izin vermek için kullanılan bir uzantı.
- Özel Klavye - sistem klavyesinin yerini alan bir uzantı.
Uygulama uzantıları tek başına uygulamalar değildir. Verimli olması ve tek bir göreve odaklanması amaçlanan uygulamanın genişletilmiş işlevselliğini (ana bilgisayar uygulamaları olarak adlandırılan diğer uygulamalardan erişilebilir) sağlarlar. Kendi ikili dosyalarına, kendi kod imzalarına ve kendi öğe kümelerine sahiptirler, ancak içeren uygulamanın ikili dosyasının bir parçası olarak App Store aracılığıyla teslim edilirler. Bir (içeren) uygulama birden fazla uzantıya sahip olabilir. Kullanıcı, uzantıları olan bir uygulamayı yüklediğinde, bunlar iOS genelinde kullanılabilir olacaktır.
Bir örneğe bakalım: Bir kullanıcı Safari kullanarak bir resim bulur, paylaş düğmesine basar ve paylaşım için uygulama uzantınızı seçer. Safari, uzantıyı yükleyen ve sunan iOS Sosyal çerçevesiyle "konuşur". Uzantının kodu çalışır, sistemin somutlaştırılmış iletişim kanallarını kullanarak verileri iletir ve görev tamamlandığında - Safari, uzantı görünümünü bozar. Bundan kısa bir süre sonra sistem işlemi sonlandırıyor ve başvurunuz hiçbir zaman ekranda görüntülenmiyor. Yine de bir resim paylaşma işlevini tamamladı.
İşlemler arası iletişimi kullanan iOS, ana bilgisayar uygulamasının ve bir uygulama uzantısının birlikte çalışabilmesini sağlamaktan sorumludur. Geliştiriciler, uzantı noktası ve sistem tarafından sağlanan üst düzey API'leri kullanır, bu nedenle hiçbir zaman altta yatan iletişim mekanizmaları hakkında endişelenmelerine gerek kalmaz.
Yaşam döngüsü
Uygulama Uzantıları, iOS uygulamalarından farklı bir yaşam döngüsüne sahiptir. Ana bilgisayar uygulaması, bir kullanıcının eylemine yanıt olarak uzantının yaşam döngüsünü başlatır. Ardından sistem, uygulama uzantısını başlatır ve aralarında bir iletişim kanalı kurar. Uzantının görünümü, ana bilgisayar uygulamasının isteğinde alınan öğeler kullanılarak ana bilgisayar uygulaması bağlamında görüntülenir. Uzantının görünümü görüntülendiğinde, kullanıcı onunla etkileşim kurabilir. Kullanıcının eylemine yanıt olarak, uzantı, görevi hemen gerçekleştirerek/iptal ederek veya gerekirse bunu gerçekleştirmek için bir arka plan işlemi başlatarak ana makine uygulamasının isteğini tamamlar. Bundan hemen sonra, ana bilgisayar uygulaması, uzantının görünümünü bozar ve kullanıcı, ana bilgisayar uygulamasında önceki bağlamına döner. Bu işlemi gerçekleştirmenin sonuçları, işlem tamamlandıktan sonra ana bilgisayar uygulamasına döndürülebilir. Uzantı genellikle, ana bilgisayar uygulamasından alınan isteği tamamladıktan (veya bunu gerçekleştirmek için bir arka plan işlemi başlattıktan) hemen sonra sonlandırılır.
Sistem, bir kullanıcının eyleminin uzantısını ana bilgisayar uygulamasından açar, uzantı kullanıcı arabirimini görüntüler, bazı işler gerçekleştirir ve verileri ana makine uygulamasına döndürür (uzantının türüne uygunsa). Uzantısı çalışırken içeren uygulama çalışmıyor bile.
Uygulama Uzantısı Oluşturma - Bugün Uzantısını Kullanma Uygulamalı Örnek
Widget'lar olarak da adlandırılan Bugün uzantıları, Bildirim merkezinin Bugün görünümünde bulunur. Bunlar, kullanıcıya güncel bir içerik sunmanın (hava koşullarını gösterme gibi) veya hızlı görevleri gerçekleştirmenin (bir yapılacaklar listesi uygulamasının pencere öğesinde yapılanları işaretlemek gibi) harika bir yoludur. Burada klavye girişinin desteklenmediğini belirtmek zorundayım.
Uygulamamızdaki en güncel bilgileri gösterecek bir Today uzantısı oluşturalım (GitHub'daki kod). Bu kodu çalıştırmak için lütfen proje için Uygulama Grubunu (yeniden) yapılandırdığınızdan emin olun (Geliştirme Ekibinizi seçin, Uygulama Grubu adının benzersiz olması gerektiğini unutmayın ve Xcode'un talimatlarını izleyin).
Yeni Widget Oluşturma
Daha önce de söylediğimiz gibi, uygulama uzantıları bağımsız uygulamalar değildir. Uygulama uzantısını oluşturacağımız kapsayıcı bir uygulamaya ihtiyacımız var. İçeren uygulamamızı aldıktan sonra, Dosya -> Yeni -> Hedef'e Xcode'a giderek yeni bir hedef eklemeyi seçiyoruz. Buradan, Bugün Uzantısı eklemek için yeni hedefimizin şablonunu seçiyoruz.
Bir sonraki adımda Ürün Adımızı seçebiliriz. Bu, Bildirim Merkezi'nin Bugün görünümünde görünecek olan addır. Bu adımda da Swift ve Objective-C arasında dil seçme seçeneği bulunmaktadır. Bu adımları tamamladıktan sonra, Xcode, Info.plist
dosyası ve bir arabirim dosyası (bir storyboard veya .xib dosyası) ile ana sınıf ( TodayViewController
adlı) için varsayılan başlık ve uygulama dosyaları sağlayan bir Today şablonu oluşturur. Info.plist
dosyası varsayılan olarak şöyle görünür:
<key>NSExtension</key> <dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.widget-extension</string> </dict>
Şablon tarafından sağlanan film şeridini kullanmak istemiyorsanız, NSExtensionMainStoryboard
anahtarını kaldırın ve görünüm denetleyicinizin adıyla birlikte NSExtensionPrincipalClass
anahtarını bir değer olarak ekleyin.
Bir Bugün widget'ı şunları yapmalıdır:
- içeriğin her zaman güncel görünmesini sağlayın
- kullanıcı etkileşimlerine uygun şekilde yanıt verin
- iyi performans gösterir (iOS widget'ları belleği akıllıca kullanmalıdır, aksi takdirde sistem tarafından sonlandırılırlar)
Veri Paylaşımı ve Paylaşılan Bir Kapsayıcı
Uygulama uzantısı ve onu içeren uygulamanın her ikisi de, içeren uygulama ile uzantı arasında dolaylı bir iletişimin bir yolu olan özel olarak tanımlanmış paylaşılan kapsayıcılarında paylaşılan verilere erişebilir.
Apple'ın bunları bu kadar "basit" hale getirmesini sevmiyor musunuz? :)
NSUserDefaults
veri paylaşımı basittir ve yaygın bir kullanım durumudur. Varsayılan olarak, uzantı ve onu içeren uygulama, ayrı NSUserDefaults
veri kümelerini kullanır ve birbirlerinin kapsayıcılarına erişemez. Bu davranışı değiştirmek için iOS, Uygulama Gruplarını tanıttı. İçeren uygulamada ve uzantıda uygulama gruplarını etkinleştirdikten sonra, aynı paylaşılan kapsayıcıya erişmek için [NSUserDefaults standardUserDefaults]
kullanmak yerine [[NSUserDefaults alloc] initWithSuiteName:@"group.yourAppGroupName"]
.
Widget'ı Güncelleme
İçeriğin her zaman güncel olmasını sağlamak için Today uzantısı, bir pencere öğesinin durumunu yönetmek ve içerik güncellemelerini işlemek için bir API sağlar. Sistem ara sıra pencere aracı görünümünün anlık görüntülerini yakalar, bu nedenle pencere aracı görünür hale geldiğinde, görünümün canlı bir sürümüyle değiştirilene kadar en son anlık görüntü görüntülenir. Bir anlık görüntü alınmadan önce bir parçacığın durumunu güncellemek için NCWidgetProviding
protokolüne bir uyum önemlidir. Pencere aracı, widgetPerformUpdateWithCompletionHandler:
çağrısını aldığında, pencere aracının görünümü en son içerikle güncellenmeli ve tamamlama işleyicisi, güncellemenin sonucunu açıklamak için aşağıdaki sabitlerden biri ile çağrılmalıdır:

-
NCUpdateResultNewData
- Yeni içerik, görünümün yeniden çizilmesini gerektiriyor -
NCUpdateResultNoDate
- Parçacığın güncellenmesi gerekmiyor -
NCUpdateResultFailed
- Güncelleme işlemi sırasında bir hata oluştu
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler { // Perform any setup necessary in order to update the view. // If an error is encountered, use NCUpdateResultFailed // If there's no update required, use NCUpdateResultNoData // If there's an update, use NCUpdateResultNewData [self updateTableView]; completionHandler(NCUpdateResultNewData); }
Widget'ın Ne Zaman Görüntülenebilir Olduğunu Kontrol Etme
Bir parçacığın ne zaman görüntüleneceğini kontrol etmek için NCWidgetController
sınıfından setHasContent:forWidgetWithBundleIdentifier:
yöntemini kullanın. Bu yöntem, widget'ın içeriğinin durumunu belirlemenize izin verir. Widget'tan veya içerdiği uygulamadan (etkinse) çağrılabilir. Bu yönteme, widget içeriğinin hazır olup olmadığını tanımlayarak bir NO
veya YES
bayrağı iletebilirsiniz. İçerik hazır değilse, Bugün görünümü açıldığında iOS widget'ınızı görüntülemez.
NCWidgetController *widgetController = [[NCWidgetController alloc] init]; [widgetController setHasContent:YES forWidgetWithBundleIdentifier:@"com.your-company.your-app.your-widget"];
İçeren Uygulamayı Widget'tan Açma
Today pencere öğesi, openURL:completionHandler:
yöntemini çağırarak içerdiği uygulamanın açılmasını talep edebilen tek uzantıdır. İçeren uygulamanın kullanıcının mevcut görevi bağlamında anlamlı bir şekilde açılmasını sağlamak için özel bir URL şeması (hem widget'ın hem de içeren uygulamanın kullanabileceği) tanımlanmalıdır.
[self.extensionContext openURL:[NSURL URLWithString:@"customURLsheme://URLpath"] completionHandler:nil];
Kullanıcı Arayüzü Hususları
Widget'ınızı tasarlarken, bulanık/canlı olması gereken UIVisualEffectView
contentView
, contentView'a eklenmesi gerektiğini unutmayın, UIVisualEffectView
sınıfından yararlanın. Widget'lar ( NCWidgetProviding
protokolüne uygun), son viewWillDisappear:
görünümündeki durumu eşleştirmek için viewWillAppear:
içindeki önbelleğe alınmış durumları yüklemeli ve daha sonra normal bir görünümde olmayan bir durum olan yeni veri geldiğinde sorunsuz bir şekilde geçiş yapmalıdır. denetleyici (UI, viewDidLoad
ve animasyonları işler ve viewWillAppear
içindeki verileri yükler). Widget'lar, bir görevi gerçekleştirmek veya içeren uygulamayı tek bir dokunuşla açmak için tasarlanmalıdır. Klavye girişi bir pencere öğesi içinde mevcut değildir. Bu, metin girişi gerektiren herhangi bir UI'nin kullanılmaması gerektiği anlamına gelir.
Bir widget'a hem dikey hem de yatay kaydırma eklemek mümkün değildir. Veya daha doğrusu, kaydırma görünümü eklemek mümkündür ancak kaydırma çalışmaz. Bugün uzantısındaki bir kaydırma görünümündeki yatay kaydırma hareketi, bildirim merkezi tarafından durdurulacak ve bu da Bugün'den Bildirim merkezine kaydırmaya neden olacaktır. Bir Bugün uzantısı içinde dikey olarak kaydırma görünümü, Bugünün Görünümü kaydırılarak kesilecektir.
Teknik Notlar
Burada, bir Uygulama Uzantısı oluştururken akılda tutulması gereken bazı önemli noktalara değineceğim.
Tüm Uzantılarda Ortak Olan Özellikler
Aşağıdaki öğeler tüm uzantılar için geçerlidir:
SharedApplication nesnesi sınırların dışında : Uygulama uzantıları, bir paylaşılanApplication nesnesine erişemez veya o nesneyle ilgili yöntemlerden herhangi birini kullanamaz.
Kamera ve mikrofon kapalı : Uygulama uzantıları, cihazdaki kameraya veya mikrofona erişemez (ancak bu, tüm donanım öğeleri için geçerli değildir). Bu, bazı API'lerin kullanılamamasının bir sonucudur. Uygulama uzantısındaki bazı donanım öğelerine erişmek için API'sinin uygulama uzantıları için uygun olup olmadığını kontrol etmeniz gerekir (yukarıda açıklanan API kullanılabilirliği denetimiyle).
Arka plan görevlerinin çoğu sınırsızdır : Uygulama uzantıları, aşağıda açıklanan yükleme veya indirme işlemlerini başlatma dışında uzun süredir devam eden arka plan görevlerini gerçekleştiremez.
AirDrop sınırların dışında : Uygulama uzantıları AirDrop kullanarak veri alamaz (ancak gönderebilir).
Arka Planda Yükleme/İndirme
Arka planda gerçekleştirilebilecek bir görev, NSURLSession object
kullanarak yükleme/indirme yapmaktır.
Yükleme/indirme görevi başlatıldıktan sonra uzantı, ana bilgisayar uygulamasının isteğini tamamlayabilir ve görevin sonucu üzerinde herhangi bir etki olmaksızın sonlandırılabilir. Arka plan görevi tamamlandığında uzantı çalışmıyorsa, sistem arka planda içeren uygulamayı başlatır ve uygulamanın temsilci yöntemi application:handleEventsForBackgroundURLSession:completionHandler:
çağrılır.
Uzantının bir arka plan NSURLSession
görevi başlattığı uygulama, hem içeren uygulamanın hem de uzantısının erişebileceği bir paylaşılan kapsayıcıya sahip olmalıdır.
İçeren uygulama ve uygulama uzantılarının her biri için farklı arka plan oturumları oluşturduğunuzdan emin olun (her arka plan oturumunun benzersiz bir tanımlayıcısı olmalıdır). Bu önemlidir çünkü aynı anda yalnızca bir işlem arka plan oturumunu kullanabilir.
Eylem ve Paylaşım
Eylem ve Paylaşım uzantıları arasındaki farklar, bir kodlayıcının bakış açısından tamamen açık değildir, çünkü pratikte çok benzerler. Xcode'un paylaşım uzantısı hedefi şablonu, sosyal paylaşım için kullanabileceğiniz standart bir oluşturma görünümü kullanıcı arabirimi sağlayan SLComposeServiceViewController
kullanır, ancak bu gerekli değildir. Bir eylem uzantısının SLComposeServiceViewController
devralabileceği şekilde, tamamen özel bir tasarım için bir paylaşım uzantısı da doğrudan UIViewController'dan devralabilir.
Bu iki uzantı türü arasındaki fark, nasıl kullanılmaları gerektiğidir. Eylem uzantısıyla, kendi kullanıcı arayüzüne sahip olmayan bir uzantı oluşturabilirsiniz (örneğin, seçilen metni çevirmek ve çeviriyi ana uygulamaya döndürmek için kullanılan bir uzantı). Paylaşım uzantısı, doğrudan ana bilgisayar uygulamasından yorumları, fotoğrafları, videoları, sesleri, bağlantıları ve daha fazlasını paylaşmanıza olanak tanır. UIActivityViewController
, Paylaşım uzantılarının üst satırda renkli simgeler olarak sunulduğu ve eylem uzantılarının alt satırda tek renkli simgeler olarak sunulduğu hem Eylem hem de Paylaşım uzantılarını çalıştırır (Şekil 2.1).
Yasak API'ler
Üstbilgi dosyalarında NS_EXTENSION_UNAVAILABLE
makrosu veya kullanılamazlık için benzer makro ile işaretlenen API'ler kullanılamaz (örneğin: iOS 8'deki HealthKit ve EventKit UI çerçeveleri hiçbir uygulama uzantısında kullanılamaz).
Bir uygulama ile bir uzantı arasında kod paylaşıyorsanız, uygulama uzantısı için izin verilmeyen bir API'ye atıfta bulunmanın bile uygulamanızın App Store'dan reddedilmesine yol açacağını unutmamalısınız. Bununla, paylaşılan sınıfları farklı hedefler için ortak bir ebeveyn ve farklı alt sınıflarla hiyerarşilere yeniden çarpanlara ayırarak başa çıkmayı seçebilirsiniz. Diğer bir yol, ön işlemciyi #ifdef
kontrolleriyle kullanmaktır. Hala yerleşik koşullu hedef olmadığından, kendinizinkini oluşturmanız gerekir.
Bunu yapmanın bir başka güzel yolu da kendi gömülü çerçevenizi oluşturmaktır. Uzantılar için kullanılamayan API'leri içermediğinden emin olun. Bir uygulama uzantısını gömülü çerçeve kullanmak üzere yapılandırmak için hedefin oluşturma ayarlarına gidin ve "Yalnızca Uygulama Uzantısı-Güvenli API Gerektir" ayarını Evet olarak ayarlayın. Xcode projesini yapılandırırken, Dosyaları Kopyala inşa aşamasında, gömülü çerçeve için hedef olarak “Çerçeveler” seçilmelidir. “SharedFrameworks” hedefini seçerseniz, gönderiminiz App Store tarafından reddedilecektir.
Geriye Dönük Uyumluluk Üzerine Bir Not
Uygulama uzantıları yalnızca iOS 8'den beri mevcut olsa da, içeren uygulamanızı önceki iOS sürümlerinde kullanılabilir hale getirebilirsiniz.
Apple İnsan Arayüzü Uyumluluğu
Bir uygulama uzantısı tasarlarken Apple'ın iOS İnsan Arayüzü Yönergelerini aklınızda bulundurun. İçeren uygulamanızın desteklediği cihaz ne olursa olsun, uygulama uzantınızın evrensel olduğundan emin olmalısınız. Uygulama uzantısının evrensel olduğundan emin olmak için, Xcode'da "iPhone/iPad" değerini (bazen evrensel olarak adlandırılır) belirten hedeflenen cihaz ailesi oluşturma ayarını kullanın.
Çözüm
Uygulama uzantıları kesinlikle iOS 8'de en görünür etkiye sahiptir. Cihazların %79'u halihazırda iOS 8 kullandığından (13 Nisan 2015 tarihinde App Store tarafından ölçüldüğü gibi), uygulama uzantıları, uygulamaların faydalanması gereken inanılmaz özelliklerdir. API'nin kısıtlamalarını ve uzantılar ve bunları içeren uygulama arasında veri paylaşma şeklini birleştirerek, Apple'ın güvenlik modelinden ödün vermeden platformla ilgili en büyük şikayetlerden birini ele almayı başardığı görülüyor. Üçüncü taraf uygulamaların verilerini doğrudan birbirleriyle paylaşmalarının hala bir yolu yok. Bu çok yeni bir kavram olmasına rağmen, çok umut verici görünüyor.