Swift: 用Alamofire做http请求,用ObjectMapper解析JSON
跟不上时代的人突然间走在了时代的前列,果然有别样的风景。首先鄙视一下AFNetworking。这个东西实在太难用了。不想封装都不行,要不写一大堆代码。 NSURL *URL = [NSURL URLWithString:@"http://example.com/resources/123.json"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:URL.absoluteString parameters:nil
progress:nil
success:^(NSURLSessionTask *task,id responSEObject) {
NSLog(@"JSON: %@",responSEObject);
}
failure:^(NSURLSessionTask *operation,NSError *error) {
NSLog(@"Error: %@",error);
}
];
Http请求但是用alamofire就简单的很多了,如: Alamofire.request(.GET,"https://httpbin.org/get",parameters: ["foo": "bar"])
.response { request,response,data,error in
print(response)
}
都是一个GET请求,但是可见的是Alamofire代码量少很多。这也是和AFNetworking3.x比较了,如果你用的是AFNetworking2.x的话代码量的对比更加明显。对于程序员来说调用方法的API简单方便就是用户体验。Developer们也是需要满足UE的需要的。 下面开始进入正题。下面用请求微博的time line来做栗子。 parameters = ["access_token": weiboUserInfo.accessToken ?? "","source": ConstantUtil.WEIBO_APPKEY] //1
Alamofire.request(.GET,"https://api.weibo.com/2/statuses/friends_timeline.json" //2,parameters: parameters,encoding: .URL,headers: nil)
.responseString(completionHandler: {response in
print("response:- (response)") //3
})
这里用Alamofire请求微博的time line。 如果一切设置正确,你会看到这样的结果: {
"statuses": [
{
"created_at": "Tue May 31 17:46:55 +0800 2011","id": 11488058246,"text": "求关注。",
"source": "<a href="http://weibo.com" rel="nofollow">新浪微博</a>","favorited": false,"truncated": false,"in_reply_to_status_id": "","in_reply_to_user_id": "","in_reply_to_screen_name": "","geo": null,"mid": "5612814510546515491","reposts_count": 8,"comments_count": 9,"annotations": [],"user": {
"id": 1404376560,"screen_name": "zaku","name": "zaku","province": "11","city": "5","location": "北京 朝阳区","description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。","url": "http://blog.sina.com.cn/zaku","profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1","domain": "zaku","gender": "m","followers_count": 1204,...
}
},...
],"ad": [
{
"id": 3366614911586452,"mark": "AB21321XDFJJK"
},"previous_cursor": 0,// 暂时不支持
"next_cursor": 11488013766,// 暂时不支持
"total_number": 81655
}
以上是微博给出来的例子的一部分,我们来看看我们需要什么。我们需要一部分文字和一部分的图片。之后要显示的内容主要就是文字或者图片。 解析我们用 安装 pod 'ObjectMapper','~> 1.1'
最外面的一层是: {
"statuses": [ ... ],"previous_cursor": 0,"next_cursor": 11488013766,"total_number": 81655 }
所以对应的model定义是这样的: import ObjectMapper
class BaseModel: Mappable { // 1
var previousCursor: Int?
var nextCursor: Int?
//var statuses
var totalNumber: Int?
required init?(_ map: Map) { // 2
}
func mapping(map: Map) { // 3
previousCursor <- map["previous_cursor"]
nextCursor <- map["next_cursor"]
//hasVisible <- map["hasvisible"]
statuses <- map["..."] // 4
totalNumber <- map["total_number"]
}
}
最重要的是先 在深入一层上问的标签4的内容我们在这里详细介绍。我们要展示的内容都是在statuses下的。那么我们应该如何处理这部分的内容呢?statuses的json格式是这样的: {
"statuses": [ { "created_at": "Tue May 31 17:46:55 +0800 2011","id": 11488058246,"text": "求关注。", "source": "<a href="http://weibo.com" rel="nofollow">新浪微博</a>","favorited": false,"truncated": false,"in_reply_to_status_id": "","in_reply_to_user_id": "","in_reply_to_screen_name": "","geo": null,... } ],}
可以有两个方式来处理深层的json数据。一个是在 class BaseModel {
var text: String?
required init?(_ map: Map) {
}
func mapping(map: Map) {
self.text <- map["statuses.text"] } }
但是这样是错误的!因为statuses是一个数组,而不是一个对象。只有statuses对应的是一个对象的时候才适用于这个情况。 对上面的代码进行修改,让其适用于数据的情况。 class BaseModel {
var text: String?
required init?(_ map: Map) {
}
func mapping(map: Map) {
self.text <- map["status.0.text"] } }
那么就剩下最后的一种方法了。内层json的model类继承外层的json的model类。按照这个方法那么我们为statuses对应的json对象定义一个model类为 class StatusModel: BaseModel { // 1
var statusId: String?
var thumbnailPic: String?
var bmiddlePic: String?
var originalPic: String?
var weiboText: String?
var user: WBUserModel?
required init?(_ map: Map) {
super.init(map) // 2
}
override func mapping(map: Map) {
super.mapping(map) // 2
statusId <- map["id"] thumbnailPic <- map["thumbnail_pic"] bmiddlePic <- map["bmiddle_pic"] originalPic <- map["original_pic"] weiboText <- map["text"] } }
那么在最外层的 class BaseModel: Mappable {
var previousCursor: Int?
var nextCursor: Int?
var hasVisible: Bool?
var statuses: [StatusModel]? // 1
var totalNumber: Int?
required init?(_ map: Map) {
}
func mapping(map: Map) {
previousCursor <- map["previous_cursor"]
nextCursor <- map["next_cursor"]
hasVisible <- map["hasvisible"]
statuses <- map["statuses"] // 2
totalNumber <- map["total_number"]
}
}
这样 那么从http请求,到返回数据,到解析json串的一系列动作就可以完整的联结起来了。最开始介绍使用Alamofire请求并成功返回之后,我们只是把字符串打印了出来。现在可以调用map方法来匹配json串和我们定义好的model类了。 parameters = ["access_token": weiboUserInfo.accessToken ?? "","source": ConstantUtil.WEIBO_APPKEY]
Alamofire.request(.GET,"https://api.weibo.com/2/statuses/friends_timeline.json",headers: nil)
.responseString(completionHandler: {response in
print("response:- (response)")
let statuses = Mapper<BaseModel>().map(response.result.value) // 1
print("total number: (statuses!.totalNumber)")
if let timeLine = statuses where timeLine.totalNumber > 0 { // 2
self.timeLineStatus = timeLine.statuses
self.collectionView?.reloadData()
}
})
to be continued…(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |