Bamboots 0.6.0

Bamboots 0.6.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2017年12月
SwiftSwift版本4.0
SPM支持SPM

mmoaay维护。



 
依赖
AlamofireCodable>= 0
Alamofire>= 0
 

Bamboots 0.6.0

  • 作者
  • mmoaay

Bamboots: Extension 4 Alamofire

CI Status
Version
Platform
Language
Codebeat
License
Gitter
Weibo
<3

Bamboots 是一个基于 Alamofire 的网络请求框架,旨在使业务开发中的网络请求更容易。

协议

Bamboots 利用面向协议编程的优点,将所有与网络请求相关的抽象成协议。以下是协议列表:

  • Requestable: 网络请求协议,遵守此协议的对象可以执行网络请求。
  • Formable: 表单协议。遵守此协议的对象可以由 Requestable 协议中的 requestdownloadupload 方法使用。
    • UploadFormable: 上传表单协议,上传请求表单的基本协议。
      • UploadStreamFormable: 遵守此协议来创建包含流对象的上传表单。
      • UploadDataFormable: 遵守此协议来创建包含数据对象的上传表单。
      • UploadFileFormable: 遵守此协议来创建包含文件的上传表单。
      • UploadMultiFormDataFormable: 遵守此协议来创建包含多表单数据的上传表单。
    • DownloadFormable: 下载表单协议,下载请求表单的基本协议。
      • DownloadResumeFormable: 遵守此协议来创建可以恢复下载任务的下载表单。
    • RequestFormable: 遵守此协议来创建请求表单。
  • Loadable: 用于在请求时在指定容器上显示遮罩的协议(例如,请求开始时在 UIViewcontroller 的视图中添加 UIActivityIndicatorView,请求结束时移除)。遵守此协议的对象可以使用 DataRequestload 方法。
    • Maskable: Loadable 的遮罩协议,遵守此协议的视图将被视为遮罩。
    • Containable: Loadable 的容器协议,遵守此协议的对象可以用作遮罩的容器。
    • Progressable: 请求的进度协议,遵守此协议的对象可以获取请求的进度。遵守此协议的对象可以使用 DataRequestprogress 方法。
  • Messageable: 消息协议。
    • Warnable: 警告协议。遵守此协议来自定义错误发生时显示警告消息的方式。
    • Informable: 通知协议。遵守此协议来自定义请求成功时显示通知消息的方式。
  • Errorable: 错误协议。遵守此协议来自定义错误配置。
    • JSONErrorable:用于JSON数据的错误协议。通过遵循此协议来自定义JSON数据的错误配置。

通常您不需要太关注这些协议,因为我们已经为它们有了许多默认实现。但是,如果您想自定义某些内容,您只需遵循这些协议并做您想做的事情。以下是这些协议的一些默认实现。

  • LoadType:一个符合Loadable协议的枚举,使用case default(container:Containable)情况在请求时在容器上显示MaskView
  • UIAlertController+Messageable:使用此扩展,您可以将UIAlertController直接传递到DataRequestwarninform方法。
  • UIButton+Loadable:使用此扩展,您可以将按钮直接传递到DataRequestload方法。
  • UITableViewCell+Loadable:使用此扩展,您可以将单元格直接传递到DataRequestload方法。
  • UIRefreshControl+Loadable:使用此扩展,您可以将UIRefreshControl直接传递到DataRequestload方法。
  • UIProgressView+Progressable:使用此扩展,您可以将UIProgressView直接传递到DataRequestprogress方法。
  • UIScrollView+Containable:扩展UIScrollView以符合Containable协议。
  • UITableViewCell+Containable:扩展UITableViewCell以符合Containable协议。
  • UIViewController+Containable:扩展UIViewController以符合Containable协议。
  • ActivityIndicator:defaultValue的默认遮罩层,用于UITableViewCell和UIButton。
  • MaskView:其他内容的默认遮罩层。

功能

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

要求

  • Alamofire:Swift中的优雅HTTP网络
  • AlamofireCodable:一个Alamofire扩展,它使用Codable将JSON响应数据转换为Swift对象

使用

创建一个表单

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

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

并且您还可以为指定的协议创建扩展

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

以及其他参数,如urlmethodparameters等。
每个请求都将有它自己的值,因此我们创建一个对象并将其使它遵循协议

