目標(biāo)是將序列化和網(wǎng)絡(luò)請求做成單獨的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
}
再為一些基本類型擴(kuò)展遵循一下這個protocol
extension Int: ISwiftyJson {
mutating func dFromJSON(json: JSON) {
self = json.intValue
}
func dToJSON() -> JSON {
var json = JSON()
json.intValue = self
return json
}
}
需要序列化的Model也需要擴(kuò)展遵循一下這個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;
}
}
現(xiàn)在序列化這個是基本上算是實現(xiàn)了, 但是還需要封裝一下.
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序列化的時候調(diào)用aLoadFromJSONString這個方法就可以了.
網(wǎng)絡(luò)請求(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)
}
}
實際使用中調(diào)用一下就可以了
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)
}
}
關(guān)聯(lián)聲明與實現(xiàn)
ApiModelSerialize和ApiNetwork聲明在Common中, 實現(xiàn)在具體framework中, 在App中需要將他們關(guān)聯(lián)起來.
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