Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Swift中将数组保存为json文件?_Json_Xcode_Swift - Fatal编程技术网

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

如何在Swift中将数组保存为json文件?,json,xcode,swift,Json,Xcode,Swift,我是斯威夫特的新手,我在这方面遇到了麻烦。所以我需要做的是将这个数组保存为iphone文档文件夹中的json文件 var levels = ["unlocked", "locked", "locked"] 然后,以后可以将其读回另一个数组。有人能告诉我怎么做吗?或者提供准确的代码来实现这一点 编辑: 我发现了一个例子。这是他们设置数据的方式: "[ {"person": {"name":"Dani","age":"24"}}, {"person": {"name":"ray","age":"

我是斯威夫特的新手,我在这方面遇到了麻烦。所以我需要做的是将这个数组保存为iphone文档文件夹中的json文件

var levels = ["unlocked", "locked", "locked"]
然后,以后可以将其读回另一个数组。有人能告诉我怎么做吗?或者提供准确的代码来实现这一点

编辑: 我发现了一个例子。这是他们设置数据的方式:

 "[ {"person": {"name":"Dani","age":"24"}}, {"person": {"name":"ray","age":"70"}} ]" 
您可以通过以下方式访问它:

 if let item = json[0] 
   { if let person = item["person"] 
     { if let age = person["age"] 
      { println(age) } } }
但是我需要能够从保存在文档文件夹中的文件中执行相同的操作。

我建议您使用framework。学习它的文档,并学习如何将字符串写入文件(提示:
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)
} 

