Alamofire的使用教程

来源:互联网 发布:淘宝冷门类目有哪些 编辑:程序博客网 时间:2024/05/18 01:39

环境:Alamofire 4, Xcode 8.2, iOS 10, and Swift 3.
Alamofire是一个基于HTTP的网络请求库,适用于iOS和OSX,针对apple的基本网络请求库作了封装,简化网络请求的复杂逻辑。
Alamofire提供了request/response方法,JSON参数形式,序列化功能,以及authentication等许多特性。在本篇文章中,你可以学到通过Alamofire实现基本的数据上传和下载。
首先,下载基本的空项目:https://koenig-media.raywenderlich.com/uploads/2016/12/PhotoTagger-starter-1.zip
这个项目名称叫做PhotoTagger,当你完成了这个项目,会实现以下的效果:当你从照片库选择一张照片,并且上传到我们指定的第三方服务器,就可以实现照片的智能识别,包含照片所包含的标签,和图片的合成颜色:
这里写图片描述
下载完项目,build运行后你可以看到下面的效果。
这里写图片描述
点击select Photo按钮,当前view的背景会换成你选择的图片的样子

Imagga 的API

Imagga是一个图片识别平台,为开发者免费提供了图片的上传获取API,有兴趣可以看看Imagga平台的这个小项目。https://imagga.com/auto-tagging-demo?url=https://imagga.com/static/images/tagging/vegetables.jpg
如果想使用Imagga,首页需要注册成为其平台的开发者,填下一下的表格即可https://imagga.com/auth/signup/hacker
当填完后这个表格后,点击确定进入主页面,能看到这个页面
这里写图片描述
注意Authorization 这个部分,在以后的网络请求中会有用到。
这里是imagga的文档详细使用说明,需要的可以看看。http://docs.imagga.com/

安装 Dependencies

创建cocoaPod环境,创建Podfile文件,如下

platform :ios, '10.0'inhibit_all_warnings!use_frameworks!target 'PhotoTagger' do  pod 'Alamofire', '~> 4.2.0'end

然后在终端执行以下指令:

pod install

如果你的电脑上没有安装cocoaPods环境,查看这篇文章http://www.raywenderlich.com/97014/use-cocoapods-with-swift
关闭当前的项目,并且打开项目PhotoTagger.xcworkspace. 运行后发现还开始的页面都一样,没有变化,下面开始正式进入网络请求的介绍部分。

开始一个Alamofire请求

分为三个部分,
upload:上传multipart files和stream,file 或data
download:下载files或者重新开始一个已经开始的网络请求
,request:每一个不含文件上传和下载的Http请求。

上传 Files

打开ViewController.swift 并且引进头文件

import Alamofire

这样就可以使用Alamofire提供的function了
接着:添加一个extension到文件的最后面

// Networking callsextension ViewController {  func upload(image: UIImage,              progressCompletion: @escaping (_ percent: Float) -> Void,              completion: @escaping (_ tags: [String], _ colors: [PhotoColor]) -> Void) {    guard let imageData = UIImageJPEGRepresentation(image, 0.5) else {      print("Could not get JPEG representation of UIImage")      return    }  }}

这一步上传我们本地的图片到imagga的服务器,同时会返回给我们一个图片。

然后,在imagePickerController(_:didFinishPickingMediaWithInfo:)方法中的给imageView赋值image时添加以下代码:

// 1takePictureButton.isHidden = trueprogressView.progress = 0.0progressView.isHidden = falseactivityIndicatorView.startAnimating()upload(  image: image,  progressCompletion: { [unowned self] percent in    // 2    self.progressView.setProgress(percent, animated: true)  },  completion: { [unowned self] tags, colors in    // 3    self.takePictureButton.isHidden = false    self.progressView.isHidden = true    self.activityIndicatorView.stopAnimating()    self.tags = tags    self.colors = colors    // 4    self.performSegue(withIdentifier: "ShowResults", sender: self)  })

所有的alamofire的请求都是异步的,这样就意味着UI的刷新也是异步的,下面介绍每一步的含义:
1. 隐藏上传按钮,并且展示上传的进度和activity view
2. 上传文件的时候通过progress handler 来更新上传进度条:
3.当上传完成之后,通过completion handler来更新UI
4.当上传完成之后,通过storyBoard来实现跳转。
然后 在upload(image:progressCompletion:completion:) 的image转化之后添加以下代码:

Alamofire.upload(  multipartFormData: { multipartFormData in    multipartFormData.append(imageData,                             withName: "imagefile",                             fileName: "image.jpg",                             mimeType: "image/jpeg")  },  to: "http://api.imagga.com/v1/content",  headers: ["Authorization": "Basic xxx"],  encodingCompletion: { encodingResult in  })

记着更换Basic xxx 成你自己的。
然后,在encodingCompletion的闭包里面添加以下代码:

