美文网首页Swift
HBKit-Swift 框架说明

HBKit-Swift 框架说明

作者: MaxCong | 来源:发表于2017-06-09 16:07 被阅读0次

    1. HBKit 来源

    HBKit最早由HuobanKit演变而来,我将HuobanKit中跟业务无关的代码抽离出来,精简成基本的网络框架和数据库(CoreData)框架,对MVVM架构设计方案清晰分层,并结合VIPER、Riblets架构设计思路引入Router路由,组成:网络、数据库、路由三个体系。可以以极简的方式来使用,并让ViewController间解耦。并由Swift进行代码重写,一个全新Swift框架。
    而HuobanKit则以后由业务model组成,负责业务的数据与服务器交互。

    目前本框架还没有公布出来,尚需进一步完善

    1.1 网络部分

    网络请求部分针对Alamofire进行二次封装,
    提取出可以方便快捷使用的网络请求GET/ POST/ PUT/ DELETE的四种方法
    

    1.2 数据库部分

    采用apple原生CoreData作为基础数据库,提供数据增、删、查(改)的动作,
    并支持Api属性对应数据entity模型的驼峰命名法的匹配:如user_id => userId
    

    1.3 路由部分

    采用url网络链接写法,基于url进行拆分并提取出class/function?params进行ViewController窗口的初始化
    

    2. 用法

    2.1 发起网络请求

    2.1.1 GET

    • 按任意请求举例
    // 接口域在HBKitConfig.swift HBApiURL中设置
    let request = HBRequest.GETRequestWithPath(path: "/uri")
    request.completion { [unowned self] (error:NSError?, response:HBResponse) in
        if error != nil {
            print("faild to request, error :", error)
        } else {
            print("response:", response)
        }
    }
    request.send()
    

    2.1.2 POST

    • 按用户登录举例
    var parameters: Dictionary = Dictionary<String, Any>()
    parameters["username"] = "username"
    parameters["password"] = "password"
    
    let request:HBRequest = HBRequest.POSTRequestWithPath(path: "/auth", parameters: parameters)
    request.completion { (error:NSError?, response:HBResponse) in
        if error != nil {
            print("faild to request, error :", error)
        } else {
            print("response:", response.body as Any)
        }
    }
    request.send()
    

    2.1.3 MultiRequest

    • 多请求需要服务器支持batch接口、并对POST请求进行拆分和返回数据
    // 基于GET请求将send方法添加参数packer: HBMultiRequestPacker.shared
    request.send(packer: HBMultiRequestPacker.shared)
    
    // 并由HBMultiRequestPacker类send
    HBMultiRequestPacker.shared.send()
    

    2.2 数据库

    2.2.1 网络请求入库

    2.2.1.1 如何根据接口返回数据构建数据表?

    • 如果已经存在 {YourProjectName}.xcdatamodeld 文件则建立Entity, 比如ItemModel
    • 在ItemModel当中新建两个字段:

    ItemModel

    itemId (Integer 64)

    name (String)

    • 并打开XCode -> Editor -> Create NSManagedObject Class 新建一个针对于ItemModel的类
    • 打开ItemModel的类,在class后面加入HBManagedObject声明
    • 并为ItemModel类添加一个类方法identityPropertyNames指明主键(Primary key):
    public class ItemModel:NSManagedObject, HBManagedObject {
        static func identityPropertyNames() -> [String] {
            return ["itemId"]
        }
    }
    

    2.2.1.2 如何将接口数据存入CoreData?

    • 比如:接收到Api数据如下
    {"item_id": 10000, "name": "测试Item"}
    
    • 在线请求HBRequest接收到的数据在response.body当中(response:HBResponse),尝试入库
    // 网络请求返回值片段...
    request.completion { [unowned self] (error:NSError?, response:HBResponse) in
        if error == nil {
            // response.body = {"item_id": 10000, "name": "测试Item"}
            let body = response.body as! Dictionary
            let itemModel = ItemModel.hb_createObjectOrUpdate(fromDictionary:  body, isSave: true)
        }
    }
    
    • 如果请求的response.body是一个Array,则可以使用HBManagedObject针对Array的扩展方法:
    /* 
    response.body = [
                            {"item_id": 10000, "name": "测试Item0"},
                            {"item_id": 10001, "name": "测试Item1"},
                            {"item_id": 10002, "name": "测试Item2"}
                        ]
    */
    // 网络请求返回值,入库片段
    request.completion { [unowned self] (error:NSError?, response:HBResponse) in
        let body = response.body as! [Dictionary]
        let itemArray:Array = ItemModel.hb_createObjectsOrUpdate(fromArray:  body,
                         isSave: true, 
                         step: { (itemModel:ItemModel, index:Int) in
            // 单步执行,可以改造数据等
        }, completion: { 
            // 注意completion还可以做其他事情,比如Array循环结尾的回调      
        })!
    }
    

    2.2.2 数据库数据查询

    • 数据库查询方法,可以写在ItemModel中,比如按itemId查询一个指定数据
    public class ItemModel: NSManagedObject, HBManagedObject {
        static func identityPropertyNames() -> [String] {
            return ["itemId"]
        }
        
        static func queryModel(itemId:Int64) -> ItemModel? {
            let result:Array = self.hb_getObjects(predicate: NSPredicate.init(format: "itemId=%ld", itemId))
            if result.count > 0 {
                return result.first
            }
            return nil
        }
    }
    

    2.2.3 数据库数据删除

    • 通过ItemModel查询到的数据,通过实例方法.delete()即可删除,比如:
    let itemModel = ItemModel.queryModel(itemId:10000)
    itemModel.delete()
    

    2.2.4 数据库数据修改和保存

    let itemModel = ItemModel.queryModel(itemId:10000)
    itemModel.name = "change the name"
    itemModel.save()
    

    2.3 Router 路由解耦

    • HBKit提供一个HBRouter类来进行业务层(UIViewController)开发解耦,并提供HBBaseViewController的协议来约定解耦规则
    • HBRouter基于网络链接来进行url的拆解,识别huoban://host(class)/action(function)?params...
    • HBRouter会根据host,自动寻找host + "ViewController"的类来初始化

    2.3.1 声明一个可用于HBRouter路由的HBBaseViewController

    • HBBaseViewController 存在一个协议,需要实现该方法,才能完成Router的调用
    protocol HBBaseViewController {
        static func createViewController() -> UIViewController
    }
    
    • 开始声明一个基于HBBaseViewController协议的ViewController,叫ItemViewController
    • ItemViewController可以有HBRouter传参,比如:itemId:NSNumber
    class ItemViewController: UIViewController, HBBaseViewController {
        var itemId:NSNumber? = nil
        
        // 基于HBBaseViewController协议,声明createViewController,方便HBRouter
        static func createViewController() -> UIViewController {
            //这里采用从StoryBoard来获取一个UIViewController
            return self.instantiateViewControllerFromStoryboard(name: "Item")
        }
        
        override func viewDidLoad() {
        }
    }
    
    • 需要打开ItemViewController的地方,可以采用HBRouter的url形式来打开它:
    HBRouter.shared.push(path: "huoban://item", params: ["item_id": NSNumber.init(value: 10000)])
    

    当然我们也可以通过?item_id=10000传参

    HBRouter.shared.push(path: "huoban://item?item_id=10000")
    
    • HBRouter会自动将item_id转换成itemId的方式进行赋值(?itemId=10000则不会转换)
    • 这代码的结果将会是:
    var itemViewController = ItemViewController.createViewController()
    itemViewController.itemId = NSNumber.init(value:10000)
    self.navigationController.pushViewController(itemViewController)
    
    • HBRouter有两个方法打开ViewController: 1. push, 2. present

    2.4 OBServable(订阅被观察者Block)

    2.4.1 HBKit/Extension/Observable.swift 是被观察者

    • 由于MVVM的架构变更,ViewModel层和ViewController层需要一种方式来解耦,将ViewModel 状态变更自动回调给 ViewController。做到减少状态设置,对ViewController减肥。
    • 具体用法
    //ViewModel
    class ItemViewModel {
        var itemName = Observable<String>("")
        init (_ itemId:Int) {
            // itemId......do something
        }
        
        func requestNetworkData() {
            itemName <- "refresh new name!"
        }
        func requestNetworkData2() {
            itemName <- "refresh new name2!"
        }
    }
    
    // ViewController
    class ItemViewController {
        var itemViewModel = ItemViewModel(10000)
        @IBOutlet weak var itemNameLabel: UILabel!
        
        itemViewModel.itemName.subscribe{ [unowned self] (oldValue, newValue:Bool) in
            self.itemNameLabel.text = newValue
        }
    
        itemViewModel.requestNetworkData()
        itemViewModel.requestNetworkData2()
    }
    

    2.5 工程目录结构推荐

    • 基于尽可能的解耦业务逻辑间的联系,我们在使用HBRouter的时候,会将ViewController进行分类,我推荐的目录结构为:

    Project

    Core

    Common

    HBKit

    Data

    ItemModel.swift

    Model

    ItemAgent.swift

    Module

    Item

    Item.storyboard

    ItemList

    ItemListViewController.swift


    3. HBKit 目录结构

    • HBKitConfig (Config设置类)

    • Network (网络请求组件目录)

      • HBClient
      网络请求发送,认证信息拼接,用于将HBRequest包装成真实的URLRequest类的请求
      拼接Header
      
      • HBRequest
      请求体包装用户接口类
      用户可以设定HttpMethod: GET/ POST/ PUT/ DELETE
      
      • HBResponse
      网络请求返回值的包装用户接口类
      
      • HBAuthorization
      登录用户验证类
      
      • HBMultiRequest
      多请求类,基于Batch接口进行Post打包提交
      
    • CoreData (基于CoreData实现数据组件目录)

      • HBManagedObject (NSManagedObject+extension)
      对NSManagedObject的扩展,封装了方便增、删、改、查的动作,使用反射的原理映射给CoreData的Model类
      
    • Extension

      • Class

        • HBNotificationCenter
        广播的block轻巧封装
        
        • Observable
        极简观察者模式
        
        • HBImageURLSessionDataTask
        轻巧的图片下载类
        
      • NSObject扩展

      1.获取NSObject中的属性名称列表
      
      • String扩展
      1.字符串切割"_"现转换为驼峰命名法
      
      • UIImageView扩展
      1. 针对ImageView提供快捷网络图片设置
      
      • UIButton扩展
      1. 针对UIButton提供快捷网络图片设置
      
      • UIViewController扩展
      定义常规HBBaseViewController针对HBRouter和Storyboard初始化的动作
      
      • UIActivityIndicatorView
      loading的快捷显隐的扩展
      
      • NSError
      网络请求错误的NSError扩展
      
    • Router

      • HBRouter
      路由,与HBBaseViewController一起联合进行路由的反射操作,用于解耦业务间的类 
      

    相关文章

      网友评论

        本文标题:HBKit-Swift 框架说明

        本文链接:https://www.haomeiwen.com/subject/nrrfqxtx.html