struct WeatherForm: RequestFormable {
    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
}

发起请求

您需要做的是符合Requestable协议,在这个协议中,我们为您实现了某些方法

  • func request(_ form: RequestFormable) -> DataRequest
  • func download(_ form: DownloadFormable) -> DownloadRequest
  • func download(_ form: DownloadResumeFormable) -> DownloadRequest
  • func upload(_ form: UploadDataFormable) -> UploadRequest
  • func upload(_ form: UploadFileFormable) -> UploadRequest
  • func upload(_ form: UploadStreamFormable) -> UploadRequest
  • func upload(_ form: UploadMultiFormDataFormable, completion: ((UploadRequest) -> Void)?)

以下是请求方法的用法

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

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

在请求时显示遮罩

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

func load(load: Loadable = LoadType.none) -> Self

UIViewController上显示遮罩

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

UIButton上显示遮罩

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

注意UIActivityIndicatorView的颜色是UIButton的)tintColor

显示自定义遮罩

首先,我们创建一个遵守Loadable协议的LoadConfig类。

class LoadConfig: Loadable {
    init(container: Containable? = nil, mask: Maskable? = MaskView(), inset: UIEdgeInsets = UIEdgeInsets.zero) {
        insetMine = inset
        maskMine = mask
        containerMine = container
    }
    
    func mask() -> Maskable? {
        return maskMine
    }
    
    func inset() -> UIEdgeInsets {
        return insetMine
    }
    
    func maskContainer() -> Containable? {
        return containerMine
    }
    
    func begin() {
        show()
    }
    
    func end() {
        hide()
    }
    
    var insetMine: UIEdgeInsets
    var maskMine: Maskable?
    var containerMine: Containable?
}

然后我们可以像下面这样使用它

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

这是 Loadable 协议最强大的使用方式。通过这种方式,您可以自定义 Loadable 协议具有的所有功能。

UITableViewUIScrollView 上显示遮罩

let load = LoadConfig(container:self.tableView, mask: ActivityIndicator(), 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 上显示遮罩(备注:尚在开发中)

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!)
}

我们还可以支持其他刷新控制,如 MJRefresh

请求时显示进度

我们已扩展了 Alamofire 的 DownloadRequestUploadRequest 类,并向其中添加了 progress 方法。

func progress(progress: Progressable) -> Self

然后我们可以按以下方式使用它

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

如失败则显示警告消息

我们已扩展了 Alamofire 的 DataRequest 类,并向其中添加了 warn 方法。

func warn<T: JSONErrorable>(error: T, warn: Warnable, completionHandler: ((JSONErrorable) -> Void)? = nil) -> Self

然后我们可以按以下方式使用它

let alert = UIAlertController(title: "Warning", message: "Network unavailable", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil))
        
request(WeatherForm()).warn(
    error: WeatherError(),
    warn: alert
)

注意:目前我们只为 JSON 格式响应提供 warn

如成功则显示通知消息

我们已扩展了 Alamofire 的 DataRequest 类,并向其中添加了 inform 方法。

func inform<T: JSONErrorable>(error: T, inform: Informable) -> Self

然后我们可以按以下方式使用它

let alert = UIAlertController(title: "Notice", message: "Load successfully", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil))
request(WeatherForm()).inform(
    error: WeatherInformError(),
    inform: alert
)

注意:目前我们只为 JSON 格式响应提供 inform

JSON 转对象

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

有关更多信息,请参阅 AlamofireCodable

链式调用

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

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

let warn = UIAlertController(title: "Warning", message: "Network unavailable", preferredStyle: .alert)
warn.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil))

let inform = UIAlertController(title: "Notice", message: "Load successfully", preferredStyle: .alert)
inform.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil))

request(WeatherForm()).load(load:load).progress(progress: progress).warn(error: WeatherError(), warn: warn).inform(error: WeatherInformError(), inform: inform)

bonus

EyeLoading

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

如果您感兴趣,可以检查示例项目中的 Eyeloading 文件。

示例

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

安装

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

pod "Bamboots"

作者

mmoaay, [email protected]

许可证

Bamboots 采用 MIT 许可证。有关更多信息,请参阅 LICENSE 文件。