framework 和 library的区别
要了解什么是library。首先library分为static和dynamic。Static library是指有连接到一个文件,这个文件是有binary code,是在comile time feature,需要连接application里的binary,一般只会某个指定的application使用。而dynamaic一般会在多个application里使用,同时它是run time feature。一般来说static都是较大的文件,而dynamic会是比较小的文件。
回到framework和library。一般的framework是dynamic,是较小的file,和同时间多个application都可以使用。file的末尾会加
.framework
而static library就是一些比较大的file,它会在comlite time的是时候和application的resource code做linking。library有dynamic也有static
Static libraries — .a
Dynamic libraries — .dylib
小结:可以想象 static library都是一些source code,里面只有代码,而framework大多都是dynamic,所以它可以在里面加入图片,字体之类的asset。
接下来开始建造一个framework。我会用我之前写的networkFramework通过cocopod做出third party framework。
public protocol Session {
func getData(with url: URL, completionHandler: @escaping (Data?, Error?) -> Void)
func getData(with request: URLRequest, completionHandler: @escaping(Data?, Error?) -> Void)
}
extension URLSession: Session {
public func getData(with request: URLRequest, completionHandler: @escaping (Data?, Error?) -> Void) {
self.dataTask(with: request) { (data, _, error) in
completionHandler(data, error)
}.resume()
}
public func getData(with url: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
self.dataTask(with: url) { (data, _, error) in
completionHandler(data, error)
}.resume()
}
}
这里做了一个dependency inversion,这把两个dependency调转了过来。在使用的时候更加方便,同时我们还可以使用其他的session进行代替,如alamofire。
public class APIRequestLoader {
let apiRequest: APIRequestConfigure
let urlSession: Session
public init(apiRequest: APIRequestConfigure, urlSession: Session = URLSession.shared) {
self.apiRequest = apiRequest
self.urlSession = urlSession
}
public func loadRequest<T: Codable>(completionHandler: @escaping ((T?, Error?) -> Void)) {
guard let request = try? apiRequest.makeRequest() else {
completionHandler(nil, NetworkError.invalidRequest)
return
}
urlSession.getData(with: request) { (data, error) in
guard error == nil else {
completionHandler(nil, error)
return
}
guard let data = data else {
completionHandler(nil, NetworkError.noData)
return
}
do {
let decodedData = try JSONDecoder().decode(T.self, from: data)
completionHandler(decodedData, nil)
} catch {
completionHandler(nil, NetworkError.invalidJSONData)
}
}
}
}
其他的和networkframe都一样,需要注意的是把class, function, protocol都需要加public,这样在其他file中就可以共享使用。
最后是在terminal里输入pod init。文件里会生成一个podspec的文件。在这个文件里需要输入官方的信息。
Pod::Spec.new do |spec|
spec.name = "NetworkFramework"
spec.version = "1.2.0"
spec.summary = "Let's use my networkFramework"
spec.description = "NetworkController can be use in swift"
spec.homepage = "https://github.com/grm121616/NetworkFramework"
spec.license = "MIT"
# spec.license = { :type => "MIT", :file => "FILE_LICENSE" }
spec.author = { "Jerry" => "niuBchen@hotmail.com" }
# Or just: spec.author = "Jerry"
spec.authors = { "Jerry" => "niuBchen@hotmail.com" }
# spec.social_media_url = "https://twitter.com/Jerry"
spec.platform = :ios, "13.4"
spec.source = { :git => "https://github.com/grm121616/NetworkFramework.git", :tag => "master" }
spec.source_files = "NetworkFramework/**/*.swift"
spec.swift_version = "5"
end
最后生成,到官网注册,上传。。
https://guides.cocoapods.org/making/getting-setup-with-trunk.html