[英]Serializing Objects with Alamofire and bearer token
Using the excellent Alamofire library v1.2, in a IOS 8, Xcode 6.3 and swift project, I'm trying to serialize objects from JSON-API response and I would like to know which is the best way to accomplish it. 在IOS 8,Xcode 6.3和swift项目中,使用出色的Alamofire库v1.2,我正在尝试从JSON-API响应序列化对象,我想知道哪种是实现此目标的最佳方法。 I think the main issues in the code below are:
我认为以下代码中的主要问题是:
The JSON-API response is: JSON-API响应为:
hits = [{
"_id" : "5470def9e0c0be27780121d7",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/5470def9e0c0be27780121d7_180.png",
"name" : "Mondo",
"hasVip" : false,
"location" : {
"city" : "Madrid"
}
}, {
"_id" : "540b2ff281b30f3504a1c72f",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/540b2ff281b30f3504a1c72f_180.png",
"name" : "Teatro Kapital",
"hasVip" : false,
"location" : {
"address" : "Atocha, 125",
"city" : "Madrid"
}
}, {
"_id" : "540cd44581b30f3504a1c73b",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/540cd44581b30f3504a1c73b_180.png",
"name" : "Charada",
"hasVip" : false,
"location" : {
"address" : "La Bola, 13",
"city" : "Madrid"
}
}]
Generic Response Collection Serialization: 通用响应集合序列化:
@objc public protocol ResponseCollectionSerializable {
static func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [Self]
}
extension Alamofire.Request {
public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, [T]?, NSError?) -> Void) -> Self {
let serializer: Serializer = { (request, response, data) in
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)
if response != nil && JSON != nil {
return (T.collection(response: response!, representation: JSON!), nil)
} else {
return (nil, serializationError)
}
}
return response(serializer: serializer, completionHandler: { (request, response, object, error) in
completionHandler(request, response, object as? [T], error)
})
}
}
the Club Object Class 俱乐部对象类
final class Club: ResponseCollectionSerializable {
@objc static func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [Club] {
var clubs = [Club]()
if let representation = representation as? [[String: AnyObject]] {
for representationValue in representation {
let club = Club(JSON: representationValue)
clubs.append(club)
}
}
return clubs
}
let id: String
let name: String
let imageUrl: String
let hasVip: Bool
let location: String
init(JSON: AnyObject) {
id = JSON.valueForKeyPath("id") as! String
name = JSON.valueForKeyPath("name") as! String
imageUrl = JSON.valueForKeyPath("imageUrl") as! String
hasVip = JSON.valueForKeyPath("hasVip") as! Bool
//is OK this implementation?
location = JSON.valueForKeyPath("location") as! String
}
}
the View Controller Class 视图控制器类
class ClubsViewController: UIViewController, UITableViewDataSource{
var results: [JSON]? = []
var clubs: [Club]?
@IBOutlet var tableview:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.loadClubsObjects()
}
func loadClubsObjects(){
var URL = NSURL(string: "https://api.com/v1/clubs")
var mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/x-www-form-urlencoded")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseCollection { (request, response, clubs: [Club]?, error) in
println("request = \(request)")
println("response = \(response)")
println("clubs = \(clubs)")
println("error = \(error)")
if (json != nil){
var jsonObj = JSON(json!)
if let data = jsonObj["hits"].arrayValue as [JSON]? {
self.results = data
self.tableview.reloadData()
}
}
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.results?.count ?? 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("clubsObjectCell") as! ClubsTableViewCell
cell.clubsObject = self.results?[indexPath.row]
return cell }
}
the println(clubs) output is: println(clubs)输出为:
request = <NSMutableURLRequest: 0x7fd553725870> { URL: https://api.com/v1/clubs }
response = Optional(<NSHTTPURLResponse: 0x7fd553439e20> { URL: https://api.com/v1/clubs } { status code: 200, headers {
"Access-Control-Allow-Headers" = "X-Requested-With, Accept, Origin, Referer, User-Agent, Content-Type, Authorization";
"Access-Control-Allow-Methods" = "GET,PUT,POST,DELETE,OPTIONS";
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Type" = "application/json; charset=utf-8";
Date = "Tue, 21 Apr 2015 20:18:07 GMT";
Etag = "W/\"sEDn5KBhpfpInjAtNsF4gQ==\"";
Server = "nginx/1.6.2";
"Transfer-Encoding" = Identity;
Vary = "Accept-Encoding";
"X-Powered-By" = Express;
} })
clubs = Optional([])
error = nil
Just to make sure, could you change your last lines in the ViewController
class to be the following? 为了确保您能将
ViewController
类的最后几行更改为以下内容?
request.responseJSON { request, response, json, error in
println(request)
println(response)
println(json)
println(error)
}
I want to make sure that you have set up your request properly and are getting the response back that you expect. 我想确保您已经正确设置了请求,并且正在获得期望的响应。 That is certainly half the battle.
那肯定是成功的一半。 Once you can verify that, then we can work on the
responseCollection
parsing logic. 一旦您可以验证,就可以处理
responseCollection
解析逻辑。
Also, what version of Xcode are you using and what version of Alamofire? 另外,您正在使用什么版本的Xcode和什么版本的Alamofire?
The issue you are having is two-fold. 您遇到的问题有两个方面。
First, you are not calling your responseCollection
method correctly. 首先,您没有正确调用您的
responseCollection
方法。 You should instead call it as follows: 您应该改为按以下方式调用它:
request.responseCollection { request, response, clubs: [Club], error in
println("request = \(request)")
println("response = \(response)")
println("clubs = \(clubs)")
println("error = \(error)")
}
This will then call into your Club
class properly. 然后,这将正确地进入您的
Club
班级。
The second issue is that you are not implementing the collection
method inside your Club
object. 第二个问题是您没有在
Club
对象内部实现collection
方法。 You're never going to get any clubs without actually iterating through the collection. 如果没有真正遍历整个系列,您将永远不会得到任何俱乐部。 Something roughly like the following should get you going in the right direction.
大致类似以下内容的内容可以使您朝正确的方向前进。
final class Club: ResponseCollectionSerializable {
@objc static func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [Club] {
var clubs = [Club]()
if let representation = representation as? [[String: AnyObject]] {
for representationValue in representation {
let club = Club(JSON: representationValue)
clubs.append(club)
}
}
return clubs
}
let id: String
let name: String
let imageUrl: String
let hasVip: Bool
init(JSON: AnyObject) {
id = JSON.valueForKeyPath("id") as! String
name = JSON.valueForKeyPath("name") as! String
imageUrl = JSON.valueForKeyPath("imageUrl") as! String
hasVip = JSON.valueForKeyPath("hasVip") as! Bool
}
}
Once your collection
function is actually iterating through all the representation values in the JSON array, you should have more luck. 一旦您的
collection
功能实际上遍历了JSON数组中的所有表示形式的值,您应该会更加幸运。
For bonus points, here are a few other tips to improve your code. 对于奖励积分,这里有一些其他技巧可以改善您的代码。
Club
class to guarantee that objects are only created if the JSON is parsed successfully Club
类中使用失败的初始化程序,以确保仅在JSON成功解析后才创建对象 responseCollection
completion closure to actually store the new clubs value and display those clubs in your table view. responseCollection
完成闭包中更改您的实现,以实际存储新的Club值并在表视图中显示这些Club。 The object returned to the
responseCollection
closure is no longer a JSON AnyObject that you can use with SwiftyJSON, but instead an array of Clubs.返回到
responseCollection
闭包的对象不再是可与SwiftyJSON一起使用的JSON AnyObject,而是一个Clubs数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.