Alamofire从基础到进阶 基础请求与响应(一)

Alamofire
Version:4.5.1
Swift Version: 4.0.3

Podfiles

# Uncomment the next line to define a global platform for your proje
platform :ios, '8.0'
target 'UseageAlamofire' do
  use_frameworks!
  pod 'Alamofire'
end

目录:
Alamofire从基础到进阶 基础请求与响应(一)
Alamofire从基础到进阶 小技巧(二)

创建一个简单的Request

let request = Alamofire.request("http://httpbin.org/ip")
print("request = \(request)")
输出:request = GET http://httpbin.org/ip

上面的 GET 是请求类型,后面紧跟的就是你的请求的地址,还有另外两种创建一个Request的方式:

  • request(_ urlRequest: )
  • request(_ url:, method:, parameters:, encoding:, headers: )
    我们使用一下看看效果:
let urlRequest = URLRequest(url: URL(string: "http://httpbin.org/ip")!)
let request2 = Alamofire.request(urlRequest)
print("request2 = \(request2)")
输出:request2 = GET http://httpbin.org/ip

let url = "http://httpbin.org/ip"
let method: HTTPMethod = .get
let parameters: Parameters = ["name": "chao"]
let encoding: URLEncoding = .default
let headers: HTTPHeaders = ["Content-Type": "application/json"]
let request3 = Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers)
print("request3 = \(request3)")
输出:request3 = GET http://httpbin.org/ip?name=chao

使用一下Response响应

我们已经学会了用Alamofire创建一个Request,我们最终想要的是从服务器拿到数据,我们可以这样写:

let url2 = "http://httpbin.org/ip"
Alamofire.request(url2).response(completionHandler: { defaultResponse in
    print("request = ", defaultResponse.request)
    print("-----------------------------------")
    print("response = ", defaultResponse.response)
    print("-----------------------------------")
    print("data = ", defaultResponse.data)
    print("-----------------------------------")
    print("error = ", defaultResponse.error)
    print("-----------------------------------")
    print("metrics = ", defaultResponse.metrics)
    print("-----------------------------------")
    print("timeline = ", defaultResponse.timeline)
})

输出:

response =  Optional(<NSHTTPURLResponse: 0x60000002ff00> { URL: http://httpbin.org/ip } { Status Code: 200, Headers {
    "Access-Control-Allow-Credentials" =     (
        true
    );
    "Access-Control-Allow-Origin" =     (
        "*"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        32
    );
    "Content-Type" =     (
        "application/json"
    );
    Date =     (
        "Fri, 30 Mar 2018 10:41:03 GMT"
    );
    Server =     (
        "meinheld/0.6.1"
    );
    Via =     (
        "1.1 vegur"
    );
    "X-Powered-By" =     (
        Flask
    );
    "X-Processed-Time" =     (
        0
    );
} })
-----------------------------------
data =  Optional(32 bytes)
-----------------------------------
error =  nil
-----------------------------------
metrics =  Optional((Task Interval) <_NSConcreteDateInterval: 0x600000030e40> (Start Date) 2018-03-30 10:41:03 +0000 + (Duration) 0.677700 seconds = (End Date) 2018-03-30 10:41:03 +0000
(Redirect Count) 0
(Transaction Metrics) (Request) <NSURLRequest: 0x600000012b60> { URL: http://httpbin.org/ip }
(Response) <NSHTTPURLResponse: 0x60000002f580> { URL: http://httpbin.org/ip } { Status Code: 200, Headers {
    "Access-Control-Allow-Credentials" =     (
        true
    );
    "Access-Control-Allow-Origin" =     (
        "*"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        32
    );
    "Content-Type" =     (
        "application/json"
    );
    Date =     (
        "Fri, 30 Mar 2018 10:32:49 GMT"
    );
    Server =     (
        "meinheld/0.6.1"
    );
    Via =     (
        "1.1 vegur"
    );
    "X-Powered-By" =     (
        Flask
    );
    "X-Processed-Time" =     (
        0
    );
} }
(Fetch Start) 2018-03-30 10:41:03 +0000
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
(Request Start) 2018-03-30 10:41:03 +0000
(Request End) 2018-03-30 10:41:03 +0000
(Response Start) 2018-03-30 10:41:03 +0000
(Response End) 2018-03-30 10:41:03 +0000
(Protocol Name) (null)
(Proxy Connection) NO
(Reused Connection) YES
(Fetch Type) Local Cache

(Request) <NSURLRequest: 0x600000012a10> { URL: http://httpbin.org/ip }
(Response) <NSHTTPURLResponse: 0x60000002fb60> { URL: http://httpbin.org/ip } { Status Code: 200, Headers {
    "Access-Control-Allow-Credentials" =     (
        true
    );
    "Access-Control-Allow-Origin" =     (
        "*"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        32
    );
    "Content-Type" =     (
        "application/json"
    );
    Date =     (
        "Fri, 30 Mar 2018 10:41:03 GMT"
    );
    Server =     (
        "meinheld/0.6.1"
    );
    Via =     (
        "1.1 vegur"
    );
    "X-Powered-By" =     (
        Flask
    );
    "X-Processed-Time" =     (
        0
    );
} }
(Fetch Start) 2018-03-30 10:41:03 +0000
(Domain Lookup Start) 2018-03-30 10:41:03 +0000
(Domain Lookup End) 2018-03-30 10:41:03 +0000
(Connect Start) 2018-03-30 10:41:03 +0000
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) 2018-03-30 10:41:03 +0000
(Request Start) 2018-03-30 10:41:03 +0000
(Request End) 2018-03-30 10:41:03 +0000
(Response Start) 2018-03-30 10:41:03 +0000
(Response End) 2018-03-30 10:41:03 +0000
(Protocol Name) http/1.1
(Proxy Connection) NO
(Reused Connection) NO
(Fetch Type) Network Load

)
-----------------------------------
timeline =  Timeline: { "Latency": 0.677 secs, "Request Duration": 0.678 secs, "Serialization Duration": 0.000 secs, "Total Duration": 0.678 secs }

