使用Alamofire/Codable解析JSON行

编程入门 行业动态 更新时间:2024-10-03 19:23:49
本文介绍了使用Alamofire/Codable解析JSON行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

是否可以使用Alamofire和codable解析JSON行?

Is it possible to parse JSON lines with Alamofire and codable?

这是我的代码.

Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseString {(response) in switch response.result { case .success(let value): print ("response is \(value)") case .failure(let error): print ("error is \(error)") } }

这会将所有JSON行打印为字符串,但我想将响应序列化为JSON数组.我该怎么做? JSON行的问题在于,它在单独的行上返回每组json,因此alamofire并不熟悉.

This prints all the JSON lines as a string but I want to serialize the response as an array of JSON. How would I do that? The problem with JSON lines is that it returns each set of json on a separate line so it is not familiar to alamofire.

这是我尝试过的方法,好像这是传统的JSON一样,显然不是,所以它不起作用:

Here is what I tried as if this was traditional JSON which obviously it is not so this did not work:

Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {(response) in switch response.result { case .success(let value): print ("response is \(value)") let decoder = JSONDecoder() decoder.dateDecodingStrategy = .secondsSince1970 let data = try! JSONSerialization.data(withJSONObject: value) do { let logs = try decoder.decode([Logs].self, from: data) completion(logs) } catch let error { print ("error parsing get logs: \(error)") } case .failure(let error): print ("failed get logs: \(error) ** \(response.result.value ?? "")") } }

对于不熟悉json行的任何人,这里是官方格式信息: jsonlines

For anybody unfamiliar with json lines here is the official format info: jsonlines

{"_logtype":"syslogline","_ingester":"agent","_ip":"40.121.203.183","pid":5573,"program":"docker","_host":"k8s-master-5A226838-0","logsource":"k8s-master-5A226838-0","_app":"syslog","_file":"/var/log/syslog","_line":"docker[5573]: I0411 00:18:39.644199 6124 conversion.go:134] failed to handle multiple devices for container. Skipping Filesystem stats","_ts":1491869920198,"timestamp":"2017-04-11T00:18:39.000Z","_id":"804760774821019649"} {"_logtype":"syslogline","_ingester":"agent","_ip":"40.121.203.183","pid":5573,"program":"docker","_host":"k8s-master-5A226838-0","logsource":"k8s-master-5A226838-0","_app":"syslog","_file":"/var/log/syslog","_line":"docker[5573]: I0411 00:18:39.644167 6124 conversion.go:134] failed to handle multiple devices for container. Skipping Filesystem stats","_ts":1491869920198,"timestamp":"2017-04-11T00:18:39.000Z","_id":"804760774821019648"} {"_logtype":"syslogline","_ingester":"agent","_ip":"40.121.203.183","pid":5573,"program":"docker","_host":"k8s-master-5A226838-0","logsource":"k8s-master-5A226838-0","_app":"syslog","_file":"/var/log/syslog","_line":"docker[5573]: I0411 00:18:37.053730 6124 operation_executor.go:917] MountVolume.SetUp succeeded for volume \"kubernetes.io/secret/6f322c04-e1d2-11e6-bca0-000d3a111245-default-token-swb07\" (spec.Name: \"default-token-swb07\") pod \"6f322c04-e1d2-11e6-bca0-000d3a111245\" (UID: \"6f322c04-e1d2-11e6-bca0-000d3a111245\").","_ts":1491869917193,"timestamp":"2017-04-11T00:18:37.000Z","_id":"804760762212941824"}

推荐答案

这里是在Alamofire中编写自定义DataSerializer的示例,可用于解码Decodable对象.

Here is an example of writing custom DataSerializer in Alamofire that you could use for decoding your Decodable object.

我正在使用一个随机帖子中的示例json url jsonplaceholder.typicode/posts

I am using an example from random posts json url jsonplaceholder.typicode/posts

这是 Post 类和自定义序列化器类 PostDataSerializer 的示例.

Here is an example of Post class and custom serializer class PostDataSerializer.

struct Post: Decodable { let userId: Int let id: Int let title: String let body: String } struct PostDataSerializer: DataResponseSerializerProtocol { enum PostDataSerializerError: Error { case InvalidData } var serializeResponse: (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<[Post]> { return { request, response, data, error in if let error = error { return .failure(error) } guard let data = data else { return .failure(PostDataSerializerError.InvalidData) } do { let jsonDecoder = JSONDecoder() let posts = try jsonDecoder.decode([Post].self, from: data) return .success(posts) } catch { return .failure(error) } } } }

您可以将其简单地挂接到Alamofire客户端上,该客户端就可以像这样将请求发送到远程url,

You could simply hook this upto your Alamofire client which sends request to remote url like so,

let request = Alamofire.request("jsonplaceholder.typicode/posts") let postDataSerializer = PostDataSerializer() request.response(responseSerializer: postDataSerializer) { response in print(response) }

您还可以在自定义序列化程序的serializeResponse getter中对错误和http响应代码进行其他错误检查.

You could also do additional error checking for the error and http response code in serializeResponse getter of the custom serializer.

对于您的json行,似乎每个json对象都以换行符分隔,即所谓的json行格式.您可以简单地用新的行字符分隔行,并将每一行解码为Log.

For you json line, it seems that each json object is separated with new line character in so called json line format. You could simply split the line with new line characters and decode each line to Log.

这是我创建的Log类.

Here is Log class I created.

struct Log: Decodable { let logType: String let ingester: String let ip: String let pid: Int let host: String let logsource: String let app: String let file: String let line: String let ts: Float64 let timestamp: String let id: String enum CodingKeys: String, CodingKey { case logType = "_logtype" case ingester = "_ingester" case ip = "_ip" case pid case host = "_host" case logsource case app = "_app" case file = "_file" case line = "_line" case ts = "_ts" case timestamp case id = "_id" } }

和可与Alamofire一起使用的自定义日志序列化程序.我没有在以下序列化程序中处理错误,希望您能做到.

And custom log serializer that you could use with your Alamofire. I have not handled error in the following serializer, I hope you can do it.

struct LogDataSerializer: DataResponseSerializerProtocol { enum LogDataSerializerError: Error { case InvalidData } var serializeResponse: (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<[Post]> { return { request, response, data, error in if let error = error { return .failure(error) } guard let data = data else { return .failure(LogDataSerializerError.InvalidData) } do { let jsonDecoder = JSONDecoder() let string = String(data: data, encoding: .utf8)! let allLogs = stringponents(separatedBy: .newlines) .filter { $0 != "" } .map { jsonLine -> Log? in guard let data = jsonLine.data(using: .utf8) else { return nil } return try? jsonDecoder.decode(Log.self, from: data) }.flatMap { $0 } return .success(allLogs) } catch { return .failure(error) } } } }

更多推荐

使用Alamofire/Codable解析JSON行

本文发布于:2023-11-26 09:46:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1633618.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Alamofire   Codable   JSON

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!