读取json文件并在表视图上显示错误:

时间:2018-06-15 16:02:25

标签: ios json swift

每次我在API上发布

时,我都会在文件中保存Alamofire JSON响应
xs

然后我想在tableview中显示这个响应,我想反序列化,所以我把它放在循环中它给了我这个错误:

  

错误域= NSCocoaErrorDomain代码= 3840“垃圾结束。” UserInfo = {NSDebugDescription =结尾处的垃圾。}

xs

编辑:  这是我从阿拉莫火中救出的:

{
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:07.515+0000"}
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:14.420+0000"}
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:23.183+0000"}
}

这是writetofile方法

let DocumentDirURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

let fileURL = DocumentDirURL.appendingPathComponent("x").appendingPathExtension("json")
var readString = ""

do {
    readString = try String(contentsOf: fileURL)
    let data = readString.data(using: .utf8)!
    do {
        if let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject] {
           let form_name = jsonArray[0]["message"] as? String
           print (" midas \(jsonArray) + ")
        } else {
            print("bad json")
        }
    } catch let error as NSError {
        print(error)
    }
}

更新: 由于DávidPásztor和vadian

,我设法解决了这个问题
.responseJSON() { response in

            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
               self.savestrin = utf8Text + "\n"
                print("Data: \(self.savestrin)")
            } 

            self.writeToFile(content: self.savestrin )

现在的问题我怎么不能在表视图中填充它。我试着

func writeToFile(content: String) {
     let documentsPath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

    let filePath = documentsPath.appendingPathComponent("x").appendingPathExtension("json")

    //Check if file exists
    if let fileHandle = FileHandle(forWritingAtPath: filePath.path) {
        //Append to file
        fileHandle.seekToEndOfFile()
        fileHandle.write(content.data(using: String.Encoding.utf8)!)
    }
    else {
        //Create new file
        do {
            try content.write(to: filePath, atomically: true, encoding: String.Encoding.utf8)
        } catch {
            print("Error creating \(filePath)")
        }
    }
}

2 个答案:

答案 0 :(得分:0)

这是预期的错误,因为您的JSON文件无效。您需要将第一个外括号{}更改为方括号[],因为您要存储一个字典数组,并且需要使用逗号分隔各个响应。

这就是你的JSON应该是这样的:

[
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:07.515+0000"},
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:14.420+0000"},
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:23.183+0000"}
]

您的JSON解析器逻辑也存在缺陷。您不应该使用let reading = readString.components(separatedBy: ",")将JSON分离为组件,您应该简单地解析整个JSON文件。此外,无需将文件解析为String,您可以直接将其读入Data并将其传递给JSONSerialization。也不需要嵌套的do-catch块,Swift中的JSON字典类型应为[String:Any],而不是[String:AnyObject],字典数组为[[String:Any]]

do {
    let jsonData = try Data(contentsOf: fileURL)
    if let jsonArray = try JSONSerialization.jsonObject(with: jsonData) as? [[String:Any]] {
        let form_name = jsonArray.first?["message"] as? String
        print (" midas \(jsonArray) + ")
    } else {
        print("bad json")
    }
} catch {
    print(error)
}

答案 1 :(得分:0)

我认为您可以使用Codable协议大大简化代码。在您当前的上下文中,Playground可能如下所示:

import Cocoa

let jsonData = """
[
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:07.515+0000"},
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:14.420+0000"},
{"response":99,"message":"You are signing in after Fri Jun 15 10:50:00 EDT 2018.","date":"2018-06-15T14:50:23.183+0000"}
]
""".data(using: .utf8)!

struct Response : Codable {
    let code : Int
    let message:String
    let date: Date

    private enum CodingKeys : String, CodingKey {
        case code = "response"
        case message, date
    }
}

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"

do {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .formatted(formatter)

    let responses = try decoder.decode([Response].self, from:jsonData)
    print(responses)
} catch {
    print(error)
}

这将向您展示如何根据DávidPásztor的建议解析更改的文件。由于它实现了Codable,它还可以帮助您正确地编写文件。您可能还会注意到,它允许您轻松地从JSON解析日期。