实现所有实体的基础协议
Entity.swift
import Foundation
protocol DecodableEntity
{
static func parse(data : Data) -> Self?
}
创建一个具体的实体类
UserEntity.swift
import Foundation
struct User
{
let name:String
let hobbies:String
let birthdate:String
init? (data:Data)
{
guard let obj = try?JSONSerialization.jsonObject(with:data,options:[])
as? [String:Any] else {return nil}
guard let name = obj["name"] as?String else {return nil}
guard let hobbies = obj["hobbies"] as?String else {return nil}
guard let birthdate = obj["birthdate"] as?String else {return nil}
self.name = name
self.hobbies = hobbies
self.birthdate = birthdate
}
}
extension User: DecodableEntity
{
static func parse(data : Data) -> Self?
{
return User(data: data)
}
}
创建网络请求类
HttpRequest.swift
import Foundation
import SwiftUI
enum HttpRequestMethod: String
{
case GET
case POST
case PUT
case DELETE
}
protocol HttpRequest
{
var path: String { get }
var method: HttpRequestMethod { get }
var parameter: [String:Any] { get }
associatedtype Response: DecodableEntity
}
extension HttpRequest
{
var host: String { return "http://hdjc8.com" }
}
具体网络请求
User.swift
import Foundation
struct UserHttpResquest: HttpRequest
{
typealias Response = User
var path = "/json/jsonUser.json"
let method: HttpRequestMethod = .GET
let parameter: [String : Any] = [:]
}
网络连接模块创建
HttpClient.swift
import Foundation
protocol Client
{
func send<T:HttpRequest>(_ request: T, handler: @escaping (T.Response?) -> Void)
}
struct HttpClient:Client
{
func send<T:HttpRequest>(_ request: T, handler: @escaping (T.Response?) -> Void)
{
let hostAndPath = request.host.appending(request.path)
var urlRequest = URLRequest(url: URL(string: hostAndPath)!)
urlRequest.httpMethod = request.method.rawValue
let dataTask = URLSession.shared.dataTask(with: urlRequest)
{
data, _, error in
guard let data = data, let entity = T.Response.parse(data: data) else
{
return
}
DispatchQueue.main.async {
handler(entity)
}
}
dataTask.resume()
}
}
界面显示
ContentView.swift
import SwiftUI
struct ContentView: View {
@State var name : String = ""
@State var birthdate : String = ""
@State var hobby : String = ""
var body: some View {
VStack(alignment: .leading){
Text("user.name:\(name)")
Text("user.birthday:\(birthdate)")
Text("user.hobby:\(hobby)")
Button(action: {
HttpClient().send(UserHttpResquest()) { user in
if let user = user {
name = user.name
birthdate = user.birthdate
hobby = user.hobbies
}
}
}, label: {
Text("显示结果")
})
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
结果截图
|