Swift5: App模块化

作者: DrEnhart | 来源:发表于2022-05-06 20:08 被阅读0次
    AppDemo.png

    目标是将序列化和网络请求做成单独的framework并且可以替换.
    所有公用的东西都放在公共库Common中.

    workspace 'AppDemo.xcworkspace'
    platform :ios, '13.0'
    
    use_frameworks!
    load './Api/api_v1.rb'
    
    target :Common do
      project 'Common/Common.xcodeproj'
    
      pod 'Alamofire'
    
     end
    
    target :AppDemo do
        project 'App/AppDemo/AppDemo.xcodeproj'
        pod 'Common', :path => './Common/'
        
        load_api_pods
    end
    
    target :ApiModelSerialize do
        project 'Api/ApiModelSerialize/ApiModelSerialize.xcodeproj'
    
        pod 'Common', :path => './Common/'
        pod 'SwiftyJSON'
    end
    
    target :ApiNetwork do
        project 'Api/ApiNetwork/ApiNetwork.xcodeproj'
    
        pod 'Common', :path => './Common/'
        pod 'Alamofire'
    end
    

    load_api_pods是一个单独.rb文件, 想替换framework的话就修改这个文件.

    def load_api_pods
        pod 'ApiModelSerialize', :path => './Api/ApiModelSerialize/'
        pod 'ApiNetwork', :path => './Api/ApiNetwork/'
    end
    

    序列化(ApiModelSerialize)

    在ApiModelSerialize这个framework中声明一个protocol

    protocol ISwiftyJson {
        init()
        
        mutating func dFromJSON(json: JSON)
        func dToJSON() -> JSON
    }
    

    再为一些基本类型扩展遵循一下这个protocol

    extension Int: ISwiftyJson {
        mutating func dFromJSON(json: JSON) {
            self = json.intValue
        }
        
        func dToJSON() -> JSON {
            var json = JSON()
            json.intValue = self
            return json
        }
    }
    

    需要序列化的Model也需要扩展遵循一下这个protocol

    extension Member: ISwiftyJson {
        
        public func dFromJSON(json: JSON) {
            Id = json["Id"].intValue
        }
    
        public func dToJSON() -> JSON {
            var json = JSON()
            json["Id"].intValue = Id
            return json;
        }
    }
    

    现在序列化这个是基本上算是实现了, 但是还需要封装一下.
    Common中声明一个protocol

    public protocol IApiModelSerialize {
        mutating func aLoadFromJSONString<T>(model: T, str: String)
        func aToJSONString<T>(model: T) -> String
        func aConvertJSONStringToArray<T>(type: T.Type, str: String) -> [T] where T: ServerModel
    }
    

    ApiModelSerialize中遵循一下这个protocol

    public class PApiModelSerialize: IApiModelSerialize {
    
        public init() {
            
        }
        
        public func aLoadFromJSONString<T>(model: T, str: String) {
            if var m = model as? ISwiftyJson {
                m.dFromJSON(json: JSON(parseJSON: str))
            }
        }
        
        public func aToJSONString<T>(model: T) -> String {
            if let m = model as? ISwiftyJson {
                return m.dToJSON().rawString()!
            }
            fatalError("Can't deSerialize")
        }
        
        public func aConvertJSONStringToArray<T>(type: T.Type, str: String) -> [T] where T : IServerModel {
            let arrayValue = JSON(parseJSON: str)
            var array = [T]()
            for j in arrayValue {
                if let jsonString = j.1.rawString() {
                    var t = T()
                    t.aLoadFromJSONString(str: jsonString)
                    array.append(t)
                }
            }
            return array
        }
    
    }
    

    Common中声明一个protocol

    public protocol IServerModel {
        init()
        
        mutating func aLoadFromJSONString(str: String)
        func aToJSONString() -> String
    }
    

    ServerModel作为所有Model的父类遵循这个protocol

    open class ServerModel: IServerModel {
        public required init() {
            
        }
        
        open func aLoadFromJSONString(str: String) {
            Api.pModelSerialize.aLoadFromJSONString(model: self, str: str)
        }
        
        open func aToJSONString() -> String {
            return Api.pModelSerialize.aToJSONString(model: self)
        }
    }
    

    Model序列化的时候调用aLoadFromJSONString这个方法就可以了.

    网络请求(ApiNetwork)

    Common中声明一个protocol

    public protocol IApiNetwork {
        func aRequest<T>(_ params: ServerParam, handler: IServerRequestHandler<T>?) where T: IServerModel
    }
    

    ApiNetwork中遵循一下这个protocol

    public class PApiNetwork: IApiNetwork {
    
        public init() {
            
        }
        
        public func aRequest<T>(_ params: ServerParam, handler: IServerRequestHandler<T>?) where T : IServerModel {
            ServerUtil_Alamofire.fRequest(params, handler: handler)
        }
    
    }
    

    实际使用中调用一下就可以了

    open class ServerUtil_Account {
    
        private static let c_Controller = "Account"
        
        public static func Login(loginParam: LoginParam, handler: IServerRequestHandler<MyProfile>?) {
            let param = ServerParam(post: true)
                .controller(c_Controller)
                .action("Login")
                .add(value: loginParam)
            Api.pNetwork.aRequest(param, handler: handler)
        }
    
    }
    

    关联声明与实现

    ApiModelSerialize和ApiNetwork声明在Common中, 实现在具体framework中, 在App中需要将他们关联起来.

    class AppConfigImpl {
    
        init() {
    
        }
        
        func connect() {
            Api.pModelSerialize = PApiModelSerialize()
            Api.pNetwork = PApiNetwork()
        }
    
    }
    
    class AppDelegate: UIResponder, UIApplicationDelegate {
        
        var window: UIWindow?
        
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            AppConfigImpl().connect()
            return true
        }
    
    }
    
    

    最后用登录功能做一下验证

            ServerUtil_Account.Login(loginParam: loginParam, handler: IServerRequestHandler<MyProfile>({data in
                print(data.Member?.NickName)
            }, fail: { (failInfo) in
                
            }))
    

    代码

    代码放在github, 有需要自取.
    https://github.com/drenhart/AppDemo.git

    相关文章

      网友评论

        本文标题:Swift5: App模块化

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