2016-08-15 11 views
0

Для того, чтобы избежать будучи проблемой XY, вот некоторые фон:Как хранить NSManagedObjectID постоянно?

Мое приложение позволяет пользователям создавать и сохранять множество настроек вроде как Xcode в шрифты и цвета Chooser:

enter image description here

Это происходит потому, что есть много вещей, которые пользователи могут установить. Было бы проще просто нажать на сохраненную настройку вместо того, чтобы снова установить все эти вещи.

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

Моя первая мысль состояла в том, чтобы хранить NSManagedObject экземпляр подкласса в NSUserDefaults. Но согласно документации, я не могу сохранить его, если я не преобразовать его в NSData:

объект

по умолчанию должен быть список свойств, то есть экземпляр (или для коллекций комбинации экземпляров) : NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary.

Затем я попытался хранения objectID экземпляра NSManagedObject подкласса. Я вижу, что существует метод URIRepresentation(), который возвращает NSURL. Поэтому я думал, что это сработает:

NSData(contentsOfURL: selectedOption!.objectID.URIRepresentation()) 

Но инициализатор каким-то образом сработал.

Теперь я понимаю, что это глупая идея, потому что, даже если я могу преобразовать ее в NSData, я не могу преобразовать NSData в NSManagedObjectID!

Согласно this question, ОП, кажется, чтобы иметь возможность хранить идентификатор объекта:

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

Как я могу это сделать?

+0

Вы можете просто сохранить строковое значение URIRпредставления в NSUserDefaults. Позже вы можете загрузить эту строку, затем использовать 'managedObjectIDForURIRepresentation', чтобы получить NSObjectId, а затем' objectWithID', чтобы получить NSManagedObject – Paulw11

+0

@ Paulw11, то как я могу преобразовать строку в соответствующий NSManagedObject? – Sweeper

+0

Как я уже сказал, указав URL-адрес 'managedObjectIDForURIRпредставляя' и предоставив объект, который мне был бы возвращен' objectWithID' В контексте управляемого объекта – Paulw11

ответ

3

NSUserDefaults есть "удобные методы"

public func setURL(url: NSURL?, forKey defaultName: String) 
public func URLForKey(defaultName: String) -> NSURL? 

, которые позволяют хранить и извлекать NSURL подобно полученному по URIRepresentation(). Конверсия в NSData обрабатывается прозрачно. Из documentation:

Когда NSURL хранится с использованием -[NSUserDefaults setURL:forKey:], некоторые корректировки сделаны:

  1. Любой не-файл URL записывается с помощью вызова +[NSKeyedArchiver archivedDataWithRootObject:] используя экземпляр NSURL в качестве корневого объекта.
  2. ...

Когда NSURL считывается с помощью -[NSUserDefaults URLForKey:], используется следующая логика:

  1. Если значение ключа является NSData, то NSData используется в качестве аргумента +[NSKeyedUnarchiver unarchiveObjectWithData:]. Если NSData можно разблокировать как NSURL, NSURL будет возвращен, иначе возвращается nil.
  2. ...

Так экономия управляемый объект ID просто сделать, как

NSUserDefaults.standardUserDefaults().setURL(object.objectID.URIRepresentation(), 
              forKey: "selected") 

и получения идентификатора объекта и объекта, например так:

if let url = NSUserDefaults.standardUserDefaults().URLForKey("selected"), 
    let oid = context.persistentStoreCoordinator!.managedObjectIDForURIRepresentation(url), 
    let object = try? context.existingObjectWithID(oid) { 

    print(object) 
    // ... 
} 

Для альтернативных способов сохранения выбранных параметров см. the above comment.

+0

Итак, как я могу преобразовать URL/NSData обратно в NSManagedObject? – Sweeper

+0

@ Paulw11 уже ответил на этот вопрос в комментариях к вопросу – Wain

+0

Спасибо. Я просто вернулся с обеда. Вот почему я так поздно ответил. :) – Sweeper