MBNetwork 0.4.0

MBNetwork 0.4.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2017年1月
SwiftSwift 版本3.0
SPM支持 SPM

mmoaay 维护。



 
依赖项
SwiftProtobuf>= 0
AlamofireObjectMapper~> 4
 

MBNetwork 0.4.0

  • 作者
  • mmoaay

MBNetwork 是一个基于 AlamofireObjectMapper 的网络请求框架,旨在简化商业开发的网络请求。

协议

MBNetwork 充分利用了面向协议的编程,将有关网络请求的所有相关内容抽象为协议。以下是协议列表:

  • MBRequestable:网络请求协议,符合此协议的对象可以执行网络请求。
  • MBFormable:形式协议。符合此协议的对象可用于 MBRequestable 协议中的 requestdownloadupload 方法。
    • MBUploadFormable:上传表单协议,上传请求表单的基本协议。
      • MBUploadStreamFormable:符合此协议以创建包含流对象的表单。
      • MBUploadDataFormable:符合此协议以创建包含数据对象的表单。
      • MBUploadFileFormable:符合此协议以创建包含文件的表单。
      • MBUploadMultiFormDataFormable:符合此协议以创建包含多表单数据的表单。
    • MBDownloadFormable:下载表单协议,下载请求表单的基本协议。
      • MBDownloadResumeFormable:符合此协议以创建可以恢复下载任务的下载表单。
    • MBRequestFormable:符合此协议以创建请求表单。
  • MBLoadable:用于在请求时在指定的容器上显示遮罩的协议(例如,在请求开始时在 UIViewcontroller 的视图中添加 UIActivityIndicatorView,并在请求结束时删除它)。符合此协议的对象可以使用 DataRequestload 方法。
    • MBMaskableMBLoadable 的遮罩协议,符合此协议的视图将被视为遮罩。
    • MBContainableMBLoadable 的容器协议,符合此协议的对象可以用作遮罩的容器。
    • MBProgressable:请求的进度协议,符合此协议的对象可以获取请求的进度。符合此协议的对象可以使用 DataRequestprogress 方法。
  • MBMessageable:消息协议。
    • MBWarnable:警告协议。符合此协议以自定义发生错误时显示警告消息的方式。
    • MBInformable:通知协议。遵循此协议以自定义请求成功时显示通知消息的方式。
  • MBErrorable:错误协议。遵循此协议以自定义错误配置。
    • MBJSONErrorable:适用于 JSON 数据的错误协议。遵循此协议以自定义 JSON 数据的错误配置。

通常,您无需过多关注这些协议,因为我们已经为它们提供了许多 默认 实现。不过,如果您想进行自定义,只需要遵循这些协议并执行您想要的操作。以下是这些协议的默认实现示例

  • MBLoadType:符合 MBLoadable 协议的枚举,使用 case default(container:MBContainable) 情况在请求时在容器上显示 MBMaskView
  • MBMessageType:符合 MBMessageable 协议的枚举,使用 alertController(title: String, message: String? , actions: [UIAlertAction], container: MBContainable) 情况以显示动作控制器。
  • UIButton+MBLoadable:使用此扩展,您可以直接将按钮传递给 DataRequestload 方法。
  • UITableViewCell+MBLoadable:使用此扩展,您可以直接将单元格传递给 DataRequestload 方法。
  • UIRefreshControl+MBLoadable:使用此扩展,您可以直接将 UIRefreshControl 传递给 DataRequestload 方法。
  • UIProgressView+MBProgressable:使用此扩展,您可以直接将 UIProgressView 传递给 DataRequestprogress 方法。
  • UIScrollView+MBContainable:扩展 UIScrollView 以符合 MBContainable 协议。
  • UITableViewCell+MBContainable:扩展 UITableViewCell 以符合 MBContainable 协议。
  • UIViewController+MBContainable:扩展 UIViewController 以符合 MBContainable 协议。
  • MBActivityIndicator:UITableViewCell 和 UIButton 的默认遮挡视图。
  • MBMaskView:其他内容的默认遮挡视图。

