1. 程式人生 > >swift Alamofire+ObjectMapper——swift(學習九)

swift Alamofire+ObjectMapper——swift(學習九)

Alamofire

Alamofire是目前為止我接觸的swift最好的第三方下載庫,它根本就不需要另外封裝,所有的下載方法都是class func。同時呢,它提供了很多種回撥的方法:

//最簡單下載
Alamofire.request(.GET, "https://httpbin.org/get")
//帶引數
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"]).response { (request, response, data, error) in})
//URL轉碼
Alamofire.request
(Method.GET, "https://httpbin.org/get", parameters: nil, encoding: ParameterEncoding.URL,headers: nil).responseString { (response) in })

另外它的返回值有很多種,比如response、responseJSON、responseString等閉包。我自己最喜歡用的就是responseString。這裡呢,也普及一下responseString返回物件都有哪些屬性:

//response閉包,它包含返回的result與是否正確的bool狀態
 print("response:- \(response)"
) //請求相關的東西,打印出一個可選型的URL print("request:-\(response.request)") //包含有可選型的URL、狀態、請求頭;請求頭裡有日期大小等 print("response:-\(response.response)") //打印出的二進位制 print("data:-\(response.data)") //列印時間相關 print("time:-\(response.timeline.totalDuration)")

所以我們最終需要的就只是result.value。
而有時候我們是需要返回進度的東西,有一點需要注意的是進度閉包不是在主執行緒的,所以要使用進度的時候要把它放到主執行緒裡。

public func progress(closure: ((Int64, Int64, Int64) -> Void)? = nil) -> Self {}

下載還有一個經常用到的就是時間控制了,這個東西很坑的一點就是網上很多加時間限制的方法是錯誤的。因為時間限制是加在URLSession上的confige上的。

把以上幾點綜合一下,我封裝了一個下載的函式:

/**下載
     *  host:是所有下載地址前面共有的域名地址,path:是請求地址,如果沒有host,則只需要穿入path就可以
     *  timeout:請求限制時長
     *  params:請求要帶的引數,這個可以用字典傳進來,也可以手動新增在path上,用&連線
     *  completeHandle:回撥閉包,返回的是一個JSONString
     *  progressHandle:進度閉包,返回一個實時進度,這個要在主執行緒使用進度
     */
    class func handleRequest(host:String?=nil,path:String?=nil,timeout:NSTimeInterval? = 5,params:[String: AnyObject]? = nil,completeHandle:(JSONString: String?)->Void,progressHandle:((progress:NSInteger)->Void)?=nil,cache:Bool) {

        if (host == nil)&&(path==nil) {
            return
        }

        var url:String?

        if host != nil {
            url = String.init(format:"%@?%@",host!,path!)
        }else{
            url = String.init(format:"%@",path!)
        }

        let manager = Alamofire.Manager.sharedInstance
        manager.session.configuration.timeoutIntervalForRequest = timeout!
        manager.session.configuration.timeoutIntervalForResource = timeout!

        manager.request(.GET, url!, parameters: params, encoding: ParameterEncoding.URL)
            .progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
                dispatch_async(dispatch_get_main_queue()) {
                    print("Total bytes read on main queue: \(totalBytesRead)")
                    print("Progress on main queue: \(Float(totalBytesRead) / Float(totalBytesExpectedToRead))")
                }
            }.responseString { (response) in
                /*這裡的response返回的不單單是
                 */
                print("response:- \(response)")
                print("request:-\(response.request)")
                print("response:-\(response.response)")
                print("data:-\(response.data)")
                print("time:-\(response.timeline.totalDuration)")
                switch response.result{
                    case .Success:
                        completeHandle(JSONString: response.result.value)
                    case .Failure(let error):
                        print(error)
                        let controller = UIAlertController.init(title: "request faile", message: nil, preferredStyle: UIAlertControllerStyle.Alert)
                        controller.addAction(UIAlertAction.init(title: "sure", style: UIAlertActionStyle.Cancel, handler: { (action) in

                        }))
                        UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(controller, animated: true, completion:nil)
                }
            }
    }

