如何在Swift中将数组保存为json文件?

elp*_*ita 26 xcode json swift

我是新手,我很难解决这个问题.所以我需要做的是将此数组保存为iphone文档文件夹中的json文件.

var levels = ["unlocked", "locked", "locked"]
Run Code Online (Sandbox Code Playgroud)

然后才能将它读回另一个数组.有人可以告诉我该怎么做?或提供完成此操作的确切代码.

编辑:我找到了一个例子.这是他们设置数据的方式:

 "[ {"person": {"name":"Dani","age":"24"}}, {"person": {"name":"ray","age":"70"}} ]" 
Run Code Online (Sandbox Code Playgroud)

你可以这样访问它:

 if let item = json[0] 
   { if let person = item["person"] 
     { if let age = person["age"] 
      { println(age) } } }
Run Code Online (Sandbox Code Playgroud)

但我需要能够从保存在文档文件夹中的文件中执行相同的操作.

Isu*_*uru 38

如果你像我一样不喜欢使用全新的第三方框架只是为了这样一件小事,那么这就是我在vanilla Swift中的解决方案.从在Documents文件夹中创建.json文件到将JSON写入其中.

let documentsDirectoryPathString = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!
let documentsDirectoryPath = NSURL(string: documentsDirectoryPathString)!

let jsonFilePath = documentsDirectoryPath.URLByAppendingPathComponent("test.json")
let fileManager = NSFileManager.defaultManager()
var isDirectory: ObjCBool = false

// creating a .json file in the Documents folder
if !fileManager.fileExistsAtPath(jsonFilePath.absoluteString, isDirectory: &isDirectory) {
    let created = fileManager.createFileAtPath(jsonFilePath.absoluteString, contents: nil, attributes: nil)
    if created {
        print("File created ")
    } else {
        print("Couldn't create file for some reason")
    }
} else {
    print("File already exists")
}

// creating an array of test data
var numbers = [String]()
for var i = 0; i < 100; i++ {
    numbers.append("Test\(i)")
}

// creating JSON out of the above array
var jsonData: NSData!
do {
    jsonData = try NSJSONSerialization.dataWithJSONObject(numbers, options: NSJSONWritingOptions())
    let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding)
    print(jsonString)
} catch let error as NSError {
    print("Array to JSON conversion failed: \(error.localizedDescription)")
}