特性

  1. 您无需继承任何对象即可获得其 features,并且可以扩展您想要的任何 features,而无需更改 MBNetwork 的代码。
  2. 我们为大多数协议提供了 默认 扩展,因此您可以轻松启动。
  3. 如果您有特殊需求,可以扩展或遵循它。
  4. 此 API 是根据 Alamofire 原则设计的,因此您也可以像 MBNetwork 为您所做的那样扩展它。
  5. 主要关注业务开发与 Alamofire 之间的事物,而不是网络请求本身。

要求

  • Alamofire:优雅的 Swift HTTP 网络编程。
  • ObjectMapper:由 Swift 编写的简单 JSON 对象映射库。
  • AlamofireObjectMapper:Alamofire 扩展,使用 ObjectMapper 将 JSON 响应数据转换为 Swift 对象。

使用方法

创建表单

对于业务开发,大多数请求的头部信息都是相同的,因此您只需扩展一次即可。

extension MBFormable {
    public func headers() -> [String: String] {
        return ["accessToken":"xxx"];
    }
}

您还可以为特定的协议创建扩展

extension MBFormable where Self: MBUploadFormable {
    public func headers() -> [String: String] {
        return ["accessToken":"xxx", "file":"xxx"];
    }
}

对于其他参数,例如 urlmethodparameters 等,每个请求都有自己的值。因此,我们创建一个对象并将其使符合协议

struct WeatherForm: MBRequestFormable {
    var city = "shanghai"

    public func parameters() -> [String: Any] {
        return ["city": city]
    }

    var url = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/2ee8f34d21e8febfdefb2b3a403f18a43818d70a/sample_keypath_json"
    var method = Alamofire.HTTPMethod.get
}

发送请求

您只需符合 MBRequestable 协议即可。在本协议中,我们已经为您实现了一些方法

  • func request(_ form: MBRequestFormable) -> DataRequest
  • func download(_ form: MBDownloadFormable) -> DownloadRequest
  • func download(_ form: MBDownloadResumeFormable) -> DownloadRequest
  • func upload(_ form: MBUploadDataFormable) -> UploadRequest
  • func upload(_ form: MBUploadFileFormable) -> UploadRequest
  • func upload(_ form: MBUploadStreamFormable) -> UploadRequest
  • func upload(_ form: MBUploadMultiFormDataFormable, completion: ((UploadRequest) -> Void)?)

这里是请求方法的使用

class LoadableViewController: UIViewController, MBRequestable {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        request(WeatherForm())
    }
}

请求时显示遮罩

我们扩展了 Alamofire 的 DataRequest 类,并为其添加了一个 load 方法。

func load(load: MBLoadable = MBLoadType.none) -> Self

在 UIViewController 中显示遮罩

request(WeatherForm()).load(load: MBLoadType.default(container: self))

在 UIButton 中显示遮罩

request(WeatherForm()).load(load: button)

显示自定义遮罩

首先,我们创建了一个符合 MBLoadable 协议的 LoadConfig 类。

class LoadConfig: MBLoadable {
    init(container: MBContainable? = nil, mask: MBMaskable? = MBMaskView(), inset: UIEdgeInsets = UIEdgeInsets.zero) {
        insetMine = inset
        maskMine = mask
        containerMine = container
    }

    func mask() -> MBMaskable? {
        return maskMine
    }

    func inset() -> UIEdgeInsets {
        return insetMine
    }

    func maskContainer() -> MBContainable? {
        return containerMine
    }

    func begin() {
        show()
    }

    func end() {
        hide()
    }

    var insetMine: UIEdgeInsets
    var maskMine: MBMaskable?
    var containerMine: MBContainable?
}

然后我们可以这样使用它

let load = LoadConfig(container: view, mask:MBEyeLoading(), inset: UIEdgeInsetsMake(30+64, 15, UIScreen.main.bounds.height-64-(44*4+30+15*3), 15))
request(WeatherForm()).load(load: load)