ObjectMapper

聊完下載,聊解析,也是我認為最簡單易用的解析庫了,使用起來很簡單:

//
//  TodayNewModel.swift
//  FCFTemplete
//
//  Created by 馮才凡 on 16/6/17.
//  Copyright © 2016年 fcf. All rights reserved.
//

/*
 response:- SUCCESS: {
 "status": 1,
 "msg": "獲取資料成功",
 "data": {
 "count": 4915,
 "results": [
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-16",
 "newsId": "e4933aae499aa472deca09b20d39addd",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/b383a34a9861a976aed20ed9311accc0.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16732",
 "newsNum": 0,
 "newsSource": "伯樂線上",
 "newsTitle": "史上比較用心的純程式碼實現 AutoLayout",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "7f221c0246",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-16",
 "newsId": "0bca3c1214c24ff16e954f4eeb8ef2c5",
 "newsImage": "http://cc.cocimg.com/api/uploads/160615/de1c4afd4212a4676d277ca2a36026e8.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16718",
 "newsNum": 0,
 "newsSource": "天狐部落格 投稿",
 "newsTitle": "盤點:Xcode 8新特性",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "61fe963f6c",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-16",
 "newsId": "1b0068df2cd12aca06a56b76442105da",
 "newsImage": "http://cc.cocimg.com/api/uploads/160615/eba436de53154c3401a9e95dd9558353.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16719",
 "newsNum": 0,
 "newsSource": "yohunl 投稿",
 "newsTitle": "iOS日誌獲取和實時瀏覽器顯示日誌",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "88c4cae808",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-16",
 "newsId": "60ac53300b27af1cca2637dc4bceef8c",
 "newsImage": "http://cc.cocimg.com/api/uploads/160612/03c5cdc13d6e6454a75b01088250c122.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16660",
 "newsNum": 0,
 "newsSource": "西木柚子的簡書",
 "newsTitle": "UIWebView儲存圖片",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "da47d66725",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:02",
 "newsCreateTime": "2016-06-16",
 "newsId": "f820a89094f98a8cbc72f035dbad8eb4",
 "newsImage": "http://cc.cocimg.com/api/uploads/160615/1d0a09a33dfc82a447d65ea46ea83e7a.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16708",
 "newsNum": 0,
 "newsSource": "antscript 投稿",
 "newsTitle": "ASHUD——用Swift寫的HUD庫(OS X)",
 "newsType": "swift",
 "newsTypeName": "Swift",
 "objectId": "1cab10f595",
 "updatedAt": "2016-06-16 14:00:02"
 },
 {
 "createdAt": "2016-06-16 14:00:03",
 "newsCreateTime": "2016-06-16",
 "newsId": "68f829c79226b87a763d3e125a93df0c",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/d3ace468a57c259ff98d18c11f852b34.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16726",
 "newsNum": 0,
 "newsSource": "ASO100情報中心",
 "newsTitle": "開發者後臺重大更新——展示量將成為衡量 ASO 重要標準",
 "newsType": "appstore",
 "newsTypeName": "App Store研究",
 "objectId": "867424f8df",
 "updatedAt": "2016-06-16 14:00:03"
 },
 {
 "createdAt": "2016-06-16 14:00:04",
 "newsCreateTime": "2016-06-16",
 "newsId": "371869ab00ecb682d432a34beef31cd7",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/0f8888e95688591c9362a484a1c5e824.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16725",
 "newsNum": 0,
 "newsSource": "資訊與互動設計",
 "newsTitle": "如何做好陌生領域產品的互動設計",
 "newsType": "design",
 "newsTypeName": "產品設計",
 "objectId": "a8c4097b44",
 "updatedAt": "2016-06-16 14:00:04"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "b23517b5cb2b7c92f1788304e07464c5",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/151e68ed5a2a3735321231ae602f5aed.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16731",
 "newsNum": 0,
 "newsSource": "IT之家",
 "newsTitle": "iOS 10開發者預覽版新特性:手遊也要玩直播?",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "7ac8b9671e",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "78a1697515d0dffa7dd1fedd6df19e0e",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/c4e5386f1f76c0f59e806a57e5f48450.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16730",
 "newsNum": 0,
 "newsSource": "中關村線上",
 "newsTitle": "蘋果官方迴應系統應用“隱藏式”解除安裝",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "9fa041383f",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "96abf9746109d279d49ddddc16f561f0",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/7ab5ce4915b918d551be2642a31f36bc.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16729",
 "newsNum": 0,
 "newsSource": "IT之家",
 "newsTitle": "蘋果iOS10彈窗提醒使用者更新非64位應用:拖慢系統性能",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "88fdccb8aa",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "e94c2fa2f95a2497d4dca50930340843",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/a7a04578a6486e70f7847ea9083bd814.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16728",
 "newsNum": 0,
 "newsSource": "中關村線上",
 "newsTitle": "傳iPhone 7取消雙攝像頭:因技術不成熟",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "3b1afb96a5",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "8a8e2a3c8d31d066270c788d0333d2c4",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/b947fed1b16f91e423132ce25bea6091.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16727",
 "newsNum": 0,
 "newsSource": "中關村線上",
 "newsTitle": "目標年底 蘋果正為Apple Watch 2採購元件",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "fc810e0e5e",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "facdbebd932b2eb60a88c7f54bd6b150",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/9512490536c8bf15224627821d9014a3.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16723",
 "newsNum": 0,
 "newsSource": "SwiftCafe",
 "newsTitle": "沒有硬體釋出的 WWDC 2016—macOS篇",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "fa0004a1c3",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "49ba128182ed0821d19bf249ee87e3a0",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/985c61b2efcd754c9d950313078912e8.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16722",
 "newsNum": 0,
 "newsSource": "少數派",
 "newsTitle": "想嚐鮮?談談 iOS 10 開發者預覽版體驗感受",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "688d154eb2",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:06",
 "newsCreateTime": "2016-06-16",
 "newsId": "aff01d5fb56c3a0f3b722599f9f144a1",
 "newsImage": "http://cc.cocimg.com/api/uploads/160616/9701035f5f1ff2e0e28c3585b0d58ad3.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16721",
 "newsNum": 0,
 "newsSource": "愛範兒",
 "newsTitle": "10 個重磅更新之外,iOS 10 還向這個設計趨勢靠攏",
 "newsType": "apple",
 "newsTypeName": "蘋果相關",
 "objectId": "bad7257619",
 "updatedAt": "2016-06-16 14:00:06"
 },
 {
 "createdAt": "2016-06-16 14:00:09",
 "newsCreateTime": "2016-06-16",
 "newsId": "6171059e63356d6c7fc4991f5a660ff2",
 "newsImage": "http://cc.cocimg.com/api/uploads/160615/85e61609b1e0a1a646d7da0b5abd6839.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16720",
 "newsNum": 0,
 "newsSource": "東京IT人",
 "newsTitle": "假如程式設計師生活在童話裡……",
 "newsType": "programmer",
 "newsTypeName": "程式人生",
 "objectId": "f3ed350d5c",
 "updatedAt": "2016-06-16 14:00:09"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-15",
 "newsId": "4103e8b24c743c7d0ae55f290537eda6",
 "newsImage": "http://cc.cocimg.com/api/uploads/160614/0327d8b3d630232d7e05893764f4decd.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16704",
 "newsNum": 0,
 "newsSource": "MrPeak技術分享",
 "newsTitle": "一款快速生成程式碼的Xcode外掛FastStub",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "4f95a60dd0",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-15",
 "newsId": "830e07d1817367e098241c1269811d0d",
 "newsImage": "http://cc.cocimg.com/api/uploads/160614/a01739b78ef2642bff8ee6ce0bdc33e1.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16652",
 "newsNum": 0,
 "newsSource": "Bison 投稿",
 "newsTitle": "分分鐘解決iOS開發中App啟動廣告的功能",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "2064c463a3",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-15",
 "newsId": "b0d0ad4aafb33933fcf31b01464ab84a",
 "newsImage": "http://cc.cocimg.com/api/uploads/160614/cfddce2b3de30f0d2c55d29c0cd26c95.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16703",
 "newsNum": 0,
 "newsSource": "SwiftCafe",
 "newsTitle": "快速上手 Core Spotlight",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "5f956e57b8",
 "updatedAt": "2016-06-16 14:00:01"
 },
 {
 "createdAt": "2016-06-16 14:00:01",
 "newsCreateTime": "2016-06-15",
 "newsId": "ad99486dcf16ae6f6a6e17755f620304",
 "newsImage": "http://cc.cocimg.com/api/uploads/160614/1b1ca129ad219ea729eb75d1f9be6a8d.jpg",
 "newsLink": "http://www.cocoachina.com/cms/wap.php?action=article&id=16674",
 "newsNum": 0,
 "newsSource": "漢斯哈哈哈的簡書",
 "newsTitle": "YYCache原始碼分析(二)",
 "newsType": "ios",
 "newsTypeName": "iOS開發",
 "objectId": "f2b2618d16",
 "updatedAt": "2016-06-16 14:00:01"
 }
 ]
 }
 }

 */

