第二天(快速原型跑通流程)
前面把框架搭好了,我个人喜欢的开发方式是快速原型先做 MVP(最小可行性产品), 然后基于 MVP 迭代新功能,而我想做的东西的 MVP 就是能上传图片。
调研如何使用七牛
七牛推荐的模型
参考文档:七牛安全机制
重要的概念:
- 密钥(AccessKey/SecretKey),作用:生成上传凭证。
- 上传凭证(UploadToken),作用:上传文件时用作七牛服务器认证。
七牛上传的流程:
- 使用密钥构造上传凭证。
- 使用七牛 SDK 将上传凭证和文件一并提交实现上传。
七牛推荐的方式是客户端在上传时先请求服务端生成上传策略,客户端获取到上传策略后才能上传文件。
这个应用只有客户端,上传凭证只能在客户端构造,构造的算法参考:上传凭证
经过分析,我需要如下 Swift 库:
使用 CocoaPods 安装 Swift 库
我写应用的时候刚好赶上 Swift3 发布,Swift3 有了自己的包管理器 Swift Package Manager(SPM),因为是刚刚发布,可能很多库上面都还没有, 保险起见我还是使用 CocoaPods 来管理 Swift 的库。
我使用 RVM 管理 Ruby 环境,按照 官方安装文档 安装 CocoaPods 很顺利,执行 pod repo update
同步的时候巨慢,原因大家都懂,
网上有加速的办法,大家自行寻找适合自己的吧,我自己使用的是 ShadowSocks + proxychains4,我的同步方法 proxychains4 pod repo update
。
CocoaPods 使用
在项目根目录建一个 Podfile
文件
iDragProject ├── Podfile # 创建的文件 ├── iDragProject └── iDragProject.xcodeproj 3 directories, 1 file
里面写入要安装的库
# Uncomment this line to define a global platform for your project platform :osx, '10.11' target 'iDrag' do # Comment this line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for iDrag pod "Qiniu", "~> 7.1" pod "CryptoSwift" pod "SwiftyJSON" end # 由于我使用swift3,需要配置一下编译设置 post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '3.0' end end end
Podfile 配置完后,使用 pod install
命令即可安装。
安装完成后,项目里面会多出 3 个文件, Podfile.lock
、 Pods
和 iDrag.xcworkspace
,使用 Xcode 打开项目的时候选择 iDrag.xcworkspace
而不是原来的 iDrag.xcodeproj
。
打开后运行测试一下
如何添加新的 Swift 库
在 Podfile 里添加上新的库配置,然后执行 pod update
命令即可更新。
库准备好了,可以开始写代码了,先从构造上传凭证开始。
构造上传凭证
目前对七牛 SDK 的操作有构造上传凭证和上传文件,以后还有其他上传操作,我决定把这些操作统一放到名字为 DragUploadManager
的类里。
新建一个 Controllers.swift
的文件,里面放上传相关操作的代码。
实现代码:
func createQiniuToken(filename: String) -> String { let accessKey = "your access key" let secretKey = "your secret key" let bucket = "your bucket" // 上传凭证需要的 deadline 参数,Google 搜到的 Swift 转时间戳的方法,两个小时 let deadline = round(NSDate(timeIntervalSinceNow: 3600).timeIntervalSince1970) // 上传凭证构造第一步,准备 Json 格式数据,使用 SwiftJSON 库来构造 let putPolicyDict:JSON = [ "scope": "\(bucket):\(filename)", "deadline": deadline, ] // 上传凭证构造第二步,用 Base64 编码数据 let b64PutPolicy = QNUrlSafeBase64.encode(putPolicyDict.rawString()!)! // 上传凭证第三步,用 secretKey 将上面 Base64 编码后的数据使用 HMAC sha1 算法加密 // 转成二进制格式 let secretSign = try! HMAC(key: (secretKey.utf8.map({$0})), variant: .sha1).authenticate((b64PutPolicy.utf8.map({$0}))) // 上传凭证第四步,将加密后的数据在用 Base64 编码 let b64SecretSign = QNUrlSafeBase64.encode(Data(bytes: secretSign))! // 最后,按照七牛的格式构造成上传凭证 let putPolicy:String = [accessKey, b64SecretSign, b64PutPolicy].joined(separator: ":") return putPolicy }
运行看看效果
实现上传
上传凭证构造好之后,可以开始测试上传文件功能了,查看了七牛 SDK 的 API,可以使用 putFile
函数来做测试。
DragUploadManger
添加 uploadFile
函数
func uploadFile(filePath: String) { // 获取文件路径中的文件名 let filename = NSURL(fileURLWithPath: filePath).lastPathComponent! // 创建上传凭证 let token = createQiniuToken(filename: filename) // 上传文件 let qiNiu = QNUploadManager()! qiNiu.putFile(filePath, key: filename, token: token, complete: {info, key, resp -> Void in switch info?.statusCode { case Int32(200)?: print("upload success") default: print("upload fail") } }, option: nil) }
添加测试代码测试上传
上传失败信息
017-02-01 21:46:17.286161 iDragProject[29836:489720] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file. upload fail
苹果安全机制限制,http 不安全,要实现上传需要到 Info.plist 设置一下
设置 Info.plist
打开后文件最后添加如下代码
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>qiniu.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict>
代码添加位置
添加完后效果
再次测试上传 日志显示上传成功,可以去七牛的后台检查一下是否有上传的文件
总结
上传功能已经实现,接下来就是要实现拖动文件上传了。
值得注意的地方是:一定要学会使用 CocoaPods 管理 Swift 库。