Uygulama Grupları ile uygulamalar arasında veri iletişimi ve veri kalıcılığı


87

iOS 8, dün Uygulama Gruplarıyla ilgili yeni bir API açıkladı. Önceden verileri paylaşmak ve uygulamalar arasında iletişim kurmak biraz dağınıktı ve bence Uygulama Gruplarının tam da bunu düzeltmesi amaçlanıyor.

Uygulamamda Uygulama Gruplarını etkinleştirdim ve yeni bir grup ekledim ancak nasıl kullanılacağına dair herhangi bir belge bulamıyorum. Belgeler ve API referansları yalnızca bir grubun nasıl ekleneceğini belirtir.

Peki, Uygulama Gruplarının gerçekte ne yapması amaçlanıyor? Nasıl kullanılacağına dair bir yerde herhangi bir belge var mı?

Yanıtlar:


83

Uygulama Gruplarının bir başka yararı da bir NSUserDefaultsveritabanını paylaşma yeteneğidir . Bu aynı zamanda Uygulama Uzantıları (bildirim merkezi widget'ları, özel klavyeler vb.) İçin de geçerlidir.

NSUserDefaultsUygulama grubundaki tüm uygulamalarda nesnenizi bu şekilde başlatın ve veritabanını paylaşacaklar:

Amaç-C:

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];

Swift:

NSUserDefaults(suiteName: "<group identifier>")

[NSUserDefaults standardUserDefaults]Her uygulama için veri tabanındaki her şeyin bu veri tabanına taşınmayacağını unutmayın.

Belgeler (Beta 3 itibarıyla) ve doğru bir örnek teşkil etmektedir.

Ve veritabanını senkronize etmeyi unutmayın:

[yourDefaults synchronize];

2
Yalnızca simülatörde çalışır (XCode 6 beta 5, iOS 8 beta 5)
iOS Dev

8
NOT: Bunu bir iOS 8 Uzantısı (örneğin klavye) ile kullanıyorsanız, uzantınızın Info.plist dosyasında RequestsOpenAccess = YES olduğundan emin olmanız gerekir.
Kiran Panesar

1
RequestsOpenAccess = YES yaptım ve talimatları takip ettim hala Cihazda benim için çalışmıyor ve Emulator üzerinde iyi çalışıyor, cihaza özel herhangi bir şey var mı?
MAC

Benimle aynı sorun, uygulamamda paylaşım uzantısını entegre ettim, simülatörde çalışıyor, ancak gerçek cihazda çalışmıyor, RequestOpenAccess = YES ekledim ama işe yaramıyor, sorum stackoverflow.com/questions/30489894/ …
Ravi Ojha

3
@MikeRichards emin değilim, ancak doğru hatırlıyorsam uygulama gruplarına bir takım kimliği ekleniyor
Noel Baba

74

NSUserDefaults verilerini birden çok uygulama arasında paylaşma

Bir uygulama ile bir uzantı arasında veya 2 uygulama arasında paylaşılan varsayılanlara sahip olmak için, aşağıdaki adımları kullanarak ayarlarınıza bir Uygulama Grubu eklemeniz gerekir:

  1. Proje Gezgini'nde * .xcodeproj dosyasına tıklayın (en üstte olmalıdır).
  2. Proje Gezgini'nin sağında Proje ve Hedefler'i arayın. Hedeflerin altında birincil hedefinize tıklayın (Hedefler altındaki ilk şey olmalıdır).
  3. En üste doğru, Yetenekler sekmesine tıklayın.
  4. Uygulama Grupları bölümünde, Uygulama Gruplarını AÇMAK için sağdaki anahtarı tıklayın.
  5. + Düğmesine tıklayın ve group.com.company.myApp adlı bir Uygulama Grubu ekleyin .
  6. Diğer uygulamalarınızda aynı yere gidin ve bu grup artık seçilebilir olmalıdır. Bu paylaşılan verileri kullanacak her uygulama için bu grubu açın.

Not: Apple Geliştirici Portalı'na (tüm Sertifikalarınızı, Tanımlayıcılarınızı, Aygıtlarınızı ve Yetkilendirme Profillerinizi gösteren Apple web sitesi) giderseniz ve Tanımlayıcılar> Uygulama Grupları'na giderseniz bu yeni Uygulama Grubunu görmelisiniz.

Verileri saklamak için:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")!
userDefaults.setObject("user12345", forKey: "userId")
userDefaults.synchronize()

Verileri almak için:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
  print("User Id: \(testUserId)")
}

2
Teşekkürler! Bunu nasıl yapacağımı anlamak için belgelerde biraz araştırma yapmak gerekti ve başkalarının benim attığım adımları takdir edebileceğini düşündüm.
TenaciousJay

Ayrıntılı açıklama için teşekkürler ...! Bu grubu etkinleştirmek için Apple Geliştirici Portalı'ndan (tüm Sertifikalarınızı, Tanımlayıcılarınızı, Aygıtlarınızı ve Yetkilendirme Profillerinizi gösteren Apple web sitesi) herhangi bir sertifika oluşturmamız gerekiyor mu? Push bildirimi ile aynı.?
Arbaz Shaikh

5. adımı uyguladığınızda, Uygulama Grubunu Apple Geliştirici Portalı'na eklemelidir, eklemek için doğrudan Geliştirici Portalı'na gitmeniz gerekmez. 5. adımı uyguladıktan sonra portala gidebilir ve portala sizin için yaratmış olması gerektiğini görebilirsiniz.
TenaciousJay

