Совместное использование данных между расширением общего доступа iOS 8 и основным приложением

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

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

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

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

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

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

var defaults = NSUserDefaults.standardUserDefaults()

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

var defaults = NSUserDefaults(suiteName: kDefaultsPackage)

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

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

Итак,

  • Есть ли решение для этого метода?
  • Как я могу поделиться простыми данными между содержащим приложением и расширением share? Данные - это просто учетные данные пользователя для API.

Ответ 1

Вы должны использовать 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)

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

Ответ 2

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

  • Откройте главную цель приложения > Возможности > Группы приложений, настроенные на
  • Добавьте новую группу приложений и убедитесь, что она отмечена галочкой (например, 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")
    }
    

Ответ 3

Похоже, что это работает, только когда имя группы используется как имя для набора для NSUserDefaults.

В документации указано, что NSUserDefaults.standartUserDefaults() также должно работать, но это не так, и это, вероятно, ошибка.

Ответ 4

Если у вас

group.yourappgroup

использовать

var defaults = NSUserDefaults(suiteName: "yourappgroup")

Это работает для меня

Ответ 5

В моем сценарии я делюсь данными между родительским приложением iOS и WatchKit. Я использую Xcode 6.3.1, цель развертывания iOS 8.3

var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")

В вашем режиме просмотраDidLoad убедитесь, что вы синхронизируете:

    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()

Надеюсь, это имеет смысл

Ответ 6

Я перевел в быстрый ответ на футзальное сообщение, и он работает!!

Сохранить данные:

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

Ответ 7

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

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

Enable AppGroups in project capabilities tab

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

Enable AppGroups in Extension capabilities tab

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

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

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

NSUserDefaults * appGroupData = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.appname"];
NSData * data = [appGroupData dataForKey:@"Data"];
NSArray * arrReceivedData = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Ответ 8

Вы должны использовать 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"];