Чтение файла в Swift, игровая площадка iOS

Изучив множество (много!) вопросов о быстрой игровой площадке, чтобы даже создать этот код, я все еще борюсь.

Я поместил текстовый файл в папку Resources содержимого пакета, и он отображается как псевдоним (ссылка) в запущенных временных файлах, созданных игровой площадкой (/var/folders/ ...).

import UIKit

let bundle = NSBundle.mainBundle()

let myFilePath = bundle.pathForResource("dict1", ofType: "txt")

println(myFilePath)    // <-- this is correct, there is a shortcut to the Resource file at this location

var error:NSError?

var content = String(contentsOfFile:myFilePath!, encoding:NSUTF8StringEncoding, error: &error)

println(content!)  // <-- this is *NOT* the file contents [EDIT: see later note]

// Demonstrate there's no error
if let theError = error {
    print("\(theError.localizedDescription)")
} else {
    print("No error")
}

Проблема в том, что content отображается в выводе игровой площадки как Some "apple\ngame\nhow\nswift\ntoken", а не содержимое файла, как ожидалось.

Это поиск файла, потому что, если я изменю имя файла, возникнут ошибки. Любые советы по получению содержимого файла?

Xкод 6.1

EDIT: Итак, настоящая проблема заключалась в том, что я не ожидал, что вывод игровой площадки (включая println) будет экранирован. Это, в сочетании с усталостью и другими глупостями, заставило меня поверить в существование проблемы, хотя ее не существовало.

Интересно, что не все, кажется, сбежало на детской площадке:

println("foo\nbar")    // Outputs "foo\nbar", escaped
println("\\n")         // Outputs "\n", unescaped

person alttag    schedule 23.10.2014    source источник
comment
Этот код у меня работает нормально, если я помещу файл dict1.txt в нужное место. Что находится в вашем файле dict1.txt и чем оно отличается от того, что вы видите в своей переменной content?   -  person Mike S    schedule 24.10.2014
comment
@MikeS, удивительно, как твой простой вопрос привел меня к (очевидному) ответу. Да, конечно content соответствует файлу. Я никогда не должен программировать уставшим. Что меня сбило с толку, так это сбежавший '\n', из-за которого содержимое выглядело как путь.   -  person alttag    schedule 24.10.2014
comment
Насколько я понимаю, вывод игровой площадки println != вывод консоли println. Дополнительная информация о консоли в этом вопросе.   -  person alttag    schedule 24.10.2014


Ответы (2)


Вы можете попробовать создать класс для открытия и сохранения ваших файлов:

обновление: Xcode 10 • Swift 4.2

class File {
    class func open(_ path: String, encoding: String.Encoding = .utf8) -> String? {
        if FileManager.default.fileExists(atPath: path) {
            do {
                return try String(contentsOfFile: path, encoding: encoding)
            } catch {
                print(error)
                return nil
            }
        }
        return  nil
    }

    class func save(_ path: String, _ content: String, encoding: String.Encoding = .utf8) -> Bool {
        do {
            try content.write(toFile: path, atomically: true, encoding: encoding)
            return true
        } catch {
            print(error)
            return false
        }
    }
}

использование: File.save

let stringToSave: String = "Your text"

let didSave = File.save("\(NSHomeDirectory())/Desktop/file.txt", stringToSave) 

if didSave { print("file saved") } else { print("error saving file") } 

использование: File.open

if let loadedData = File.open("\(NSHomeDirectory())/Desktop/file.txt") {
    print(loadedData)
} else {
    println("error reading file")
 }  

Если вы предпочитаете работать с URL (как это делаю я и как рекомендует Apple):
Обратите внимание, что в Swift 4 класс URL уже существует.

class Url {
    class func open(url: URL) -> String? {
        do {
            return try String(contentsOf: url, encoding: String.Encoding.utf8)
        } catch {
            print(error)
            return nil
        }
    }

    class func save(url: URL, fileContent: String) -> Bool {
        do {
            try fileContent.write(to: url, atomically: true, encoding: .utf8)
            return true
        } catch {
            print(error)
            return false
        }
    }
}
person Leo Dabus    schedule 24.10.2014

Я видел эту проблему с файлами .txt, созданными из файлов .rtf с помощью TextEdit.

Я загрузил файл text.txt в папку ресурсов моей игровой площадки, используя аналогичный вам код. Содержимое файла было «привет» и было создано путем преобразования файла .rtf в .txt путем изменения расширения.

let path = NSBundle.mainBundle().pathForResource("text", ofType: "txt")//or rtf for an rtf file
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!
println(text)

Результат был:

{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf140 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww10800\viewh8400\viewkind0 \pard\\tx720 tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural

\f0\fs24 \cf0 привет}

Таким образом, «привет там» встроено. Это проблема со всей информацией о макете в файле .rtf.

Я вернулся в TextEdit и создал настоящий файл .txt. После открытия файла - Формат|Сделать обычным текстом

Теперь этот же код выдавал на консоль вывод «привет».

person Steve Rosenberg    schedule 24.10.2014
comment
Полезная информация, но очевидно, что этот вопрос не страдает от проблемы с RTF. И как бы глупо я ни чувствовал себя из-за ошибки, которую я совершил, я уверен, что не сделал бы эту ошибку! - person alttag; 24.10.2014