Swift API返回分配给javaScript变量的JSON。如何读取JSON?
我使用的是tumblrv1api()。我曾经为特定的JSON准备所有结构。在您可以找到的文档中,返回的JSON被分配给javaScript变量。我不知道如何从变量/JSON读取数据。当我试图读取一些参数时,出现了错误:无法读取数据,因为它的格式不正确。 你知道怎么读JSON吗Swift API返回分配给javaScript变量的JSON。如何读取JSON?,swift,nsurlsession,Swift,Nsurlsession,我使用的是tumblrv1api()。我曾经为特定的JSON准备所有结构。在您可以找到的文档中,返回的JSON被分配给javaScript变量。我不知道如何从变量/JSON读取数据。当我试图读取一些参数时,出现了错误:无法读取数据,因为它的格式不正确。 你知道怎么读JSON吗 let baseUrl = ".tumblr.com/api/read/json" let https = "https://" let userName = "timberland" le
let baseUrl = ".tumblr.com/api/read/json"
let https = "https://"
let userName = "timberland"
let jsonDecoder = JSONDecoder()
guard let mainUrl = URL(string: https + userName + baseUrl) else { return }
let urlSession = URLSession.shared
urlSession.dataTask(with: mainUrl) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
}
guard let httpResponse = response as? HTTPURLResponse else { return }
if httpResponse.statusCode == 200 {
guard let data = data else { return }
do {
let myPost = try jsonDecoder.decode(TumblrJSON.self, from: data)
DispatchQueue.main.async {
print(myPost.posts[0].id)
}
} catch {
print(error.localizedDescription)
}
}
}.resume()
和JSON结构
struct TumblrJSON: Codable {
let tumblelog: TumblrJSONTumblelog
let postsStart, postsTotal: Int
let postsType: Bool
let posts: [Post]
enum CodingKeys: String, CodingKey {
case tumblelog
case postsStart = "posts-start"
case postsTotal = "posts-total"
case postsType = "posts-type"
case posts
}
}
struct Post: Codable {
let id: String
let url, urlWithSlug: String
let type, dateGmt, date: String
let bookmarklet, mobile: Int
let feedItem: String
let fromFeedID, unixTimestamp: Int
let format, reblogKey, slug: String
let isSubmission: Bool
let likeButton, reblogButton, state, noteCount: String
let tumblelog: PostTumblelog
let regularTitle, regularBody: String
let tags: [String]
enum CodingKeys: String, CodingKey {
case id, url
case urlWithSlug = "url-with-slug"
case type
case dateGmt = "date-gmt"
case date, bookmarklet, mobile
case feedItem = "feed-item"
case fromFeedID = "from-feed-id"
case unixTimestamp = "unix-timestamp"
case format
case reblogKey = "reblog-key"
case slug
case isSubmission = "is-submission"
case likeButton = "like-button"
case reblogButton = "reblog-button"
case state
case noteCount = "note-count"
case tumblelog
case regularTitle = "regular-title"
case regularBody = "regular-body"
case tags
}
}
struct PostTumblelog: Codable {
let title, name: String
let cname: Bool
let url: String
let timezone: String
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String
let avatarURL16: String
enum CodingKeys: String, CodingKey {
case title, name, cname, url, timezone
case avatarURL512 = "avatar_url_512"
case avatarURL128 = "avatar_url_128"
case avatarURL96 = "avatar_url_96"
case avatarURL64 = "avatar_url_64"
case avatarURL48 = "avatar_url_48"
case avatarURL40 = "avatar_url_40"
case avatarURL30 = "avatar_url_30"
case avatarURL24 = "avatar_url_24"
case avatarURL16 = "avatar_url_16"
}
}
struct TumblrJSONTumblelog: Codable {
let title, description, name, timezone: String
let cname: Bool
}
JSON值
var tumblr_api_read = {"tumblelog":{"title":"Timberland","description":"","name":"timberland","timezone":"US\/Eastern","cname":false,"feeds":[]},"posts-start":0,"posts-total":493,"posts-type":false,"posts":[{"id":"132163144823","url":"http:\/\/timberland.tumblr.com\/post\/132163144823","url-with-slug":"http:\/\/timberland.tumblr.com\/post\/132163144823\/publish-x-timberland-collaboration-coming","type":"photo","date-gmt":"2015-10-29 19:33:36 GMT","date":"Thu, 29 Oct 2015 15:33:36","bookmarklet":0,"mobile":0,"feed-item":"","from-feed-id":0,"unix-timestamp":1446147216,"format":"html","reblog-key":"tG24PRhC","slug":"publish-x-timberland-collaboration-coming","is-submission":false,"like-button":"<div class=\"like_button\" data-post-id=\"132163144823\" data-blog-name=\"timberland\" id=\"like_button_132163144823\"><iframe id=\"like_iframe_132163144823\" src=\"https:\/\/assets.tumblr.com\/assets\/html\/like_iframe.html?_v=66c22ab5319d742bca5762b8d18f9d06#name=timberland&post_id=132163144823&color=black&rk=tG24PRhC\" scrolling=\"no\" width=\"20\" height=\"20\" frameborder=\"0\" class=\"like_toggle\" allowTransparency=\"true\" name=\"like_iframe_132163144823\"><\/iframe><\/div>","reblog-button":"<a href=\"https:\/\/www.tumblr.com\/reblog\/132163144823\/tG24PRhC\" class=\"reblog_button\"style=\"display: block;width:20px;height:20px;\"><svg width=\"100%\" height=\"100%\" viewBox=\"0 0 21 21\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" fill=\"#000\"><path d=\"M5.01092527,5.99908429 L16.0088498,5.99908429 L16.136,9.508 L20.836,4.752 L16.136,0.083 L16.1360004,3.01110845 L2.09985349,3.01110845 C1.50585349,3.01110845 0.979248041,3.44726568 0.979248041,4.45007306 L0.979248041,10.9999998 L3.98376463,8.30993634 L3.98376463,6.89801007 C3.98376463,6.20867902 4.71892527,5.99908429 5.01092527,5.99908429 Z\"><\/path><path d=\"M17.1420002,13.2800293 C17.1420002,13.5720293 17.022957,14.0490723 16.730957,14.0490723 L4.92919922,14.0490723 L4.92919922,11 L0.5,15.806 L4.92919922,20.5103758 L5.00469971,16.9990234 L18.9700928,16.9990234 C19.5640928,16.9990234 19.9453125,16.4010001 19.9453125,15.8060001 L19.9453125,9.5324707 L17.142,12.203\"><\/path><\/svg><\/a>","note-count":"70","tumblelog":{"title":"Timberland","name":"timberland","cname":false,"url":"http:\/\/timberland.tumblr.com\/","timezone":"US\/Eastern","avatar_url_512":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_512.png","avatar_url_128":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_128.png","avatar_url_96":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_96.png","avatar_url_64":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_64.png","avatar_url_48":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_48.png","avatar_url_40":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_40.png","avatar_url_30":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_30.png","avatar_url_24":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_24.png","avatar_url_16":"https:\/\/66.media.tumblr.com\/avatar_571109f21077_16.png"},"photo-caption":"<b>Publish X Timberland Collaboration<\/b><br\/><br\/><p>Coming November 7: our latest collaboration with Publish Brand. Mark your calendars. <\/p><p>\n (via <a href=\"http:\/\/pco.lt\/1O3sTq4\">Publish X Timberland Collaboration<\/a>)\n <\/p>","width":520,"height":347,"photo-url-1280":"https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr_nwzyc074G11r6oj70o1_540.jpg","photo-url-500":"https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr_nwzyc074G11r6oj70o1_500.jpg","photo-url-400":"https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr_nwzyc074G11r6oj70o1_400.jpg","photo-url-250":"https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr_nwzyc074G11r6oj70o1_250.jpg","photo-url-100":"https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr_nwzyc074G11r6oj70o1_100.jpg","photo-url-75":"https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr_nwzyc074G11r6oj70o1_75sq.jpg","photos":[],"tags":["collab","timberland","publishbrand","timberlandxpublish"]}]};
var tumblr\u api\u read={“Tumbllog”:{“title”:“Timberland”,“description”:“name”:“Timberland”,“timezone”:“US\/Eastern”,“cname”:false,“feed”:[]},“posts start”:0,“posts total”:493,“posts type”:false,“posts”:[{“id”:“132163144823”,“url”:“http:\/\\/Timberland.tumblr.com\/post\/132163144823”,“url with slug”:“http:\/\/timberland.tumblr.com\/post\/132163144823\/publish-x-timberland-collaboration-coming”,“type:“photo”,“date gmt:“2015-10-29 19:33:36 gmt”,“date:“Thu,Oct 2015 15:33:36”,“bookmarklet:”0,“mobile:”0,“feed item:”,“from feed id:”0,“unix时间戳”:1446147216,“format:”html”,“reblog key:“tG24PRhC”,“slug:”publish-x-timberland-collaboration-coming,“is submission”:false,“like button”:“reblog button”:“note count”:“70”,“Tumblog”:“{”title:“timberland”,“name:“timberland”,“cname:”false,“url:”http:\/\/timberland.tumblr.com\”,“timezone:”US\/Eastern”,“avatar\u url\u 512:“https:\/\/66.media.tumblr.com\/571109f21077\u 512.png”,“avatar\uURL:”128”https:\/\/66.media.tumblr.com\/avatar\u 571109f21077\u 128.png,“avatar\u url\u 96:“https:\/\/66.media.tumblr.com\/avatar\u 571109f21077\u 96.png”,“avatar\u url\u 64:“https:\/\/66.media.tumblr.com\/avatar\u 571109f21077\u 64.png”,“avatar\u url\u 48:“https:\/\/\/66.media.tumblr.com\/avatar\u 109F210748:”https:\/\/66.media.tumblr.com\/阿凡达571109f21077\u 40.png,“阿凡达url\u 30:“https:\/\/66.media.tumblr.com\/阿凡达571109f21077\u 30.png”,“阿凡达url\u 24:“https:\/\/66.media.tumblr.com\/阿凡达571109f21077\u 24.png”,“阿凡达url\u 16:“https:\/\/66.media.tumblr.com\/阿凡达url\u 109F21077”图片说明“:”发布X Timberland Collaboration即将到来的11月7日:我们与发布品牌的最新合作。标记您的日历。\n(通过发布X Timberland Collaboration)\n,“宽度”:520,“高度”:347,“照片-url-1280”:“https:\/\/66.media.tumblr.com\/55f5b1f0f1076924a8f6221740f430b1\/tumblr\u nwzyc074G11r6oj70o1\u 540.jpg”,“照片-url-500”:目前,图姆布尔尔的新ZZGGGGGGGGGGGGGGGGGGGGGGGGGZZZZGGGGGGG7-111RoJ70O1-10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10",photo-url-100:“https:\/\/66.media.tumblr.com\/55F5B1F0F1076924A8F6221704F430B1\/tumblr\u nwzyc074G11r6oj70o1\u 100.jpg”,“photo-url-75:“https:\/\/66.media.tumblr.com\/55F5F5B1F0F1076924A8F6221740B1\/tumblr\u nwzyc07G11R6OJ70O1\u 75sq.jpg”,“照片”],“tags:“tags”[“Collaberland”,“timberland”,“品牌”;“Publish”],“Publish”;“发布”];
您有一个非常特殊的情况,理想情况下我们应该获得正确格式的JSON,但如果您处于这种情况
我们在这里可以做的是获取响应并将其拆分,以获得实际的JSON,然后再次将其转换为数据,用于JSONDecoder
将您的数据任务更新为
urlSession.dataTask(with: mainUrl) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
}
guard let httpResponse = response as? HTTPURLResponse else { return }
if httpResponse.statusCode == 200 {
guard let data = data else { return }
do {
if let stringData = String(data: data, encoding: String.Encoding.utf8),
// Splitting the String to get the actual JSON
var json = stringData.components(separatedBy: "tumblr_api_read = ").last {
// Removing the ";" at the end
json.remove(at: json.index(before: String.Index(encodedOffset: json.count - 1)))
print(json)
let jsonData = json.data(using: String.Encoding.utf8)!
let myPost = try jsonDecoder.decode(TumblrJSON.self, from: jsonData)
DispatchQueue.main.async {
print(myPost.posts[0].id)
}
}
} catch {
print(error.localizedDescription)
}
}
}.resume()
另外,编辑struts以支持nil值,因为json中的一些数据是nil
struct Post: Codable {
let id: String?
let url, urlWithSlug: String?
let type, dateGmt, date: String?
let bookmarklet, mobile: Int?
let feedItem: String?
let fromFeedID, unixTimestamp: Int?
let format, reblogKey, slug: String?
let isSubmission: Bool?
let likeButton, reblogButton, state, noteCount: String?
let tumblelog: PostTumblelog?
let regularTitle, regularBody: String?
let tags: [String]?
}
struct PostTumblelog: Codable {
let title, name: String?
let cname: Bool?
let url: String?
let timezone: String?
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String?
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String?
let avatarURL16: String?
}
编辑
将所有代码从这里复制到项目中,或者只是一个游乐场,它100%工作
import Foundation
import UIKit
struct TumblrJSON: Codable {
let tumblelog: TumblrJSONTumblelog
let postsStart, postsTotal: Int
let postsType: Bool
let posts: [Post]
enum CodingKeys: String, CodingKey {
case tumblelog
case postsStart = "posts-start"
case postsTotal = "posts-total"
case postsType = "posts-type"
case posts
}
}
struct Post: Codable {
let id: String?
let url, urlWithSlug: String?
let type, dateGmt, date: String?
let bookmarklet, mobile: Int?
let feedItem: String?
let fromFeedID, unixTimestamp: Int?
let format, reblogKey, slug: String?
let isSubmission: Bool?
let likeButton, reblogButton, state, noteCount: String?
let tumblelog: PostTumblelog?
let regularTitle, regularBody: String?
let tags: [String]?
enum CodingKeys: String, CodingKey {
case id, url
case urlWithSlug = "url-with-slug"
case type
case dateGmt = "date-gmt"
case date, bookmarklet, mobile
case feedItem = "feed-item"
case fromFeedID = "from-feed-id"
case unixTimestamp = "unix-timestamp"
case format
case reblogKey = "reblog-key"
case slug
case isSubmission = "is-submission"
case likeButton = "like-button"
case reblogButton = "reblog-button"
case state
case noteCount = "note-count"
case tumblelog
case regularTitle = "regular-title"
case regularBody = "regular-body"
case tags
}
}
struct PostTumblelog: Codable {
let title, name: String?
let cname: Bool?
let url: String?
let timezone: String?
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String?
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String?
let avatarURL16: String?
enum CodingKeys: String, CodingKey {
case title, name, cname, url, timezone
case avatarURL512 = "avatar_url_512"
case avatarURL128 = "avatar_url_128"
case avatarURL96 = "avatar_url_96"
case avatarURL64 = "avatar_url_64"
case avatarURL48 = "avatar_url_48"
case avatarURL40 = "avatar_url_40"
case avatarURL30 = "avatar_url_30"
case avatarURL24 = "avatar_url_24"
case avatarURL16 = "avatar_url_16"
}
}
struct TumblrJSONTumblelog: Codable {
let title, description, name, timezone: String
let cname: Bool
}
let baseUrl = ".tumblr.com/api/read/json"
let https = "https://"
let userName = "timberland"
let jsonDecoder = JSONDecoder()
let mainUrl = URL(string: https + userName + baseUrl)!
let urlSession = URLSession.shared
urlSession.dataTask(with: mainUrl) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
}
guard let httpResponse = response as? HTTPURLResponse else { return }
if httpResponse.statusCode == 200 {
guard let data = data else { return }
do {
if let stringData = String(data: data, encoding: String.Encoding.utf8),
// Splitting the String to get the actual JSON
var json = stringData.components(separatedBy: "tumblr_api_read = ").last {
// Removing the ";" at the end
json.remove(at: json.index(before: String.Index(encodedOffset: json.count - 1)))
print(json)
let jsonData = json.data(using: String.Encoding.utf8)!
let myPost = try jsonDecoder.decode(TumblrJSON.self, from: jsonData)
DispatchQueue.main.async {
print(myPost.posts[0].id!)
}
}
} catch {
print(error.localizedDescription)
}
}
}.resume()
您有一个非常特殊的情况,理想情况下我们应该获得正确格式的JSON,但是如果您处于这种情况
我们在这里可以做的是获取响应并将其拆分,以获得实际的JSON,然后再次将其转换为数据,用于JSONDecoder
将您的数据任务更新为
urlSession.dataTask(with: mainUrl) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
}
guard let httpResponse = response as? HTTPURLResponse else { return }
if httpResponse.statusCode == 200 {
guard let data = data else { return }
do {
if let stringData = String(data: data, encoding: String.Encoding.utf8),
// Splitting the String to get the actual JSON
var json = stringData.components(separatedBy: "tumblr_api_read = ").last {
// Removing the ";" at the end
json.remove(at: json.index(before: String.Index(encodedOffset: json.count - 1)))
print(json)
let jsonData = json.data(using: String.Encoding.utf8)!
let myPost = try jsonDecoder.decode(TumblrJSON.self, from: jsonData)
DispatchQueue.main.async {
print(myPost.posts[0].id)
}
}
} catch {
print(error.localizedDescription)
}
}
}.resume()
另外,编辑struts以支持nil值,因为json中的一些数据是nil
struct Post: Codable {
let id: String?
let url, urlWithSlug: String?
let type, dateGmt, date: String?
let bookmarklet, mobile: Int?
let feedItem: String?
let fromFeedID, unixTimestamp: Int?
let format, reblogKey, slug: String?
let isSubmission: Bool?
let likeButton, reblogButton, state, noteCount: String?
let tumblelog: PostTumblelog?
let regularTitle, regularBody: String?
let tags: [String]?
}
struct PostTumblelog: Codable {
let title, name: String?
let cname: Bool?
let url: String?
let timezone: String?
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String?
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String?
let avatarURL16: String?
}
编辑
将所有代码从这里复制到项目中,或者只是一个游乐场,它100%工作
import Foundation
import UIKit
struct TumblrJSON: Codable {
let tumblelog: TumblrJSONTumblelog
let postsStart, postsTotal: Int
let postsType: Bool
let posts: [Post]
enum CodingKeys: String, CodingKey {
case tumblelog
case postsStart = "posts-start"
case postsTotal = "posts-total"
case postsType = "posts-type"
case posts
}
}
struct Post: Codable {
let id: String?
let url, urlWithSlug: String?
let type, dateGmt, date: String?
let bookmarklet, mobile: Int?
let feedItem: String?
let fromFeedID, unixTimestamp: Int?
let format, reblogKey, slug: String?
let isSubmission: Bool?
let likeButton, reblogButton, state, noteCount: String?
let tumblelog: PostTumblelog?
let regularTitle, regularBody: String?
let tags: [String]?
enum CodingKeys: String, CodingKey {
case id, url
case urlWithSlug = "url-with-slug"
case type
case dateGmt = "date-gmt"
case date, bookmarklet, mobile
case feedItem = "feed-item"
case fromFeedID = "from-feed-id"
case unixTimestamp = "unix-timestamp"
case format
case reblogKey = "reblog-key"
case slug
case isSubmission = "is-submission"
case likeButton = "like-button"
case reblogButton = "reblog-button"
case state
case noteCount = "note-count"
case tumblelog
case regularTitle = "regular-title"
case regularBody = "regular-body"
case tags
}
}
struct PostTumblelog: Codable {
let title, name: String?
let cname: Bool?
let url: String?
let timezone: String?
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String?
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String?
let avatarURL16: String?
enum CodingKeys: String, CodingKey {
case title, name, cname, url, timezone
case avatarURL512 = "avatar_url_512"
case avatarURL128 = "avatar_url_128"
case avatarURL96 = "avatar_url_96"
case avatarURL64 = "avatar_url_64"
case avatarURL48 = "avatar_url_48"
case avatarURL40 = "avatar_url_40"
case avatarURL30 = "avatar_url_30"
case avatarURL24 = "avatar_url_24"
case avatarURL16 = "avatar_url_16"
}
}
struct TumblrJSONTumblelog: Codable {
let title, description, name, timezone: String
let cname: Bool
}
let baseUrl = ".tumblr.com/api/read/json"
let https = "https://"
let userName = "timberland"
let jsonDecoder = JSONDecoder()
let mainUrl = URL(string: https + userName + baseUrl)!
let urlSession = URLSession.shared
urlSession.dataTask(with: mainUrl) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
}
guard let httpResponse = response as? HTTPURLResponse else { return }
if httpResponse.statusCode == 200 {
guard let data = data else { return }
do {
if let stringData = String(data: data, encoding: String.Encoding.utf8),
// Splitting the String to get the actual JSON
var json = stringData.components(separatedBy: "tumblr_api_read = ").last {
// Removing the ";" at the end
json.remove(at: json.index(before: String.Index(encodedOffset: json.count - 1)))
print(json)
let jsonData = json.data(using: String.Encoding.utf8)!
let myPost = try jsonDecoder.decode(TumblrJSON.self, from: jsonData)
DispatchQueue.main.async {
print(myPost.posts[0].id!)
}
}
} catch {
print(error.localizedDescription)
}
}
}.resume()
以下是正确答案和正确结构:
struct MyJsonStruct: Codable {
let tumblelog: PostTumblelog?
let postsStart: Int?
let postsTotal: Int?
let postsType: Bool?
let posts : [Post]
enum CodingKeys: String, CodingKey {
case tumblelog = "tumblelog"
case postsStart = "posts-start"
case postsTotal = "posts-total"
case postsType = "posts-type"
case posts
}
}
struct Post: Codable {
let id: String?
let url, urlWithSlug: String?
let type, dateGmt, date: String?
let bookmarklet, mobile: Int?
let feedItem: String?
let fromFeedID, unixTimestamp: Int?
let format, reblogKey, slug: String?
let isSubmission: Bool?
let likeButton, reblogButton, state, noteCount: String?
let tumblelog: PostTumblelog?
let photoCaption: String?
let width, height: Int?
let tags: [String]?
let photoUrl1280 : String?
let photoUrl500 : String?
let photoUrl400 : String?
let photoUrl250 : String?
let photoUrl100 : String?
let photoUrl75 : String?
let photos : [String]?
enum CodingKeys: String, CodingKey {
case id, url
case urlWithSlug = "url-with-slug"
case type
case dateGmt = "date-gmt"
case date, bookmarklet, mobile
case feedItem = "feed-item"
case fromFeedID = "from-feed-id"
case unixTimestamp = "unix-timestamp"
case format
case reblogKey = "reblog-key"
case slug
case isSubmission = "is-submission"
case likeButton = "like-button"
case reblogButton = "reblog-button"
case state
case noteCount = "note-count"
case tumblelog
case photoCaption = "photo-caption"
case width, height
case photoUrl1280 = "photo-url-1280"
case photoUrl500 = "photo-url-500"
case photoUrl400 = "photo-url-400"
case photoUrl250 = "photo-url-250"
case photoUrl100 = "photo-url-100"
case photoUrl75 = "photo-url-75"
case photos
case tags
}
}
struct PostTumblelog: Codable {
let title, name: String?
let description : String? = ""
let cname: Bool?
let url: String?
let timezone: String?
let feeds : [String]? = []
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String?
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String?
let avatarURL16: String?
enum CodingKeys: String, CodingKey {
case title, name, cname, url, timezone
case avatarURL512 = "avatar_url_512"
case avatarURL128 = "avatar_url_128"
case avatarURL96 = "avatar_url_96"
case avatarURL64 = "avatar_url_64"
case avatarURL48 = "avatar_url_48"
case avatarURL40 = "avatar_url_40"
case avatarURL30 = "avatar_url_30"
case avatarURL24 = "avatar_url_24"
case avatarURL16 = "avatar_url_16"
}
}
我调用解码器,如下所示:
let jsonData = json.data(using: .utf8)!
do {
let myPost = try JSONDecoder().decode(MyJsonStruct.self, from: jsonData)
print(myPost)
} catch {
print(error)
}
此外,您以不正确的方式构建json字符串:在后端插入json字符串之前,需要对html字符串进行编码,请参见示例:
<b>Publish X Timberland Collaboration</b><br/><br/><p>Coming November 7: our latest collaboration with Publish Brand. Mark your calendars. </p><p>
</p>
最后,我将“\/”替换为“/”,以生成一个好的json字符串。
之后,您可以轻松地使用swift中的json数据
然后我们有如下json字符串:
var json = """
{"tumblelog": {"title": "Timberland","description": "","name": "timberland","timezone": "US/Eastern","cname": false,"feeds": []},"posts-start": 0,"posts-total": 493,"posts-type": false,"posts": [{"id": "132163144823","url": "http://timberland.tumblr.com/post/132163144823","url-with-slug": "http://timberland.tumblr.com/post/132163144823/publish-x-timberland-collaboration-coming","type": "photo","date-gmt": "2015-10-29 19:33:36 GMT","date": "Thu, 29 Oct 2015 15:33:36","bookmarklet": 0,"mobile": 0,"feed-item": "","from-feed-id": 0,"unix-timestamp": 1446147216,"format": "html","reblog-key": "tG24PRhC","slug": "publish-x-timberland-collaboration-coming","is-submission": false,"like-button": "%3Cdiv%20class%3D%5C%22like_button%5C%22%20data-post-id%3D%5C%22132163144823%5C%22%20data-blog-name%3D%5C%22timberland%5C%22%20id%3D%5C%22like_button_132163144823%5C%22%3E%3Ciframe%20id%3D%5C%22like_iframe_132163144823%5C%22%20src%3D%5C%22https%3A%5C%2F%5C%2Fassets.tumblr.com%5C%2Fassets%5C%2Fhtml%5C%2Flike_iframe.html%3F_v%3D66c22ab5319d742bca5762b8d18f9d06%23name%3Dtimberland%26amp%3Bpost_id%3D132163144823%26amp%3Bcolor%3Dblack%26amp%3Brk%3DtG24PRhC%5C%22%20scrolling%3D%5C%22no%5C%22%20width%3D%5C%2220%5C%22%20height%3D%5C%2220%5C%22%20frameborder%3D%5C%220%5C%22%20class%3D%5C%22like_toggle%5C%22%20allowTransparency%3D%5C%22true%5C%22%20name%3D%5C%22like_iframe_132163144823%5C%22%3E%3C%5C%2Fiframe%3E%3C%5C%2Fdiv%3E","reblog-button": "%3Ca%20href%3D%5C%22https%3A%5C%2F%5C%2Fwww.tumblr.com%5C%2Freblog%5C%2F132163144823%5C%2FtG24PRhC%5C%22%20class%3D%5C%22reblog_button%5C%22style%3D%5C%22display%3A%20block%3Bwidth%3A20px%3Bheight%3A20px%3B%5C%22%3E%3Csvg%20width%3D%5C%22100%25%5C%22%20height%3D%5C%22100%25%5C%22%20viewBox%3D%5C%220%200%2021%2021%5C%22%20xmlns%3D%5C%22http%3A%5C%2F%5C%2Fwww.w3.org%5C%2F2000%5C%2Fsvg%5C%22%20xmlns%3Axlink%3D%5C%22http%3A%5C%2F%5C%2Fwww.w3.org%5C%2F1999%5C%2Fxlink%5C%22%20fill%3D%5C%22%23000%5C%22%3E%3Cpath%20d%3D%5C%22M5.01092527%2C5.99908429%20L16.0088498%2C5.99908429%20L16.136%2C9.508%20L20.836%2C4.752%20L16.136%2C0.083%20L16.1360004%2C3.01110845%20L2.09985349%2C3.01110845%20C1.50585349%2C3.01110845%200.979248041%2C3.44726568%200.979248041%2C4.45007306%20L0.979248041%2C10.9999998%20L3.98376463%2C8.30993634%20L3.98376463%2C6.89801007%20C3.98376463%2C6.20867902%204.71892527%2C5.99908429%205.01092527%2C5.99908429%20Z%5C%22%3E%3C%5C%2Fpath%3E%3Cpath%20d%3D%5C%22M17.1420002%2C13.2800293%20C17.1420002%2C13.5720293%2017.022957%2C14.0490723%2016.730957%2C14.0490723%20L4.92919922%2C14.0490723%20L4.92919922%2C11%20L0.5%2C15.806%20L4.92919922%2C20.5103758%20L5.00469971%2C16.9990234%20L18.9700928%2C16.9990234%20C19.5640928%2C16.9990234%2019.9453125%2C16.4010001%2019.9453125%2C15.8060001%20L19.9453125%2C9.5324707%20L17.142%2C12.203%5C%22%3E%3C%5C%2Fpath%3E%3C%5C%2Fsvg%3E%3C%5C%2Fa%3E","note-count": "70","tumblelog": {"title": "Timberland","name": "timberland","cname": false,"url": "http://timberland.tumblr.com/","timezone": "US/Eastern","avatar_url_512": "https://66.media.tumblr.com/avatar_571109f21077_512.png","avatar_url_128": "https://66.media.tumblr.com/avatar_571109f21077_128.png","avatar_url_96": "https://66.media.tumblr.com/avatar_571109f21077_96.png","avatar_url_64": "https://66.media.tumblr.com/avatar_571109f21077_64.png","avatar_url_48": "https://66.media.tumblr.com/avatar_571109f21077_48.png","avatar_url_40": "https://66.media.tumblr.com/avatar_571109f21077_40.png","avatar_url_30": "https://66.media.tumblr.com/avatar_571109f21077_30.png","avatar_url_24": "https://66.media.tumblr.com/avatar_571109f21077_24.png","avatar_url_16": "https://66.media.tumblr.com/avatar_571109f21077_16.png"},"photo-caption": "%3Cb%3EPublish%20X%20Timberland%20Collaboration%3C%5C%2Fb%3E%3Cbr%5C%2F%3E%3Cbr%5C%2F%3E%3Cp%3EComing%20November%207%3A%20our%20latest%20collaboration%20with%20Publish%20Brand.%20Mark%20your%20calendars.%20%3C%5C%2Fp%3E%3Cp%3E%5Cn%20%20%20%20%20%20%20%20(via%20%3Ca%20href%3D%5C%22http%3A%5C%2F%5C%2Fpco.lt%5C%2F1O3sTq4%5C%22%3EPublish%20X%20Timberland%20Collaboration%3C%5C%2Fa%3E)%5Cn%20%20%20%20%3C%5C%2Fp%3E","width": 520,"height": 347,"photo-url-1280": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_540.jpg","photo-url-500": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_500.jpg","photo-url-400": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_400.jpg","photo-url-250": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_250.jpg","photo-url-100": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_100.jpg","photo-url-75": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_75sq.jpg","photos": [],"tags": ["collab", "timberland", "publishbrand", "timberlandxpublish"]}]}
"""
以下是正确答案和正确结构:
struct MyJsonStruct: Codable {
let tumblelog: PostTumblelog?
let postsStart: Int?
let postsTotal: Int?
let postsType: Bool?
let posts : [Post]
enum CodingKeys: String, CodingKey {
case tumblelog = "tumblelog"
case postsStart = "posts-start"
case postsTotal = "posts-total"
case postsType = "posts-type"
case posts
}
}
struct Post: Codable {
let id: String?
let url, urlWithSlug: String?
let type, dateGmt, date: String?
let bookmarklet, mobile: Int?
let feedItem: String?
let fromFeedID, unixTimestamp: Int?
let format, reblogKey, slug: String?
let isSubmission: Bool?
let likeButton, reblogButton, state, noteCount: String?
let tumblelog: PostTumblelog?
let photoCaption: String?
let width, height: Int?
let tags: [String]?
let photoUrl1280 : String?
let photoUrl500 : String?
let photoUrl400 : String?
let photoUrl250 : String?
let photoUrl100 : String?
let photoUrl75 : String?
let photos : [String]?
enum CodingKeys: String, CodingKey {
case id, url
case urlWithSlug = "url-with-slug"
case type
case dateGmt = "date-gmt"
case date, bookmarklet, mobile
case feedItem = "feed-item"
case fromFeedID = "from-feed-id"
case unixTimestamp = "unix-timestamp"
case format
case reblogKey = "reblog-key"
case slug
case isSubmission = "is-submission"
case likeButton = "like-button"
case reblogButton = "reblog-button"
case state
case noteCount = "note-count"
case tumblelog
case photoCaption = "photo-caption"
case width, height
case photoUrl1280 = "photo-url-1280"
case photoUrl500 = "photo-url-500"
case photoUrl400 = "photo-url-400"
case photoUrl250 = "photo-url-250"
case photoUrl100 = "photo-url-100"
case photoUrl75 = "photo-url-75"
case photos
case tags
}
}
struct PostTumblelog: Codable {
let title, name: String?
let description : String? = ""
let cname: Bool?
let url: String?
let timezone: String?
let feeds : [String]? = []
let avatarURL512, avatarURL128, avatarURL96, avatarURL64: String?
let avatarURL48, avatarURL40, avatarURL30, avatarURL24: String?
let avatarURL16: String?
enum CodingKeys: String, CodingKey {
case title, name, cname, url, timezone
case avatarURL512 = "avatar_url_512"
case avatarURL128 = "avatar_url_128"
case avatarURL96 = "avatar_url_96"
case avatarURL64 = "avatar_url_64"
case avatarURL48 = "avatar_url_48"
case avatarURL40 = "avatar_url_40"
case avatarURL30 = "avatar_url_30"
case avatarURL24 = "avatar_url_24"
case avatarURL16 = "avatar_url_16"
}
}
我调用解码器,如下所示:
let jsonData = json.data(using: .utf8)!
do {
let myPost = try JSONDecoder().decode(MyJsonStruct.self, from: jsonData)
print(myPost)
} catch {
print(error)
}
此外,您以不正确的方式构建json字符串:在后端插入json字符串之前,需要对html字符串进行编码,请参见示例:
<b>Publish X Timberland Collaboration</b><br/><br/><p>Coming November 7: our latest collaboration with Publish Brand. Mark your calendars. </p><p>
</p>
最后,我将“\/”替换为“/”,以生成一个好的json字符串。
之后,您可以轻松地使用swift中的json数据
然后我们有如下json字符串:
var json = """
{"tumblelog": {"title": "Timberland","description": "","name": "timberland","timezone": "US/Eastern","cname": false,"feeds": []},"posts-start": 0,"posts-total": 493,"posts-type": false,"posts": [{"id": "132163144823","url": "http://timberland.tumblr.com/post/132163144823","url-with-slug": "http://timberland.tumblr.com/post/132163144823/publish-x-timberland-collaboration-coming","type": "photo","date-gmt": "2015-10-29 19:33:36 GMT","date": "Thu, 29 Oct 2015 15:33:36","bookmarklet": 0,"mobile": 0,"feed-item": "","from-feed-id": 0,"unix-timestamp": 1446147216,"format": "html","reblog-key": "tG24PRhC","slug": "publish-x-timberland-collaboration-coming","is-submission": false,"like-button": "%3Cdiv%20class%3D%5C%22like_button%5C%22%20data-post-id%3D%5C%22132163144823%5C%22%20data-blog-name%3D%5C%22timberland%5C%22%20id%3D%5C%22like_button_132163144823%5C%22%3E%3Ciframe%20id%3D%5C%22like_iframe_132163144823%5C%22%20src%3D%5C%22https%3A%5C%2F%5C%2Fassets.tumblr.com%5C%2Fassets%5C%2Fhtml%5C%2Flike_iframe.html%3F_v%3D66c22ab5319d742bca5762b8d18f9d06%23name%3Dtimberland%26amp%3Bpost_id%3D132163144823%26amp%3Bcolor%3Dblack%26amp%3Brk%3DtG24PRhC%5C%22%20scrolling%3D%5C%22no%5C%22%20width%3D%5C%2220%5C%22%20height%3D%5C%2220%5C%22%20frameborder%3D%5C%220%5C%22%20class%3D%5C%22like_toggle%5C%22%20allowTransparency%3D%5C%22true%5C%22%20name%3D%5C%22like_iframe_132163144823%5C%22%3E%3C%5C%2Fiframe%3E%3C%5C%2Fdiv%3E","reblog-button": "%3Ca%20href%3D%5C%22https%3A%5C%2F%5C%2Fwww.tumblr.com%5C%2Freblog%5C%2F132163144823%5C%2FtG24PRhC%5C%22%20class%3D%5C%22reblog_button%5C%22style%3D%5C%22display%3A%20block%3Bwidth%3A20px%3Bheight%3A20px%3B%5C%22%3E%3Csvg%20width%3D%5C%22100%25%5C%22%20height%3D%5C%22100%25%5C%22%20viewBox%3D%5C%220%200%2021%2021%5C%22%20xmlns%3D%5C%22http%3A%5C%2F%5C%2Fwww.w3.org%5C%2F2000%5C%2Fsvg%5C%22%20xmlns%3Axlink%3D%5C%22http%3A%5C%2F%5C%2Fwww.w3.org%5C%2F1999%5C%2Fxlink%5C%22%20fill%3D%5C%22%23000%5C%22%3E%3Cpath%20d%3D%5C%22M5.01092527%2C5.99908429%20L16.0088498%2C5.99908429%20L16.136%2C9.508%20L20.836%2C4.752%20L16.136%2C0.083%20L16.1360004%2C3.01110845%20L2.09985349%2C3.01110845%20C1.50585349%2C3.01110845%200.979248041%2C3.44726568%200.979248041%2C4.45007306%20L0.979248041%2C10.9999998%20L3.98376463%2C8.30993634%20L3.98376463%2C6.89801007%20C3.98376463%2C6.20867902%204.71892527%2C5.99908429%205.01092527%2C5.99908429%20Z%5C%22%3E%3C%5C%2Fpath%3E%3Cpath%20d%3D%5C%22M17.1420002%2C13.2800293%20C17.1420002%2C13.5720293%2017.022957%2C14.0490723%2016.730957%2C14.0490723%20L4.92919922%2C14.0490723%20L4.92919922%2C11%20L0.5%2C15.806%20L4.92919922%2C20.5103758%20L5.00469971%2C16.9990234%20L18.9700928%2C16.9990234%20C19.5640928%2C16.9990234%2019.9453125%2C16.4010001%2019.9453125%2C15.8060001%20L19.9453125%2C9.5324707%20L17.142%2C12.203%5C%22%3E%3C%5C%2Fpath%3E%3C%5C%2Fsvg%3E%3C%5C%2Fa%3E","note-count": "70","tumblelog": {"title": "Timberland","name": "timberland","cname": false,"url": "http://timberland.tumblr.com/","timezone": "US/Eastern","avatar_url_512": "https://66.media.tumblr.com/avatar_571109f21077_512.png","avatar_url_128": "https://66.media.tumblr.com/avatar_571109f21077_128.png","avatar_url_96": "https://66.media.tumblr.com/avatar_571109f21077_96.png","avatar_url_64": "https://66.media.tumblr.com/avatar_571109f21077_64.png","avatar_url_48": "https://66.media.tumblr.com/avatar_571109f21077_48.png","avatar_url_40": "https://66.media.tumblr.com/avatar_571109f21077_40.png","avatar_url_30": "https://66.media.tumblr.com/avatar_571109f21077_30.png","avatar_url_24": "https://66.media.tumblr.com/avatar_571109f21077_24.png","avatar_url_16": "https://66.media.tumblr.com/avatar_571109f21077_16.png"},"photo-caption": "%3Cb%3EPublish%20X%20Timberland%20Collaboration%3C%5C%2Fb%3E%3Cbr%5C%2F%3E%3Cbr%5C%2F%3E%3Cp%3EComing%20November%207%3A%20our%20latest%20collaboration%20with%20Publish%20Brand.%20Mark%20your%20calendars.%20%3C%5C%2Fp%3E%3Cp%3E%5Cn%20%20%20%20%20%20%20%20(via%20%3Ca%20href%3D%5C%22http%3A%5C%2F%5C%2Fpco.lt%5C%2F1O3sTq4%5C%22%3EPublish%20X%20Timberland%20Collaboration%3C%5C%2Fa%3E)%5Cn%20%20%20%20%3C%5C%2Fp%3E","width": 520,"height": 347,"photo-url-1280": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_540.jpg","photo-url-500": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_500.jpg","photo-url-400": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_400.jpg","photo-url-250": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_250.jpg","photo-url-100": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_100.jpg","photo-url-75": "https://66.media.tumblr.com/55f5b1f0f1076924a8f6221740f430b1/tumblr_nwzyc074G11r6oj70o1_75sq.jpg","photos": [],"tags": ["collab", "timberland", "publishbrand", "timberlandxpublish"]}]}
"""
告诉我你的JSON值。然后我可以帮你我在描述中添加了JSON结构。我无法附加获得的数据,因为即使是一篇文章,它也有太多的字符。这是一个HTML代码。解码后,由于提到的错误,我无法打印解码的JSON。我在描述中添加了API返回的JSON,以及你的问题,因为你没有对你进行编码r html字符串,然后再插入到后端的json字符串中。从字符串中创建好的数据会很麻烦。显示您的json值。然后我可以帮助您我在描述中添加了json结构。我无法附加获得的数据,因为即使是一篇文章,它也有太多的字符。这是一个html代码。解码后,由于提到的错误,我无法打印解码后的json。我将API返回的JSON添加到了描述中,还有您的问题,因为在后端插入JSON字符串之前,您没有对html字符串进行编码。从字符串创建良好的数据很麻烦。我假设可编码结构