2016-02-18 2 views
3

У меня есть группа массивов, в которой все содержат несколько экземпляров пользовательского объекта задачи, который я создал. Я спасаю массивы в NSUserDefaults следующим образом:Не удается получить данные из NSUserDefaults в сегодняшнее расширение (Swift)

Пользовательские задачи Объект

class Task:NSObject, NSCoding { 
    var name:String 
    var notes:String 
    var date:NSDate 
    var dateUse:Bool 
    var taskCompleted:Bool 

    init(name:String, notes:String, date:NSDate, dateUse:Bool, taskCompleted:Bool){ 
     self.name = name 
     self.notes = notes 
     self.date = date 
     self.dateUse = dateUse 
     self.taskCompleted = taskCompleted 
    } 

    required init(coder decoder: NSCoder){ 
     self.name = decoder.decodeObjectForKey("name") as! String 
     self.notes = decoder.decodeObjectForKey("notes") as! String 
     self.date = decoder.decodeObjectForKey("date") as! NSDate 
     self.dateUse = decoder.decodeObjectForKey("dateUse") as! Bool 
     self.taskCompleted = decoder.decodeObjectForKey("taskCompleted") as! Bool 
    } 

    func encodeWithCoder(coder: NSCoder) { 
     coder.encodeObject(self.name, forKey: "name") 
     coder.encodeObject(self.notes, forKey: "notes") 
     coder.encodeObject(self.date, forKey: "date") 
     coder.encodeObject(self.dateUse, forKey: "dateUse") 
     coder.encodeObject(self.taskCompleted, forKey: "taskCompleted") 
    } 
} 

Экономия:

let defaults = NSUserDefaults(suiteName: "group.com.myGroupName") 

let nowData = NSKeyedArchiver.archivedDataWithRootObject(nowTasks) 
defaults!.setObject(nowData, forKey: "nowData") 

Получение

let nowDataPull = defaults!.objectForKey("nowData") as? NSData 
if let nowDataPull2 = nowDataPull{ 
    let nowTasks2 = NSKeyedUnarchiver.unarchiveObjectWithData(nowDataPull2) as? [Task] 
    if let nowTasks21 = nowTasks2{ 
     nowTasks = nowTasks21 
    } 
} 

Указанный выше метод отлично подходит для установки и извлечения данных с самого iPhone. Однако этот метод не работает при попытке получить данные через сегодняшнее расширение.

При попытке извлечь из файла .swift внутренней линии сегодня, я получаю следующие ошибки:

  • Не удалось наследовать разрешения Coremedia от 52550: (нуль)

  • , истекающий приложение из-за uncached exception 'NSInvalidUnarchiveOperationException', reason: '* - [NSKeyedUnarchiver decodeObjectForKey:]: не может декодировать объект класса (MyAppName.Task) для ключа (NS.objects); класс может быть определен в исходном коде или библиотека, которая не связана»


Я знаю, что расширение может считывать данные, потому что, когда я звоню:

if (defaults?.objectForKey("nowData") != nil){ 
    print("there is data") 
} 

Я получаю отпечатанный ответ ..


Успех полностью сохранить Integer и получить через расширение сегодня, но не objectForKey


Я пробовал различные другие методы экономии, включая .plist файлы, но ничего, кажется, работает. Те же ошибки сохраняются. Любой вход был бы признателен!

+0

Я заметил, что ошибка относится к 'MyAppName.Task'. Возможно, класс Task принадлежит к другому модулю при компиляции в рамках Today Extension? –

+0

@MikePollard У меня есть все объявление класса задачи внутри файла с именем sharedCode.swift. Этот файл «проверен» с целевым членством как для основного приложения, так и для сегодняшнего расширения .. –

ответ

1

Обход:

Так я нашел обходной путь (который на самом деле более эффективным) для моей проблемы.Поскольку декодирование [Task] вызывало проблемы, я решил продолжить работу и получить данные из массива, в котором не было объектов, а всего лишь NSDate() экземпляров. Из-за этого я могу теперь сохранить и получить доступ к важным аспектам данных, которые необходимы сегодняшнему расширению. Я призываю всех, у кого возникли проблемы с декодированием пользовательского класса, попытаться и упростить ваши данные, если это вообще возможно, для извлечения и использования в расширении. Я не совсем уверен, что проблема была или есть, но получение простых данных из массива, хранящегося в NSUserDefaults, работает без проблем.

Надеюсь, что вся эта ерунда может помочь кому-то еще!

+0

Я склоняюсь к тому, чтобы делать то же самое. В моем случае я знаю, что пользовательский класс связан как с App, так и с Today Extension, но архивирование и дизархирование работает только в самом iPhone-приложении. Я не могу не чувствовать, что должен быть лучший способ сделать это! – cptdanko

+0

У меня была такая же точная проблема. Пробыв несколько дней, я нашел другое решение. Возможно, вы захотите это сделать. –

1
let default = NSUserDefault() 
default.objectForKey("key") 
+1

как это ответить? – cptdanko

1

Set Object

let defaults = NSUserDefaults.standardUserDefaults() 
defaults.setObject("iOS", forKey: "userNameKey") 

defaults.setInteger(25, forKey: "Age") 
defaults.setBool(true, forKey: "UseTouchID") 
defaults.setDouble(M_PI, forKey: "Pi") 

Чтение

let defaults = NSUserDefaults.standardUserDefaults() 
let name = defaults.stringForKey("userNameKey") 
+2

Я не думаю, что 'standardUserDefaults()' работает с общими данными между приложением и расширением? Я уверен, что вы должны объявить название группы. –

4

Другой способ - исправить имя класса, используемого для NSCoding. Вы просто должны использовать:

  • NSKeyedArchiver.setClassName("Task", forClass: Task.self перед сериализацией
  • NSKeyedUnarchiver.setClass(Task.self, forClassName: "Task") перед тем десериализации

везде, где это необходимо.

Похоже, что расширения iOS префиксное имя класса с именем расширения.

+2

Это самое общее решение для расширений iOS (и должно быть принятым ответом). –

Смежные вопросы