import UIKit
import ObjectMapper

class resultObj: Mappable {
    var createdAt:String?
    var newsCreateTime:String?
    var newsId:String?
    var newsImage:String?
    var newsLink:String?
    var newsNum:NSNumber?
    var newsSource:String?
    var newsTitle:String?
    var newsType:String?
    var newsTypeName:String?
    var objectId:String?
    var updatedAt:String?
    required init?(_ map: Map) {
    }
    func mapping(map: Map) {
        createdAt <- map["createdAt"]
        newsCreateTime <- map["newsCreateTime"]
        newsId <- map["newsId"]
        newsImage <- map["newsImage"]
        newsLink <- map["newsLink"]
        newsNum <- map["newsNum"]
        newsSource <- map["newsSource"]
        newsTitle <- map["newsTitle"]
        newsType <- map["newsType"]
        newsTypeName <- map["newsTypeName"]
        objectId <- map["objectId"]
        updatedAt <- map["updatedAt"]
    }
}

class dataObj: Mappable {
    var count:NSNumber?
    var results:[resultObj]?
    required init?(_ map: Map) {
    }
    func mapping(map: Map) {
        count <- map["count"]
        results <- map["results"]
    }
}

class TodayNewModel: Mappable {
    var status:Int?
    var msg:String?
    var data:dataObj?
    init(){}
    required init?(_ map: Map) {
    }

    func mapping(map: Map) {
        status <- map["status"]
        msg <- map["msg"]
        data <- map["data"]
    }
}
//這裡需要提示一下的是:很多網上教程說要在func mapping(map: Map)函式里加一個mapping(map),不知道是不是我理解錯的原因,但是就我這裡的解析來說,在裡面加mapping(map)是錯誤的做法,會無限遞迴下去的。

OK,model裡大概就是這樣了。那下載好了的時候,我們只需要把它們結合起來使用就可以了:

FCFBaseViewModel.handleRequest(nil, path: "http://cloud.bmob.cn/f8bb56aa119e68ee/news_list_2_0", timeout:10, params: (["limit":20,"skip":0]), completeHandle: { (returnValue) in
        print("************************************")
        print(returnValue)
        let result = Mapper<TodayNewModel>().map(returnValue)
        if let obj = result {
            let res = (obj.data?.results![0])! as resultObj
            print(res.newsTitle!)
        }
        }, progressHandle: nil, cache: false)