Обмен данными между общим расширением iOS 8 и основным приложением
Недавно я сделал простое расширение для iOS 8, чтобы понять, как работает система. Как утверждает Apple в своем Руководстве по программированию расширений приложений:
По умолчанию содержащее приложение и его расширения не имеют прямого доступа к контейнерам друг друга.
Это означает, что расширение и содержащее приложение не обмениваются данными. Но на той же странице Apple предлагает решение:
Если вы хотите, чтобы ваше содержащее приложение и его расширения могли обмениваться данными, используйте Xcode или портал разработчика, чтобы включить группы приложений для приложения и его расширений. Затем зарегистрируйте группу приложений на портале и укажите группу приложений для использования в содержащем приложении.
Тогда становится возможным использовать NSUserDefaults для обмена данными между содержащим приложение и расширением. Это именно то, что я хотел бы сделать. Но по какой-то причине это не работает.
На той же странице Apple предлагает стандартные значения по умолчанию:
var defaults = NSUserDefaults.standardUserDefaults()
В презентации WWDC (217) они предлагают общий пакет:
var defaults = NSUserDefaults(suiteName: kDefaultsPackage)
Кроме того, я включил группы приложений как для цели приложения, так и для цели расширения с тем же именем группы приложений:
Но все эти настройки даром. Я не могу получить данные, которые я сохранил в приложении, из расширения. Как будто две цели используют совершенно разные хранилища NSUserDefaults.
Так,
- Есть ли решение для этого метода?
- Как я могу поделиться простыми данными между приложением и расширением общего доступа? Данные - это просто учетные данные пользователя для API.
7 ответов
Вы должны использовать NSUserDefaults как это:
Сохранить данные:
ObjC
NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
[shared setObject:object forKey:@"yourkey"];
[shared synchronize];
быстрый
let defaults = UserDefaults(suiteName: "group.yourgroup")
defaults?.set(5.9, forKey: "yourKey")
Читать данные:
ObjC
NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
id value = [shared valueForKey:@"yourkey"];
NSLog(@"%@",value);
быстрый
let defaults = UserDefaults(suiteName: "group.yourgroup")
let x = defaults?.double(forKey: "yourKey")
print(x)
Это будет работать нормально!
Вот как я это сделал:
- Откройте основную цель приложения> Возможности> Группы приложений, для которых установлено значение
- Добавьте новую группу приложений и убедитесь, что она отмечена (например, group.com.seligmanventures.LightAlarmFree)
- Откройте цель наблюдения (с вкладкой "Возможности") > Группы приложений, установленные на
- Добавьте новую группу приложений и убедитесь, что она отмечена (например, group.com.seligmanventures.LightAlarmFree - но она должна совпадать с именем группы выше)
Сохраните данные в группу следующим образом:
var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree") defaults?.setObject("It worked!", forKey: "alarmTime") defaults?.synchronize()
Получить данные из группы следующим образом:
var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree") defaults?.synchronize() // Check for null value before setting if let restoredValue = defaults!.stringForKey("alarmTime") { myLabel.setText(restoredValue) } else { myLabel.setText("Cannot find value") }
Если у вас есть
group.yourappgroup
использование
var defaults = NSUserDefaults(suiteName: "yourappgroup")
Это работает для меня
Очевидно, что это работает, только когда имя группы используется в качестве имени набора для NSUserDefaults.
Документация говорит, что NSUserDefaults.standartUserDefaults() также должен работать, но это не работает, и это, вероятно, ошибка.
В моем сценарии я делюсь данными между родительским приложением iOS и WatchKit. Я использую Xcode 6.3.1, iOS Deployment Target 8.3
var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")
В вашем viewDidLoad убедитесь, что вы синхронизируете:
override func viewDidLoad() {
super.viewDidLoad()
defaults?.synchronize()
}
Пример кнопки отправки текста, но, конечно, вы можете передать что угодно:
@IBAction func btnSend(sender: UIButton) {
var aNumber : Int = 0;
aNumber = aNumber + 1
//Pass anything with this line
defaults?.setObject("\(aNumber)", forKey: "userKey")
defaults?.synchronize()
}
Затем с другой стороны убедитесь, что группа приложений совпадает:
var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")
Затем синхронизируйте и cal: (в этом случае "lblNumber" является меткой IBOutlet)
defaults?.synchronize()
var tempVar = defaults!.stringForKey("userKey")!;
lblNumber.setText(tempVar);
Затем, если вы хотите установить что-то на этой стороне и синхронизировать его обратно, просто сделайте то же самое, синхронизируйте и просто убедитесь, что stringForKey, который вы вызываете на другой стороне, такой же:
defaults?.setObject("sending sample text", forKey: "sampleKey")
defaults?.synchronize()
Надеюсь, это имеет смысл
Я перевел в ответ быстрого Фугри, и это работает!
Сохранить данные:
let shared = NSUserDefaults(suiteName: "nameOfCreatedGroup")
shared("Saved String 1", forKey: "Key1")
shared("Saved String 2", forKey: "Key2")
Читать данные:
let shared = NSUserDefaults(suiteName: "nameOfCreatedGroup")!
valueToRead1 = shared("Key1") as? String
valueToRead2 = shared("Key2") as? String
println(valueToRead1) // Saved String 1
println(valueToRead2) // Saved String 2
Вы можете поделиться данными, выполнив следующие действия:
- Выберите ваш проект -> выберите вкладку "Возможности" -> "Включить группы приложений" -> нажмите "+" -> вставьте свой идентификатор пакета после "группы".
Выберите свой добавочный номер -> выберите вкладку "Возможности" -> "Включить группы приложений" -> нажмите "+" -> вставьте свой идентификатор пакета после "группы".
- Поместите ниже код в основное приложение, для которого вы хотите поделиться данными:
NSUserDefaults *appGroupData = [[NSUserDefaults alloc]initWithSuiteName:@"group.com.appname"]; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:[self allData]]; // Get my array which I need to share [appGroupData setObject: data forKey:@"Data"]; [appGroupData synchronize];
- Вы можете получить объект в расширении:
NSUserDefaults *appGroupData = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.appname"]; NSData *data = [appGroupData dataForKey:@"Data"]; NSArray *arrReceivedData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Вам следует использовать NSUserDefaults, как показано ниже, и убедиться, что вы включили группу приложений в вашем предварительном профиле, а группа приложений должна быть настроена как зеленый символ, и она должна добавить ваш предварительный профиль и BundleID.
NSUserDefaults *sharedUserDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
[sharedUserDefault setObject:object forKey:@"yourkey"];
[sharedUserDefault synchronize];
NSUserDefaults *sharedUserDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
sharedUserDefault value = [sharedUserDefault valueForKey:@"yourkey"];