// Write that JSON to the file created earlier
let jsonFilePath = documentsDirectoryPath.URLByAppendingPathComponent("test.json")
do {
    let file = try NSFileHandle(forWritingToURL: jsonFilePath)
    file.writeData(jsonData)
    print("JSON data was written to teh file successfully!")
} catch let error as NSError {
    print("Couldn't write to file: \(error.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

  • 在 Swift 4.x 项目上使用它的任何人都必须使用 `jsonFilePath.path` 而不是 `jsonFilePath.absoluteString`。 (3认同)

Ima*_*tit 24

#1.将Swift保存Array为json文件

下面的斯威夫特3/iOS的10码演示了如何变换一个Array实例为JSON数据并将其保存到位于使用iPhone的文档目录中的一个JSON文件FileManagerJSONSerialization:

func saveToJsonFile() {
    // Get the url of Persons.json in document directory
    guard let documentDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    let fileUrl = documentDirectoryUrl.appendingPathComponent("Persons.json")

    let personArray =  [["person": ["name": "Dani", "age": "24"]], ["person": ["name": "ray", "age": "70"]]]

    // Transform array into data and save it into file
    do {
        let data = try JSONSerialization.data(withJSONObject: personArray, options: [])
        try data.write(to: fileUrl, options: [])
    } catch {
        print(error)
    }
}

/*
 Content of Persons.json file after operation:
 [{"person":{"name":"Dani","age":"24"}},{"person":{"name":"ray","age":"70"}}]
*/
Run Code Online (Sandbox Code Playgroud)

作为替代方案,您可以实现以下使用流的代码:

func saveToJsonFile() {
    // Get the url of Persons.json in document directory
    guard let documentDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    let fileUrl = documentDirectoryUrl.appendingPathComponent("Persons.json")

    let personArray =  [["person": ["name": "Dani", "age": "24"]], ["person": ["name": "ray", "age": "70"]]]

    // Create a write-only stream
    guard let stream = OutputStream(toFileAtPath: fileUrl.path, append: false) else { return }
    stream.open()
    defer {
        stream.close()
    }

    // Transform array into data and save it into file
    var error: NSError?
    JSONSerialization.writeJSONObject(personArray, to: stream, options: [], error: &error)

    // Handle error
    if let error = error {
        print(error)
    }
}

/*
 Content of Persons.json file after operation:
 [{"person":{"name":"Dani","age":"24"}},{"person":{"name":"ray","age":"70"}}]
*/
Run Code Online (Sandbox Code Playgroud)

#2.Array从json文件中获取Swift

以下Swift 3/iOS 10代码显示了如何从位于iPhone文档目录中的json文件获取数据,并Array使用FileManager和将其转换为实例JSONSerialization:

/*
 Content of Persons.json file:
 [{"person":{"name":"Dani","age":"24"}},{"person":{"name":"ray","age":"70"}}]
*/

func retrieveFromJsonFile() {
    // Get the url of Persons.json in document directory
    guard let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    let fileUrl = documentsDirectoryUrl.appendingPathComponent("Persons.json")

    // Read data from .json file and transform data into an array
    do {
        let data = try Data(contentsOf: fileUrl, options: [])
        guard let personArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: [String: String]]] else { return }
        print(personArray) // prints [["person": ["name": "Dani", "age": "24"]], ["person": ["name": "ray", "age": "70"]]]
    } catch {
        print(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

作为替代方案,您可以实现以下使用流的代码:

/*
 Content of Persons.json file:
 [{"person":{"name":"Dani","age":"24"}},{"person":{"name":"ray","age":"70"}}]
*/

func retrieveFromJsonFile() {
    // Get the url of Persons.json in document directory
    guard let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    let fileUrl = documentsDirectoryUrl.appendingPathComponent("Persons.json")

    // Create a read-only stream
    guard let stream = InputStream(url: fileUrl) else { return }
    stream.open()
    defer {
        stream.close()
    }

    // Read data from .json file and transform data into an array
    do {
        guard let personArray = try JSONSerialization.jsonObject(with: stream, options: []) as? [[String: [String: String]]] else { return }
        print(personArray) // prints [["person": ["name": "Dani", "age": "24"]], ["person": ["name": "ray", "age": "70"]]]
    } catch {
        print(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

位于Github的Save-and-read-JSON-from-Playground repo中的Playground显示了如何将Swift保存Array到json文件以及如何读取json文件并从中获取Swift Array.


Tee*_*ppa 18

我建议你使用SwiftyJSON框架.究其文档和除学习如何将字符串写入到文件(提示:NSFileHandle)

类似下面的代码,但你真的需要学习SwiftyJSON和NSFileHandle来学习如何将JSON数据序列化到文件并解析文件中的JSON数据

let levels = ["unlocked", "locked", "locked"]
let json = JSON(levels)
let str = json.description
let data = str.dataUsingEncoding(NSUTF8StringEncoding)!
if let file = NSFileHandle(forWritingAtPath:path) {
    file.writeData(data)
} 
Run Code Online (Sandbox Code Playgroud)

  • 克里斯·拉特纳(Chris Lattner)+ Swift编译器团队的其他成员建议不要使用任何第三方框架。 (3认同)
  • 这是 Codable 协议发布之前的旧答案。苹果不会因此拒绝。 (3认同)
  • 为什么要使用第三方框架来实现像JSON序列化这样的简单操作?它不必要地膨胀了您的代码,并使您面临被苹果公司拒绝的风险。 (2认同)

Mas*_*len 11

在Swift 4中,它已经内置了JSONEncoder

let pathDirectory = getDocumentsDirectory()
try? FileManager().createDirectory(at: pathDirectory, withIntermediateDirectories: true)
let filePath = pathDirectory.appendingPathComponent("levels.json")

let levels = ["unlocked", "locked", "locked"]
let json = try? JSONEncoder().encode(levels)

do {
     try json!.write(to: filePath)
} catch {
    print("Failed to write JSON data: \(error.localizedDescription)")
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}
Run Code Online (Sandbox Code Playgroud)

您要编码的对象必须符合Encodable协议。

阅读有关如何扩展现有对象以使其可编码的苹果官方指南

  • @CristianMoisei如果所有嵌套目录不存在,它将创建所有嵌套目录。例如,与将-p标志添加到mkdir命令相同。 (2认同)