2015-09-20 1 views
0

В настоящее время я работаю с SpriteKit на Xcode 7 и ios 9, и я обнаружил, что предлагаемый метод URLByAppendingPathComponent для доступа к локальным URL-адресам для файлов с комбинацией с archiveRootObject не сохраняет объект в папке назначения, а в папке «Данные». Вот кодURLByAppendingPathComponent с archiveRootObject не работает правильно?

func saveData(){ 
    let objectToSave = SomeObject() 

    let docPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String 
    let path = NSURL(string: docPath) 
    let fp = path?.URLByAppendingPathComponent("savedObject.data") 
    if NSKeyedArchiver.archiveRootObject(objectToSave, toFile: String(fp)) { 
     print("Success writing to file!") 
    } else { 
     print("Unable to write to file!") 
    } 

} 

Это, однако, сохраните данные, но в папке «Данные» рядом с папкой Bundle. (Хотя я не тестировал его на реальном устройстве).

В отладчике константа fp держит правильную строку NSURL, поэтому я просто просто не понимаю, что я делаю неправильно.

Однако, используя let fp = docPath + "/savedObject.data", а затем в функции archiveRootObject сохраняет объект в правильном месте, хотя в отладчике строки идентичны.

Мой вопрос: может кто-нибудь, пожалуйста, объясните мне, что не так с первым подходом?

+0

'fp' является' NSURL'. Используйте метод «путь», чтобы получить URL-адрес в качестве пути к файлу. – rmaddy

+0

Спасибо за ответ. Я знаю, что 'fp' является' NSURL', но не конвертируется в строку в 'String()' метод? В любом случае, не могли бы вы быть более конкретными, как достичь этого? Я все еще немного новичок в быстром, поэтому понимание этого поможет мне. – darksoul99

+1

Замените 'String (fp)' на 'ftp.path'. (Я думаю, что это правильно, я больше Objective-C, чем Swift). – rmaddy

ответ

2

В настоящее время лучшим API для использования является NSFileManager. Вы также должны использовать метод NSURL path вместо String(). Я рекомендовал бы это:

if let docDir = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first, 
    let filePath = docDir.URLByAppendingPathComponent("savedObject.data").filePathURL?.path 
{ 
    // ...Write to the path 
} 

Больше на String(x):

Я скопировал определение по String initializer «s ниже. Вы можете видеть, что он пробует несколько различных строковых представлений и в основном для целей отладки - в случае NSURL и многих других подклассов NSObject он вызывает метод Obj-C description. Вы не должны полагаться на результат description. Вместо этого вы должны использовать любые доступные для конкретной ситуации методы, например path.

extension String { 
    /// Initialize `self` with the textual representation of `instance`. 
    /// 
    /// * If `T` conforms to `Streamable`, the result is obtained by 
    /// calling `instance.writeTo(s)` on an empty string s. 
    /// * Otherwise, if `T` conforms to `CustomStringConvertible`, the 
    /// result is `instance`'s `description` 
    /// * Otherwise, if `T` conforms to `CustomDebugStringConvertible`, 
    /// the result is `instance`'s `debugDescription` 
    /// * Otherwise, an unspecified result is supplied automatically by 
    /// the Swift standard library. 
    /// 
    /// - SeeAlso: `String.init<T>(reflecting: T)` 
    public init<T>(_ instance: T) 
    ... 
+1

Большое спасибо за подробное объяснение и предложение о том, как улучшить код! С таким множеством подходов нередко легко решить, какой из них лучше всего, когда говорят одни книги, интернет говорит, что другой подход и в настоящее время лучше всего ... Его все об обучении каждый раз, и у меня есть над чем работать. Еще раз спасибо, привет. – darksoul99

+0

** Синтаксис Swift 3: ** 'if let docDir = FileManager.default.urls (для: .documentDirectory, в: .userDomainMask) .first' ... – Olivier

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

  • Нет связанных вопросов^_^