如果你和我一样,不喜欢为这样一件小事使用全新的第三方框架,这里是我的解决方案。从在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)")
}
让documentsDirectoryPathString=NSSearchPathForDirectoriesInDomains(.DocumentDirectory、.UserDomainMask,true)。首先!
让documentsDirectoryPath=NSURL(字符串:documentsDirectoryPath字符串)!
让jsonFilePath=documentsDirectoryPath.URLByAppendingPathComponent(“test.json”)
让fileManager=NSFileManager.defaultManager()
var isDirectory:ObjCBool=false
//在Documents文件夹中创建.json文件
如果!fileManager.fileExistsAtPath(jsonFilePath.absoluteString,isDirectory:&isDirectory){
让created=fileManager.createFileAtPath(jsonFilePath.absoluteString,内容:nil,属性:nil)
如果创建{
打印(“已创建文件”)
}否则{
打印(“由于某种原因无法创建文件”)
}
}否则{
打印(“文件已存在”)
}
//创建测试数据数组
变量编号=[String]()
对于var i=0;i<100;i++{
数字。附加(“测试\(i)”)
}
//从上述数组中创建JSON
var jsonData:NSData!
做{
jsonData=尝试NSJSONSerialization.dataWithJSONObject(数字、选项:NSJSONWritingOptions())
让jsonString=String(数据:jsonData,编码:NSUTF8StringEncoding)
打印(jsonString)
}将let错误捕获为NSError{
打印(“数组到JSON转换失败:\(错误。localizedDescription)”)
}
//将该JSON写入先前创建的文件
让jsonFilePath=documentsDirectoryPath.URLByAppendingPathComponent(“test.json”)
做{
let file=try NSFileHandle(forwritingtour:jsonFilePath)
file.writeData(jsonData)
打印(“JSON数据已成功写入文件!”)
}将let错误捕获为NSError{
打印(“无法写入文件:\(错误。localizedDescription)”)
}
#1。将Swift
数组
另存为json文件 下面的Swift 3/iOS 10代码展示了如何使用
FileManager
JSONSerialization
Array
实例转换为json数据,并将其保存到位于iPhone文档目录中的json文件中:

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"}}]
*/
/*
 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)
    }
}
作为替代方案,您可以实现以下使用流的代码:

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"}}]
*/
/*
 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)
    }
}

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

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"}}]
*/
/*
 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)
    }
}
作为替代方案,您可以实现以下使用流的代码:

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"}}]
*/
/*
 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)
    }
}


Github回购协议中的游乐场展示了如何将Swift
数组保存到json文件中,以及如何读取json文件并从中获取Swift
数组。

这里是通用的Swift解决方案

我已经创建了一个泛型类,它允许轻松地进行操作

//
//  OfflineManager.swift
// 
//
//  Created by Prashant on 01/05/18.
//  Copyright © 2018 Prashant. All rights reserved.
//

import UIKit

class OfflineManager: NSObject {

    static let sharedManager = OfflineManager()
    let LocalServiceCacheDownloadDir        = "LocalData"

    // Replace case as your naming 

    enum WSCacheKeys {
        case CampignList . 
        case CampignDetail(id:String)
        case ScreenShotList

        var value:String {
            switch self {
            case .CampignList:
              return  "CampignList"
            case .CampignDetail(let id):
                return id
            case .ScreenShotList :
                return "ScreenShotList"
            }

        }
    }

    func getBaseForCacheLocal(with fileName:String) -> String? {

        let filePath = FileManager.default.getDocumentPath(forItemName: self.LocalServiceCacheDownloadDir)
        if FileManager.default.directoryExists(atPath: filePath) {
            return filePath.stringByAppendingPathComponent(fileName)
        } else {
            if  FileManager.default.createDirectory(withFolderName: self.LocalServiceCacheDownloadDir) {
                return filePath.stringByAppendingPathComponent(fileName)
            }
        }
        return nil
    }



    //------------------------------------------------------------

    @discardableResult
    func cacheDataToLocal<T>(with Object:T,to key:WSCacheKeys) -> Bool {
        let success = NSKeyedArchiver.archiveRootObject(Object, toFile: getBaseForCacheLocal(with: key.value)!)
        if success {
            print( "Local Data Cached\(String(describing: getBaseForCacheLocal(with: key.value)))")
        } else {
            print("Error")
        }

        return success

    }

    //------------------------------------------------------------

    func loadCachedDataFromLocal<T>(with key:WSCacheKeys ) -> T? {
        return NSKeyedUnarchiver.unarchiveObject(withFile: getBaseForCacheLocal(with: key.value)!) as? T
    }


    //------------------------------------------------------------


    func removeAllCacheDirs () {
        do {
            try FileManager.default.removeItem(atPath: self.getBaseForCacheLocal(with: "")!)

        } catch {
            print("error in remove dir \(error.localizedDescription)")
        }

    }

    //--------------------------------------------------------------------------------


}
下面是字符串扩展的方法

public func stringByAppendingPathComponent(_ path: String) -> String {
    let fileUrl = URL.init(fileURLWithPath: self)
    let filePath = fileUrl.appendingPathComponent(path).path
    return filePath
}
如何使用它

挽救

   OfflineManager.sharedManager.cacheDataToLocal(with: object as! [String:Any], to: .CampignList)
读取数据

    DispatchQueue.global().async {
        // GET OFFLINE DATA
        if let object:[String:Any] = OfflineManager.sharedManager.loadCachedDataFromLocal(with: .CampignList) {
            do {
                let data = try  JSONSerialization.data(withJSONObject: object, options: [])
                let object = try CampaignListResponse.init(data: data)
                self.arrCampignList = object.data ?? []
                DispatchQueue.main.async {
                    self.tableVIew.reloadData()
                }
            } catch {
            }
        }
      }

注意:您可以为json类型定义自己的
WSCacheKeys
,就像我在Swift 4中获取一些活动列表一样,这已经是内置的

您试图编码的对象必须符合
可编码
协议


阅读如何将现有对象扩展为可编码对象。

以下是Isuru在Swift 4.2中的答案。这在操场上起作用:

let documentsDirectoryPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let documentsDirectoryPath = NSURL(string: documentsDirectoryPathString)!

let jsonFilePath = documentsDirectoryPath.appendingPathComponent("test.json")
let fileManager = FileManager.default
var isDirectory: ObjCBool = false

// creating a .json file in the Documents folder
if !fileManager.fileExists(atPath: (jsonFilePath?.absoluteString)!, isDirectory: &isDirectory) {
    let created = fileManager.createFile(atPath: 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 i in 0..<100 {
    numbers.append("Test\(i)")
}

// creating JSON out of the above array
var jsonData: NSData!
do {
    jsonData = try JSONSerialization.data(withJSONObject: numbers, options: JSONSerialization.WritingOptions()) as NSData
    let jsonString = String(data: jsonData as Data, encoding: String.Encoding.utf8)
    print(jsonString as Any)
} catch let error as NSError {
    print("Array to JSON conversion failed: \(error.localizedDescription)")
}

// Write that JSON to the file created earlier
//    let jsonFilePath = documentsDirectoryPath.appendingPathComponent("test.json")
do {
    let file = try FileHandle(forWritingTo: jsonFilePath!)
    file.write(jsonData as Data)
    print("JSON data was written to teh file successfully!")
} catch let error as NSError {
    print("Couldn't write to file: \(error.localizedDescription)")
}
让documentsDirectoryPathString=NSSearchPathForDirectoriesInDomains(.documentDirectory、.userDomainMask,true)。首先!
让documentsDirectoryPath=NSURL(字符串:documentsDirectoryPath字符串)!
让jsonFilePath=documentsDirectoryPath.appendingPathComponent(“test.json”)
让fileManager=fileManager.default
var isDirectory:ObjCBool=false
//在Documents文件夹中创建.json文件
如果!fileManager.fileExists(atPath:(jsonFilePath?.absoluteString)!,isDirectory:&isDirectory){
让created=fileManager.createFile(路径:jsonFilePath!.absoluteString,内容:nil,属性:nil)
如果创建{
打印(“已创建文件”)
}否则{
打印(“由于某种原因无法创建文件”)
}
}否则{
打印(“文件已存在”)
}
//创建测试数据数组
变量编号=[String]()

对于0中的i..在我们给你“实现这一点的确切代码”之前,你能提供你在这方面的研究结果吗?我到处都找过,但找不到类似的东西。例如,我看到的所有示例代码都以这种方式提供数据“[{“person”:{“name”:“Dani”,“age”:“24”},{“person”:{“name”:“ray”,“age”:“70”}]],然后提到您可以访问这样的信息“if let item=json[0]{if let person=item[“person”]{if let age=person[“age”]{println(age)}”这比我需要做的要复杂一点,因为我只有一个简单的数组。我还没有看到任何一个例子,他们将数据保存到json文件中的文档文件夹中,显示您的研究成果可以帮助我们为您提供最佳的解决方案