switch encodingResult {case .success(let upload, _, _):  upload.uploadProgress { progress in    progressCompletion(Float(progress.fractionCompleted))  }  upload.validate()  upload.responseJSON { response in  }case .failure(let encodingError):  print(encodingError)}

然后。在upload.responseJSON:添加以下代码

// 1.guard response.result.isSuccess else {  print("Error while uploading file: \(response.result.error)")  completion([String](), [PhotoColor]())  return}// 2.guard let responseJSON = response.result.value as? [String: Any],  let uploadedFiles = responseJSON["uploaded"] as? [[String: Any]],  let firstFile = uploadedFiles.first,  let firstFileID = firstFile["id"] as? String else {    print("Invalid information received from service")    completion([String](), [PhotoColor]())    return}print("Content uploaded with ID: \(firstFileID)")// 3.completion([String](), [PhotoColor]())

这里分步介绍每一步的含义:
1. 查看请求是否成功,如果失败,打印失败信息,并且调用completion handler。
2. 分离每一部分的数据,并查看返回的状态是否有效,如果有错误,打印失败信息,并且调用completion handler。
3. 更新UI
运行项目,选择一张图片上传,可以在打印台看到以下信息:
图片
这个时候,已经完成了基本的数据上传

数据下载

接下来就是讲刚刚上传照片的分析数据下载下来。
在ViewController的upload(image:progress:completion:):中添加以下代码

func downloadTags(contentID: String, completion: @escaping ([String]) -> Void) {  Alamofire.request(    "http://api.imagga.com/v1/tagging",    parameters: ["content": contentID],    headers: ["Authorization": "Basic xxx"]  )  .responseJSON { response in    guard response.result.isSuccess else {      print("Error while fetching tags: \(response.result.error)")      completion([String]())      return    }    guard let responseJSON = response.result.value as? [String: Any] else {      print("Invalid tag information received from the service")      completion([String]())      return    }    print(responseJSON)    completion([String]())  }}

然后upload(image:progress:completion:) 替换completion handler为以下代码

self.downloadTags(contentID: firstFileID) { tags in  completion(tags, [PhotoColor]())}

运行项目,上传你的文件并且查看控制台信息。如下图:
这里写图片描述
然后返回downloadTags(contentID:completion:) 并且替换.responseJSON
下的代码为以下代码

// 1.guard response.result.isSuccess else {  print("Error while fetching tags: \(response.result.error)")  completion([String]())  return}// 2.guard let responseJSON = response.result.value as? [String: Any],  let results = responseJSON["results"] as? [[String: Any]],  let firstObject = results.first,  let tagsAndConfidences = firstObject["tags"] as? [[String: Any]] else {    print("Invalid tag information received from the service")    completion([String]())    return}// 3.let tags = tagsAndConfidences.flatMap({ dict in  return dict["tag"] as? String})// 4.completion(tags)

运行项目,上传一张图片就可以看到以下效果:
这里写图片描述
下面开始获取图片的colors的接口,同样的:
在ViewController的downloadTags(contentID:completion:):下面添加以下代码

func downloadColors(contentID: String, completion: @escaping ([PhotoColor]) -> Void) {  Alamofire.request(    "http://api.imagga.com/v1/colors",    parameters: ["content": contentID],    // 1.    headers: ["Authorization": "Basic xxx"]  )  .responseJSON { response in    // 2.    guard response.result.isSuccess else {      print("Error while fetching colors: \(response.result.error)")      completion([PhotoColor]())      return    }    // 3.    guard let responseJSON = response.result.value as? [String: Any],      let results = responseJSON["results"] as? [[String: Any]],      let firstResult = results.first,      let info = firstResult["info"] as? [String: Any],      let imageColors = info["image_colors"] as? [[String: Any]] else {        print("Invalid color information received from service")        completion([PhotoColor]())        return    }    // 4.    let photoColors = imageColors.flatMap({ (dict) -> PhotoColor? in      guard let r = dict["r"] as? String,        let g = dict["g"] as? String,        let b = dict["b"] as? String,        let closestPaletteColor = dict["closest_palette_color"] as? String else {          return nil      }      return PhotoColor(red: Int(r),                        green: Int(g),                        blue: Int(b),                        colorName: closestPaletteColor)    })    // 5.    completion(photoColors)  }}

最后在upload(image:progress:completion:)的completion handler下面添加以下代码:

self.downloadTags(contentID: firstFileID) { tags in  self.downloadColors(contentID: firstFileID) { colors in    completion(tags, colors)  }}

运行项目,并且点击colors 按钮可以看到以下效果。
这里写图片描述

项目地址:https://github.com/LINDreaming/DailyTools
原文地址:https://www.raywenderlich.com/147086/alamofire-tutorial-getting-started-2