BMSCore
BMSCore 是 IBM Bluemix Mobile Services(IBM Bluemix 移动服务)Swift SDK 的核心组件。
目录
概述
BMSCore 提供了其他 Bluemix Mobile Services (BMS)客户端 SDK 使用 HTTP 基础设施与相应的 Bluemix 服务进行通信的 HTTP 基础设施。这些其他 SDK 包括 BMSAnalytics,BMSPush,BMSSecurity 和 BluemixObjectStorage。
您还可以使用此SDK通过BMSURLSession
向任何资源发出网络请求。该API是对原生Swift URLSession的包装,目前支持数据任务和上传任务。BMSURLSession
在您的应用程序中安装了其他BMS SDK后将变得更强大。借助于BMSSecurity,您可以发出网络请求到受移动客户端访问保护的远端。借助于BMSAnalytics,将自动收集所有使用BMSURLSession
做出的请求的分析数据(如果选择启用),这些数据可以随后发送到移动分析服务。
需求
- iOS 8.0+ / watchOS 2.0+
- Xcode 7.3, 8.0
- Swift 2.2 - 3.0
- Cocoapods或Carthage
安装
可以使用Cocoapods或Carthage安装Bluemix移动服务Swift SDK。
Cocoapods
要使用Cocoapods安装BMSCore,将其添加到Podfile中。如果项目还没有Podfile,使用pod init
命令。
use_frameworks!
target 'MyApp' do
pod 'BMSCore'
end
然后运行pod install
命令,并打开生成的.xcworkspace
文件。要更新到BMSCore的新版本,使用pod update BMSCore
。
有关使用Cocoapods的更多信息,请参阅Cocoapods指南。
Xcode 8
在Xcode 8中使用Cocoapods安装时,请确保已安装Cocoapods 1.1.0 版本或更高。您可以使用命令 sudo gem install cocoapods
获取Cocoapods的最新版本。
如果打开Xcode 8项目(在安装BMSCore之后)提示“转换为当前Swift语法?”,请 不要 转换BMSCore或BMSAnalyticsAPI。
Carthage
使用Carthage安装BMSCore,请按照这里的说明操作。
在您的Cartfile中添加以下行
github "ibm-bluemix-mobile-services/bms-clientsdk-swift-core"
然后运行 carthage update
命令。构建完成后,将 BMSCore.framework
和 BMSAnalyticsAPI.framework
添加到您的项目中(步骤3,请参阅上述链接)。
Xcode 8
对于使用Swift 2.3构建的应用,请使用命令 carthage update --toolchain com.apple.dt.toolchain.Swift_2_3
。否则,请使用 carthage update
。
示例用法
查看完整的API参考 这里。
--
导入模块
import BMSCore
--
初始化客户端
在与其他BMS SDK一起使用BMSCore时,初始化 BMSClient
是必须的。
BMSClient.sharedInstance.initialize(bluemixRegion: BMSClient.Region.usSouth)
--
监控网络连接
使用NetworkMonitor
API,您可以为iOS设备监控互联网连接状态。您可以使用这些信息来决定何时发送网络请求,以及如何处理离线或网络速度慢的情况。
首先,创建一个NetworkMonitor
的新实例。每个应用程序只需要一个实例。注意:初始化器是可能失败的,因此您需要稍后解开结果。
let networkMonitor = NetworkMonitor()
要获取当前网络连接类型(WiFi、WWAN或无连接),请使用networkMonitor.currentNetworkConnection
。如果设备已启用数据计划,您可以使用networkMonitor.cellularNetworkType
查看他们是否有访问4G、3G或2G。
您还可以创建一个观察者来检测网络连接变化。
Swift 3
networkMonitor.startMonitoringNetworkChanges()
NotificationCenter.default.addObserver(self, selector: #selector(networkConnectionChanged), name: NetworkMonitor.networkChangedNotificationName, object: nil)
func networkConnectionChanged() {
print("Changed network connection to: \(networkMonitor.currentNetworkConnection)")
}
Swift 2
networkMonitor.startMonitoringNetworkChanges()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(networkConnectionChanged), name: NetworkMonitor.networkChangedNotificationName, object: nil)
func networkConnectionChanged() {
print("Changed network connection to: \(networkMonitor.currentNetworkConnection)")
}
--
发起网络请求
数据任务
使用BMSURLSession
,您可以创建数据任务来发送和接收数据。
以下示例展示了如何创建并发送一个数据任务,使用完成处理程序来解析响应。
注意:如果您还使用BMSAnalytics框架收集这些网络请求的数据,请确保如示例所示,在创建数据任务后立即调用.resume()
。
Swift 3
var request = URLRequest(url: URL(string: "http://httpbin.org/get")!)
request.httpMethod = "GET"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .default, delegate: nil, delegateQueue: nil, autoRetries: 2)
urlSession.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if let httpResponse = response as? HTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
if data != nil, let responseString = String(data: data!, encoding: .utf8) {
print("Response data: \(responseString)")
}
if let error = error {
print("Error: \(error)")
}
}.resume()
Swift 2
let request = NSMutableURLRequest(URL: NSURL(string: "http://httpbin.org/get")!)
request.HTTPMethod = "GET"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .defaultSessionConfiguration(), delegate: nil, delegateQueue: nil, autoRetries: 2)
urlSession.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in
if let httpResponse = response as? NSHTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
if data != nil, let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) {
print("Response data: \(responseString)")
}
if let error = error {
print("Error: \(error)")
}
}.resume()
--
作为使用完成处理器的替代方案,你可以创建自己的 URLSessionDelegate,以获得对处理响应的更多控制。
Swift 3
var request = URLRequest(url: URL(string: "http://httpbin.org/get")!)
request.httpMethod = "GET"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .default, delegate: URLSessionDelegateExample(), delegateQueue: nil, autoRetries: 2)
urlSession.dataTask(with: request).resume()
class URLSessionDelegateExample: NSObject, URLSessionDataDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let error = error {
print("Error: \(error)\n")
}
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
if let httpResponse = response as? HTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
// Required when connecting with an MCA-protected backend
completionHandler(URLSession.ResponseDisposition.allow)
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
if let responseString = String(data: data, encoding: .utf8) {
print("Response data: \(responseString)")
}
}
}
Swift 2
let request = NSMutableURLRequest(URL: NSURL(string: "http://httpbin.org/get")!)
request.HTTPMethod = "GET"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .defaultSessionConfiguration(), delegate: NSURLSessionDelegateExample(), delegateQueue: nil, autoRetries: 2)
urlSession.dataTaskWithRequest(request).resume()
class NSURLSessionDelegateExample: NSObject, NSURLSessionDataDelegate {
internal func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if let error = error {
print("Error: \(error)\n")
}
}
internal func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
if let httpResponse = response as? NSHTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
// Required when connecting with an MCA-protected backend
completionHandler(NSURLSessionResponseDisposition.Allow)
}
internal func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
if let responseString = String(data: data, encoding: NSUTF8StringEncoding) {
print("Response data: \(responseString)")
}
}
}
--
Upload task
上传任务是一种数据任务,可以简化数据或文件的上传过程。使用上传任务,你可以监视每个上传的进度,并在应用未运行时在后台继续上传。
以下示例展示了如何使用完成处理程序解析响应来上传文件。
注意:如果您还使用BMSAnalytics框架收集这些网络请求的数据,请确保如示例所示,在创建数据任务后立即调用.resume()
。
Swift 3
let file = Bundle.main.url(forResource: "MyPicture", withExtension: "jpg")!
var request = URLRequest(url: URL(string: "https://httpbin.org/post")!)
request.httpMethod = "POST"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .default, delegate: nil, delegateQueue: nil, autoRetries: 2)
urlSession.uploadTask(with: request, fromFile: file, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) in
if let httpResponse = response as? HTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
if let error = error {
print("Error: \(error)")
}
}).resume()
Swift 2
let file = NSBundle.mainBundle().URLForResource("MyPicture", withExtension: "jpg")!
let request = NSMutableURLRequest(URL: NSURL(string: "https://httpbin.org/post")!)
request.HTTPMethod = "POST"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .defaultSessionConfiguration(), delegate: nil, delegateQueue: nil, autoRetries: 2)
urlSession.uploadTaskWithRequest(request, fromFile: file, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) in
if let httpResponse = response as? NSHTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
if let error = error {
print("Error: \(error)")
}
}).resume()
--
作为使用完成处理器的替代方案,你可以创建自己的 URLSessionDelegate,以获得对处理响应的更多控制。
Swift 3
let file = Bundle.main.url(forResource: "MyPicture", withExtension: "jpg")!
var request = URLRequest(url: URL(string: "https://httpbin.org/post")!)
request.httpMethod = "POST"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .default, delegate: URLSessionDelegateExample(), delegateQueue: nil, autoRetries: 2)
urlSession.uploadTask(with: request, fromFile: file).resume()
class URLSessionDelegateExample: NSObject, URLSessionDataDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let error = error {
print("Error: \(error)\n")
}
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
if let httpResponse = response as? HTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
// Required when connecting with an MCA-protected backend
completionHandler(URLSession.ResponseDisposition.allow)
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
if let responseString = String(data: data, encoding: .utf8) {
print("Response data: \(responseString)")
}
}
func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
DispatchQueue.main.async {
let currentProgress = Float(totalBytesSent) / Float(totalBytesExpectedToSend) * 100
print("Upload progress = \(currentProgress)%")
}
}
}
Swift 2
let file = NSBundle.mainBundle().URLForResource("MyPicture", withExtension: "jpg")!
let request = NSMutableURLRequest(URL: NSURL(string: "https://httpbin.org/post")!)
request.HTTPMethod = "POST"
request.setValue("value", forHTTPHeaderField: "key")
let urlSession = BMSURLSession(configuration: .defaultSessionConfiguration(), delegate: NSURLSessionDelegateExample(), delegateQueue: nil, autoRetries: 2)
urlSession.uploadTaskWithRequest(request, fromFile: file).resume()
class NSURLSessionDelegateExample: NSObject, NSURLSessionDataDelegate {
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if let error = error {
print("Error: \(error)\n")
}
}
internal func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
if let httpResponse = response as? NSHTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
// Required when connecting with an MCA-protected backend
completionHandler(NSURLSessionResponseDisposition.Allow)
}
internal func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
if let responseString = String(data: data, encoding: NSUTF8StringEncoding) {
print("Response data: \(responseString)")
}
}
internal func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
dispatch_async(dispatch_get_main_queue()) {
let currentProgress = Float(totalBytesSent) / Float(totalBytesExpectedToSend) * 100
print("Upload progress = \(currentProgress)%")
}
}
}
--
自动重发请求
在上面的数据任务和上传任务示例中,BMSURLSession
初始化器中有一个可选参数 autoRetries
。这是在由于网络问题失败时,BMSURLSession
会自动重发的任务次数。这些自动重试发生在以下条件下
- 请求超时
- 网络连接丢失(如WiFi断开或失去蜂窝服务)
- 连接到主机失败
- 504 响应
如果在这个初始化器中省略了这个参数,则不会发生自动重试。
许可证
版权所有 2016 IBM 公司。
遵循 Apache License,版本 2.0(“许可证”);除非遵守许可证,否则不得使用此文件。您可以在以下位置获得许可证副本:
https://apache.ac.cn/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则根据许可证分发的软件按“现状”提供,不提供任何明示或暗示的保证或条件。有关许可协议的管理权限和限制,请参阅许可证。