Alamofire 入门教程(下)
2016-07-19 10:48
316 查看
上篇地址
获取数据
在 ViewController 的 extension 里面,uploadImage(_:progress:completion:)的下面添加如下的代码:
func downloadTags(contentID: String, completion: ([String]) -> Void) { Alamofire.request( .GET, "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: AnyObject] else { print("Invalid tag information received from service") completion([String]()) return } print(responseJSON) completion([String]()) } }
同样把
Basic xxx替换为你自己的 token,设置好 URL 以及对应的参数。
下一步,返回
uploadImage(_:progress:completion:)替换
completion中的代码:
self.downloadTags(firstFileID) { tags in completion(tags: tags, colors: [PhotoColor]()) }
编译运行你的工程,上传一个文件,之后你在控制台就会看见返回的数据:
你不用关心
confidence的分数,在本次教程中我们只使用
tag的名称。
下一步,返回
downloadTags(_: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: AnyObject], results = responseJSON["results"] as? [AnyObject], firstResult = results.first, tagsAndConfidences = firstResult["tags"] as? [[String: AnyObject]] 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)
下面是每步的代码:
1. 检查响应是否成功;如果不成功,输出错误信息并调用 completion
2. 对返回 json 数据进行解析。
3. 迭代
tagsAndConfidences数组,检索
tag.
4. 调用
completion。
注意:
你使用 Swift 的
flatMap方法来进行迭代,这个方法在遇到值为
nil的情况不会崩溃,并且会从返回结果中移除为
nil的值。这可以让你使用条件解包(
as?)来验证字典的值是否可以转换为一个字符串。
再一次编译运行你的工程,选择一涨图片,然后你会看到下面的界面:
在 ViewController extension
downloadTags(_:completion:)下面添加如下代码:
func downloadColors(contentID: String, completion: ([PhotoColor]) -> Void) { Alamofire.request( .GET, "http://api.imagga.com/v1/colors", parameters: ["content": contentID, "extract_object_colors": NSNumber(int: 0)], // 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: AnyObject], results = responseJSON["results"] as? [AnyObject], firstResult = results.first as? [String: AnyObject], info = firstResult["info"] as? [String: AnyObject], imageColors = info["image_colors"] as? [[String: AnyObject]] 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, g = dict["g"] as? String, b = dict["b"] as? String, 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) } }
最后,返回
uploadImage(_:progress:completion:)方法,在
completion里面的
success的情况,添加下面的代码:
self.downloadTags(firstFileID) { tags in self.downloadColors(firstFileID) { colors in completion(tags: tags, colors: colors) } }
再一次编译运行你的工程,选择一涨图片,然后你会看到下面的界面:
优化 PhotoTagger
你可能已经注意到了,在PhotoTagger里面有重复代码。
Alamofire 提供了一个简单的方法来排除重复的代码并且提供集中配置。这就需要创建一个结构体,遵循
URLRequestConvertible协议,并且更新你的上传和请求调用。
创建一个 Swift 文件,点击
File\New\File…,然后在 iOS 下面选择 Swift 文件,点击下一步,文件命名为 ImaggaRouter.swift,然后点击创建。
在你新建的文件中添加下面的代码:
import Foundation import Alamofire public enum ImaggaRouter: URLRequestConvertible { static let baseURLPath = "http://api.imagga.com/v1" static let authenticationToken = "Basic xxx" case Content case Tags(String) case Colors(String) public var URLRequest: NSMutableURLRequest { let result: (path: String, method: Alamofire.Method, parameters: [String: AnyObject]) = { switch self { case .Content: return ("/content", .POST, [String: AnyObject]()) case .Tags(let contentID): let params = [ "content" : contentID ] return ("/tagging", .GET, params) case .Colors(let contentID): let params = [ "content" : contentID, "extract_object_colors" : NSNumber(int: 0) ] return ("/colors", .GET, params) } }() let URL = NSURL(string: ImaggaRouter.baseURLPath)! let URLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(result.path)) URLRequest.HTTPMethod = result.method.rawValue URLRequest.setValue(ImaggaRouter.authenticationToken, forHTTPHeaderField: "Authorization") URLRequest.timeoutInterval = NSTimeInterval(10 * 1000) let encoding = Alamofire.ParameterEncoding.URL return encoding.encode(URLRequest, parameters: result.parameters).0 } }
把
Basic xxx替换为你自己的 token,设置好 URL 以及对应的参数。这个
router会帮助我们创建
NSMutableURLRequest实例,并且提公布了三种情况:
.Content,
.Tags(String), 或
.Colors(String)。现在所有的模板代码都在这里,如果你需要更新它的话。返回
uploadImage(_:progress:completion:)方法,并且把
Alamofire.upload替换成下面的代码:
Alamofire.upload( ImaggaRouter.Content, multipartFormData: { multipartFormData in multipartFormData.appendBodyPart(data: imageData, name: "imagefile", fileName: "image.jpg", mimeType: "image/jpeg") }, /// original code continues...
然后替换
downloadTags(_:completion:)方法里的
Alamofire.request:
Alamofire.request(ImaggaRouter.Tags(contentID))
最后,更新
downloadColors(_:completion:) with代码里的
Alamofire.request:
Alamofire.request(ImaggaRouter.Colors(contentID))
最后一次编译运行,所有的功能都像之前一样,也就意味着没有破坏你的 app,进行了代码重构。不错的工作!
最终工程代码
下载地址
不要忘记替换你自己的 token。你也可以去 github 下载 Alamofire
原帖地址
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- Apple Swift学习教程
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 介绍 Fedora 上的 Swift
- php修改上传图片尺寸的方法
- 为ckeditor编辑器加上传图片的功能
- 上传图片时JS自动显示图片
- TinyMCE汉化及本地上传图片功能实例详解
- 基于Jquery插件Uploadify实现实时显示进度条上传图片
- ASP.NET实现上传图片并生成缩略图的方法
- Android获取SD卡中选中图片的路径(URL)示例
- ASP.Net 上传图片并生成高清晰缩略图
- FileUpload上传图片(图片不变形)
- 简单PHP上传图片、删除图片实现代码