上面输出了很多很多的东西,我们来具体看看都有什么?
DefaultDataResponse
这个响应结果是Alamofire提供的一个结构体,我们看一下源码:

/// The URL request sent to the server.
public let request: URLRequest?

/// The server's response to the URL request.
public let response: HTTPURLResponse?

/// The data returned by the server.
public let data: Data?

/// The error encountered while executing or validating the request.
public let error: Error?

/// The timeline of the complete lifecycle of the request.
public let timeline: Timeline

var _metrics: AnyObject?

DefaultDataResponse结构体定义了上面这几个属性:
reqeuest就是你定义的请求
reponse是响应结果
data是服务器返回给我们的数据
error是执行请求和验证结果时候的错误
timeline是该请求从请求到收到结果的一条时间线
_metrics是iOS10及以后提供的一个时间线的属性,和timeline大同小异,所以你要使用的话必须是支持iOS10以后的版本才能使用

/// 这样写就没有问题了
if #available(iOS 10, *) {
    print("metrics = ", defaultResponse.metrics)
}

不过除了response响应处理以外我们还有4种其他的响应处理方式:

  • responseJSON
  • reponseData
  • responseString
  • responsePropertyList

在我们的程序里,大多数用到的是第一和第二种。
responseString响应处理的是字符串
responsePropertyList响应处理的是plist(类似于responseJSON)都是转换成Any类型。
responseJSON是将服务器返回数据序列化为json然后转换成Any.
reponseData是将服务器返回数据序列化为Data然后转换成Data.

Alamofire强烈建议我们使用这四种去做处理,不建议我们使用DefaultResponse,这个就不纠结了我们用下面四种已经足够了。

先看responseData:

Alamofire.request(url2).responseData(completionHandler: { response in
    print(response.result.value)
})
输出:Optional(32 bytes)

我们看到了reponse.result,这个result是啥?我们点进去看看

enum Result<Value> {
    case success(Value)
    case failure(Error)

    public var value: Value? {
        switch self {
        case .success(let value):
            return value
        case .failure:
            return nil
        }
    }
}
/// 源码我没有展示完 我们只看关于这篇文章的

Reust是一个泛型的枚举,当我们使用responseData的使用,Value就会被转换为Data,当我们调用response.result.vlaue的时候就会看到输出了"Optional(32 bytes)"这很明显是Data类型,然后我们把它解析出来看看是什么:

let url2 = "http://httpbin.org/ip"
Alamofire.request(url2).responseData(completionHandler: { response in
    guard let value = response.result.value else { return }
    let result = try? JSONSerialization.jsonObject(with: value, options: [])
    guard let res = result else { return }
    let dictionary = res as! [String: Any]
    print("dictionary = ", dictionary)
})
输出:dictionary =  ["origin": 101.81.57.239]

这就是responseData的简单用法了.
下面我们来看responseJSON怎么使用:

Alamofire.request(url2).responseJSON { response in
     print(response.result.value)
}
输出: Optional({ origin = "101.81.57.239";})

很明显它是一个JSON格式,这就是Alamofire序列化为JSON的好处。为什么我们使用Reulst,因为它是Alamofire序列化好服务器给我们使用的一个属性,所以我们不用再去做序列化的操作,直接使用就好了。下面我们转化成字典类型:

Alamofire.request(url2).responseJSON { response in
    guard let value = response.result.value else { return }
    let dictionary = value as! [String: Any]
    print("dictionary = ", dictionary)
}
输出:dictionary =  ["origin": 101.81.57.239]

和responseData是一样的输出结果,但是比responseData要少两步, 所以如果你的程序后台返回的是JSON格式的数据,你直接使用responseJSON要比responseData要方便很多。

--以此来记录 Usage Alamofire ^ _^ --

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容