Обмен данными между общим расширением iOS 8 и основным приложением

Недавно я сделал простое расширение для iOS 8, чтобы понять, как работает система. Как утверждает Apple в своем Руководстве по программированию расширений приложений:

По умолчанию содержащее приложение и его расширения не имеют прямого доступа к контейнерам друг друга.

Это означает, что расширение и содержащее приложение не обмениваются данными. Но на той же странице Apple предлагает решение:

Если вы хотите, чтобы ваше содержащее приложение и его расширения могли обмениваться данными, используйте Xcode или портал разработчика, чтобы включить группы приложений для приложения и его расширений. Затем зарегистрируйте группу приложений на портале и укажите группу приложений для использования в содержащем приложении.

Тогда становится возможным использовать NSUserDefaults для обмена данными между содержащим приложение и расширением. Это именно то, что я хотел бы сделать. Но по какой-то причине это не работает.

На той же странице Apple предлагает стандартные значения по умолчанию:

var defaults = NSUserDefaults.standardUserDefaults()

В презентации WWDC (217) они предлагают общий пакет:

var defaults = NSUserDefaults(suiteName: kDefaultsPackage)

Кроме того, я включил группы приложений как для цели приложения, так и для цели расширения с тем же именем группы приложений:Возможности XCode Target, группы приложений

Но все эти настройки даром. Я не могу получить данные, которые я сохранил в приложении, из расширения. Как будто две цели используют совершенно разные хранилища NSUserDefaults.

Так,

  1. Есть ли решение для этого метода?
  2. Как я могу поделиться простыми данными между приложением и расширением общего доступа? Данные - это просто учетные данные пользователя для 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)

Это будет работать нормально!

Вот как я это сделал:

  1. Откройте основную цель приложения> Возможности> Группы приложений, для которых установлено значение
  2. Добавьте новую группу приложений и убедитесь, что она отмечена (например, group.com.seligmanventures.LightAlarmFree)
  3. Откройте цель наблюдения (с вкладкой "Возможности") > Группы приложений, установленные на
  4. Добавьте новую группу приложений и убедитесь, что она отмечена (например, group.com.seligmanventures.LightAlarmFree - но она должна совпадать с именем группы выше)
  5. Сохраните данные в группу следующим образом:

    var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree")
    defaults?.setObject("It worked!", forKey: "alarmTime")
    defaults?.synchronize()
    
  6. Получить данные из группы следующим образом:

    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

Вы можете поделиться данными, выполнив следующие действия:

  1. Выберите ваш проект -> выберите вкладку "Возможности" -> "Включить группы приложений" -> нажмите "+" -> вставьте свой идентификатор пакета после "группы".
  2. Выберите свой добавочный номер -> выберите вкладку "Возможности" -> "Включить группы приложений" -> нажмите "+" -> вставьте свой идентификатор пакета после "группы".

    1. Поместите ниже код в основное приложение, для которого вы хотите поделиться данными:

    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];

    1. Вы можете получить объект в расширении:

    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"];
Другие вопросы по тегам