这是 MBLoadable 协议最强大的使用方式。这样你可以自定义 MBLoadable 协议的任何内容。

在 UITableView & UIScrollView 中显示遮罩

let load = LoadConfig(container:self.tableView, mask: MBActivityIndicator(), inset: UIEdgeInsetsMake(UIScreen.main.bounds.width - self.tableView.contentOffset.y > 0 ? UIScreen.main.bounds.width - self.tableView.contentOffset.y : 0, 0, 0, 0))
request(WeatherForm()).load(load: load)

在 UITableViewCell 中显示遮罩(PS:仍在开发中)

refresh.attributedTitle = NSAttributedString(string: "Loadable UIRefreshControl")
refresh.addTarget(self, action: #selector(LoadableTableViewController.refresh(refresh:)), for: .valueChanged)
tableView.addSubview(refresh)

func refresh(refresh: UIRefreshControl) {
    request(WeatherForm()).load(load: refresh)
}

可加载 UIRefreshControl

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView .deselectRow(at: indexPath, animated: false)
    let cell = tableView.cellForRow(at: indexPath)
    request(WeatherForm()).load(load: cell!)
}

请求时显示进度

我们扩展了 Alamofire 的 DownloadRequestUploadRequest 类,并为其添加了一个 progress 方法。

func progress(progress: MBProgressable) -> Self

然后我们可以这样使用它

download(ImageDownloadForm()).progress(progress: progress)

失败时显示警告消息

我们扩展了 Alamofire 的 DataRequest 类,并为其添加了一个 warn 方法。

func warn<T: MBJSONErrorable>(error: T, warn: MBWarnable = MBMessageType.none, completionHandler: ((MBJSONErrorable) -> Void)? = nil) -> Self

然后我们可以这样使用它

request(WeatherForm()).warn(error: WeatherError(), warn: MBMessageType.alertController(title: "Warning", message: "Network unavailable", actions: [UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil)], container: self))

注意:我们现在只为 JSON 格式响应提供了 warn

成功时显示通知消息

我们扩展了 Alamofire 的 DataRequest 类,并为其添加了一个 inform 方法。

func inform<T: MBJSONErrorable>(error: T, inform: MBInformable = MBMessageType.none) -> Self

然后我们可以这样使用它

request(WeatherForm()).inform(error: WeatherInformError(), inform: MBMessageType.alertController(title: "Notice", message: "Load successfully", actions: [UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil)], container: self))

注意:我们现在只为 JSON 格式响应提供了 inform

JSON 到 Object

request(WeatherForm()).responseObject(keyPath: "data") { (response: DataResponse<WeatherResponse>) in
    if let value = response.result.value {
        self.weatherResponse = value
        self.tableView.reloadData()
    }
}

有关更多信息,请参阅 AlamofireObjectMapper

链式调用

上述所有方法都可以以链式方式调用,例如以下方式

let load = LoadConfig(container: view, mask:MBEyeLoading(), inset: UIEdgeInsetsMake(30+64, 15, UIScreen.main.bounds.height-64-(44*4+30+15*3), 15))
let warn = MBMessageType.alertController(title: "Warning", message: "Network unavailable", actions: [UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil)], container: self)
let inform = MBMessageType.alertController(title: "Notice", message: "Load successfully", actions: [UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil)], container: self)
request(WeatherForm()).load(load:load).progress(progress: progress).warn(error: WeatherError(), warn: warn).inform(error: WeatherInformError(), inform: inform)

Bonus

MBEyeloading

我们在实现自定义加载时编写了这个动画效果,并且它全部使用 CAAnimationGroup 实现。

如果您对此感兴趣,可以在示例项目中查看 MBEyeloading 文件。

示例

要运行示例项目,请首先克隆仓库,然后从 Example 目录运行 pod install

安装

MBNetwork 可通过 CocoaPods 获取。要安装,只需将以下行添加到您的 Podfile 中

pod "MBNetwork"

作者

mmoaay, [email protected]

许可证

MBNetwork 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。