@TenaciousJay Süper cevap. Sadece eklemek istiyorum Uygulamayı func uygulamasından başlatmak istiyorsanız (uygulama: UIApplication, openURL url: NSURL, options: [String: AnyObject]) -> Bool
Taimur Ajmal

mükemmel cevap. teşekkürler @TenaciousJay. Bir değişkeni ve değerini AppB'den AppA'ya almaya çalışıyorum, bunu nasıl yapabilirim? Örneğin, AppB'de "riderCancelledRequest = true" ise, bunu AppA'da nasıl alırım?
LizG

37

Uygulama grupları, benim mevcut dokümantasyona ilişkin yorumuma göre, öncelikle uzantıları, daha özel olarak da widget'ları hedefliyor. Widget'lar, uygulamanızla birlikte var olan kendi uygulama paketleridir. Ayrı bir uygulama olduklarından ve bu nedenle kendi sanal alanlarına sahip olduklarından, dosyaları paylaşmak için Uygulama Gruplarını kullanmanız gerekecektir.

Bazı başlıkların grep'lenmesinden sonra, gerekli API'yi bulduğumu düşünüyorum, ancak aslında iOS 7'nin bir parçası olarak yerleştirildi.

NSFileManagercontainerURLForSecurityApplicationGroupIdentifier:uygulamalarınız için Uygulama Gruplarını açarken oluşturduğunuz tanımlayıcıyı iletebileceğiniz bir yöntemi vardır :

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];

Teşekkürler, genişletilebilirlik konusunda haklı olduğunuza inanıyorum. Bu iOS 7 yöntemi hakkında biraz daha şüpheliyim, bana oldukça statik görünüyor, iOS 8 uygulamalar arasında gerçek etkileşimler ve iletişim sağladı.
Streem

@Justafinger Bu iOS 7 yöntemi yalnızca paylaşılan uygulamalar arasında verilere yazmak ve verilerden okumak için bir URL oluşturmak içindir. Bu özel yöntem yalnızca widget'lar için gerçekten yararlıdır (şimdiye kadar gördüğüm kadarıyla), ancak diğer uzantılar için değil.
Wayne Hartman

Apple'ın bunu iOS 8'de programlı olarak bir kapsayıcı oluşturmak ve özel dosyaları paylaşmak zorunda kalmadan kolaylaştırmak istediğine inanıyorum. Belgeler , NSUserDefault'u kullanarak verileri paylaşabilmeniz gerektiğini belirtir. Sanırım bir şeyi kaçırıyorum çünkü bu benim için çalışmıyor.
akış

@Justafinger Ben de işe gidemedim NSUserDefaults. Beta 1 bug'a kadar tebeşirim var.
Wayne Hartman

@WayneHartman NSUserDefaultsVeritabanı için bir geçici çözüm var . Cevabımı gör.
Noel Baba

6

Bugün dokunduğum önemli bir tuzak şudur:

Pek çok projede tek bir uygulama hedefi ve bu hedefin her bir yapılandırması için farklı paket tanımlayıcıları belirlediğini gördüm. Burada işler karışıyor. Geliştiricilerin amaçladığı şey, hata ayıklama yapılandırması için bir hata ayıklama uygulaması ve sürüm hedefi için bir üretim uygulaması oluşturmaktı.

Bunu yaparsanız, her iki uygulama da böyle ayarlandıklarında aynı NSUserDefaults'u paylaşacaktır.

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()

Bu birçok yerde sorunlara neden olur:

  1. Kullanıcıya özel bir uygulama giriş ekranı gösterildiğinde bir anahtar için EVET'i ayarladığınızı hayal edin. Diğer uygulama şimdi de EVET okuyacak ve tanıtımı göstermeyecek.
  2. Evet, bazı uygulamalar da oAuth belirteçlerini kullanıcı varsayılanlarında depolar. Her neyse ... Uygulamaya bağlı olarak, uygulama bir belirteç olduğunu fark edecek ve yanlış belirteci kullanarak verileri almaya başlayacaktır. Garip hatalarla başarısız olma şansı yüksektir.

Bu problemin çözümü genel olarak varsayılan anahtarların önüne mevcut yapılandırmanın inşa edilmesidir. Konfigürasyonlarınız için farklı paket tanımlayıcıları ayarlayarak konfigürasyonu çalışma zamanında kolayca tespit edebilirsiniz. Ardından paket tanımlayıcısını şuradan okuyun NSBundle.mainBundle(). Aynı paket tanımlayıcılarına sahipseniz, farklı önişlemci makroları ayarlamanız gerekir.

#ifdef DEBUG
  NSString* configuration = @"debug";
#elif RELEASE
  NSString* configuration = @"release";
#endif

Swift'de neredeyse aynı görünecek:

#if DEBUG
  let configuration = "debug"
#elseif RELEASE
  let configuration = "release"
#endif

8
Sorunlarınız, tüm verilerinizi paylaşılan bir UserDefaults'da karıştırdığınız için mevcuttur. NSUserDefaults.standardUserDefaults()Paylaşılmaması gereken veriler için kullanmalısınız .
Daniel

2

Depolamak

let shared: NSUserDefaults = NSUserDefaults(suiteName: "group.abcapp")!
shared.setObject("abc.png", forKey: "favEmoji")
shared.synchronize()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.