将回调 Swift JSON AnyObject 转换为 NSDictionary
Convert a callback Swift JSON AnyObject into a NSDictionary
我有一个网络连接,使用 JSON 读取数据并提供回调;
executeRequestURL(requestURL: url, taskCallback: {(status, resp) -> Void in
if (status == true) {
if let results = resp as? NSDictionary {
print ("\(results.count) results found")
let list = results.allValues.first as! NSArray
print (list)
}
} else {
print ("Error -- \(resp)")
}
})
这个调用;
private class func executeRequestURL(requestURL: NSURL, taskCallback: @escaping (Bool, AnyObject?) -> ()) {
print ("Attempting URL -- \(requestURL)")
let request: NSURLRequest = NSURLRequest(url: requestURL as URL, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: kAPI_TIMEOUT)
let session: URLSession = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard error == nil else {
print(error)
return
}
guard let data = data else {
print("Data is empty")
return
}
let json = try! JSONSerialization.jsonObject(with: data, options: [])
//print(json)
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
taskCallback(true, json as AnyObject?)
} else {
taskCallback(false, json as AnyObject?)
}
})
task.resume()
}
我遇到的问题是我想将结果读入字典,遍历它并创建对象。
现在,我会将我的代码放在 executeRequestURL 中,以确保它能正常工作,但我打算为所需的实体将这段代码分开。
问题:
我如何阅读 resp
作为字典?
谢谢
响应示例如下;
{
"objects": [
{
"uid": "coll_20ce39424470457c925f823fc150b3d4",
"title": "Popular",
"temp_image": "",
"body": "",
"active": true,
"slug": "popular",
"created": "2014-10-25T12:45:54+00:00",
"modified": "2014-10-25T12:45:54.159000+00:00",
"ends_on": "2100-01-01T00:00:00+00:00",
}
]
}
我是这样做的:
func getHttpData(urlAddress : String)
{
// Asynchronous Http call to your api url, using NSURLSession:
guard let url = URL(string: urlAddress) else
{
print("Url conversion issue.")
return
}
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
// Call whatever function you want to do with your dictionary
useMyDictionary(dictionary: json)
} catch {
print(error)
// Something went wrong
}
}
else if error != nil
{
print(error)
}
}).resume()
}
还有很多其他方法,但我喜欢使用 ObjectMapper。对我来说它看起来更干净。所以只需创建一个新的 Swift 文件,导入 ObjectMapper
并编写下面的代码。
class yourDataModel: Mappable {
// MARK: - Constants & Variables
var myObjects: [yourDataModel]
required init?(_ map: Map) {
myObjects = []
}
func mapping(map: Map) {
myObjects <- map["objects"]
}
}
class YourCustomObjects: Mappable {
// MARK: - Constants & Variables
var userId:String
var title:String
var tempimage:String
var body:String
var active:Bool
var slug : String
var createdDate:String
var modifiedDate:String
var endDate:String
// MARK: - init
required init?(_ map: Map) {
userId = ""
title = ""
tempimage = ""
body = ""
active = false
slug = ""
createdDate = ""
modifiedDate = ""
endDate = ""
}
func mapping(map: Map) {
userId <- map["uid"]
title <- map["title"]
tempimage <- map["temp_image"]
body <- map["body"]
active <- map["active"]
slug <- map["slug"]
createdDate <- map["created"]
modifiedDate <- map["modified"]
endDate <- map["ends_on"]
}
}
基本上它是您的模型 class,现在您只需将结果传递给 JSON,希望它是 AnyObject,它会给您一个包含所有 [=20] 的数组=] 在里面。你可以像下面这样使用它
if let data = Mapper<yourDataModel>().map(resp){
print(data)
}
试试这个,如果遇到任何困难,请告诉我。
由于 JSON 是字典,因此 return 是回调中的字典 ([String:Any]
)。在Swift 3AnyObject
变成了Any
。 Swift 的强类型系统鼓励尽可能具体。
做更好的错误处理!你应该 return 一个错误而不仅仅是 false
.
代码使用了新的 Swift 3 结构 URL
和 URLRequest
private class func executeRequestURL(requestURL: URL, taskCallback: @escaping (Bool, [String:Any]?) -> ()) {
print ("Attempting URL -- \(requestURL)")
let request = URLRequest(url: requestURL, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: kAPI_TIMEOUT)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) in
guard error == nil else {
print(error)
taskCallback(false, nil)
return
}
guard let data = data else {
print("Data is empty") // <- this will never be reached. If there is no error,
taskCallback(false, nil) // data is always non-nil.
return
}
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
let json = try! JSONSerialization.jsonObject(with: data, options: []) as! [String:Any]
taskCallback(true, json)
} else {
taskCallback(false, nil)
}
})
task.resume()
}
JSON 结果包含一个带有一个键 objects
的字典,其中包含一个字典数组。 JSON集合类型很容易区分:{}
是字典,[]
是数组。
要将 JSON 映射到对象,请创建结构
struct Item {
var uid : String
var title : String
var tempImage : String
var body : String
var active : Bool
var slug : String
var created : String
var modified : String
var endOn : String
}
和一个数组
var items = [Item]()
然后将字典映射到Item
if let objects = json["objects"] as? [[String:Any]] {
for object in objects {
let uid = object["uid"] as! String
var title = object["title"] as! String
var tempImage = object["temp_image"] as! String
var body = object["body"] as! String
var active = object["active"] as! Bool
var slug = object["slug"] as! String
var created = object["created"] as! String
var modified = object["modified"] as! String
var endOn = object["end_on"] as! String
let item = Item(uid: uid, title: title, tempImage:tempImage, body: body, active: active, slug: slug, created: created, modified: modified, endOn: endOn)
items.append(item)
}
JSON 值似乎来自数据库,该数据库始终包含所有字段,因此强制展开的值是安全的。
我有一个网络连接,使用 JSON 读取数据并提供回调;
executeRequestURL(requestURL: url, taskCallback: {(status, resp) -> Void in
if (status == true) {
if let results = resp as? NSDictionary {
print ("\(results.count) results found")
let list = results.allValues.first as! NSArray
print (list)
}
} else {
print ("Error -- \(resp)")
}
})
这个调用;
private class func executeRequestURL(requestURL: NSURL, taskCallback: @escaping (Bool, AnyObject?) -> ()) {
print ("Attempting URL -- \(requestURL)")
let request: NSURLRequest = NSURLRequest(url: requestURL as URL, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: kAPI_TIMEOUT)
let session: URLSession = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard error == nil else {
print(error)
return
}
guard let data = data else {
print("Data is empty")
return
}
let json = try! JSONSerialization.jsonObject(with: data, options: [])
//print(json)
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
taskCallback(true, json as AnyObject?)
} else {
taskCallback(false, json as AnyObject?)
}
})
task.resume()
}
我遇到的问题是我想将结果读入字典,遍历它并创建对象。
现在,我会将我的代码放在 executeRequestURL 中,以确保它能正常工作,但我打算为所需的实体将这段代码分开。
问题:
我如何阅读 resp
作为字典?
谢谢
响应示例如下;
{
"objects": [
{
"uid": "coll_20ce39424470457c925f823fc150b3d4",
"title": "Popular",
"temp_image": "",
"body": "",
"active": true,
"slug": "popular",
"created": "2014-10-25T12:45:54+00:00",
"modified": "2014-10-25T12:45:54.159000+00:00",
"ends_on": "2100-01-01T00:00:00+00:00",
}
]
}
我是这样做的:
func getHttpData(urlAddress : String)
{
// Asynchronous Http call to your api url, using NSURLSession:
guard let url = URL(string: urlAddress) else
{
print("Url conversion issue.")
return
}
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
// Call whatever function you want to do with your dictionary
useMyDictionary(dictionary: json)
} catch {
print(error)
// Something went wrong
}
}
else if error != nil
{
print(error)
}
}).resume()
}
还有很多其他方法,但我喜欢使用 ObjectMapper。对我来说它看起来更干净。所以只需创建一个新的 Swift 文件,导入 ObjectMapper
并编写下面的代码。
class yourDataModel: Mappable {
// MARK: - Constants & Variables
var myObjects: [yourDataModel]
required init?(_ map: Map) {
myObjects = []
}
func mapping(map: Map) {
myObjects <- map["objects"]
}
}
class YourCustomObjects: Mappable {
// MARK: - Constants & Variables
var userId:String
var title:String
var tempimage:String
var body:String
var active:Bool
var slug : String
var createdDate:String
var modifiedDate:String
var endDate:String
// MARK: - init
required init?(_ map: Map) {
userId = ""
title = ""
tempimage = ""
body = ""
active = false
slug = ""
createdDate = ""
modifiedDate = ""
endDate = ""
}
func mapping(map: Map) {
userId <- map["uid"]
title <- map["title"]
tempimage <- map["temp_image"]
body <- map["body"]
active <- map["active"]
slug <- map["slug"]
createdDate <- map["created"]
modifiedDate <- map["modified"]
endDate <- map["ends_on"]
}
}
基本上它是您的模型 class,现在您只需将结果传递给 JSON,希望它是 AnyObject,它会给您一个包含所有 [=20] 的数组=] 在里面。你可以像下面这样使用它
if let data = Mapper<yourDataModel>().map(resp){
print(data)
}
试试这个,如果遇到任何困难,请告诉我。
由于 JSON 是字典,因此 return 是回调中的字典 ([String:Any]
)。在Swift 3AnyObject
变成了Any
。 Swift 的强类型系统鼓励尽可能具体。
做更好的错误处理!你应该 return 一个错误而不仅仅是 false
.
代码使用了新的 Swift 3 结构 URL
和 URLRequest
private class func executeRequestURL(requestURL: URL, taskCallback: @escaping (Bool, [String:Any]?) -> ()) {
print ("Attempting URL -- \(requestURL)")
let request = URLRequest(url: requestURL, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: kAPI_TIMEOUT)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) in
guard error == nil else {
print(error)
taskCallback(false, nil)
return
}
guard let data = data else {
print("Data is empty") // <- this will never be reached. If there is no error,
taskCallback(false, nil) // data is always non-nil.
return
}
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
let json = try! JSONSerialization.jsonObject(with: data, options: []) as! [String:Any]
taskCallback(true, json)
} else {
taskCallback(false, nil)
}
})
task.resume()
}
JSON 结果包含一个带有一个键 objects
的字典,其中包含一个字典数组。 JSON集合类型很容易区分:{}
是字典,[]
是数组。
要将 JSON 映射到对象,请创建结构
struct Item {
var uid : String
var title : String
var tempImage : String
var body : String
var active : Bool
var slug : String
var created : String
var modified : String
var endOn : String
}
和一个数组
var items = [Item]()
然后将字典映射到Item
if let objects = json["objects"] as? [[String:Any]] {
for object in objects {
let uid = object["uid"] as! String
var title = object["title"] as! String
var tempImage = object["temp_image"] as! String
var body = object["body"] as! String
var active = object["active"] as! Bool
var slug = object["slug"] as! String
var created = object["created"] as! String
var modified = object["modified"] as! String
var endOn = object["end_on"] as! String
let item = Item(uid: uid, title: title, tempImage:tempImage, body: body, active: active, slug: slug, created: created, modified: modified, endOn: endOn)
items.append(item)
}
JSON 值似乎来自数据库,该数据库始终包含所有字段,因此强制展开的值是安全的。