Typealias/模型设置类型别名, Escaping/转义闭包, Codable/模型可编码协议 的使用

1. Typealias 模型设置类型别名

  1.1 实现

struct MovieModel {
    let title: String
    let director: String
    let count: Int
}

// 赋值 Model
typealias TVModel = MovieModel

// 设置类型别名
struct TypealiasBootcamp: View {
    //@State var item = MovieModel(title: "Title", director: "Joe", count: 5)
    @State var item = TVModel(title: "TV title", director: "Emmily", count: 10)
    var body: some View {
        VStack {
            Text(item.title)
            Text(item.director)
            Text("\(item.count)")
        }
    }
}

2. Escaping 定义转义闭包

  2.1 实现

/// ViewModel 中转义闭包操作
class EscapingViewModel: ObservableObject{
    @Published var text: String = "Hello"
    
    func getData(){
        // [weak self] 表示弱引用
        //downloadData3 { [weak self] data in
        //    self?.text = data
        //}
        
        //downloadData4 { [weak self] result in
        //    self?.text = result.data
        //}
        
        downloadData5 { [weak self] downloadCompletion in
            self?.text =  downloadCompletion.data
        }
    }
    
    // 下载数据
    func downloadData() -> String{
        return "New Data"
    }
    
    // 下载数据 2
    func downloadData2(completionHandler:(_ data: String) -> ()){
        completionHandler("New data!!!")
    }
    
    // 下载数据 3
    func downloadData3(completionHandler:@escaping (_ data: String) -> ()){
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            completionHandler("New data!")
        }
    }
    
    // 下载数据 4
    func downloadData4(completionHandler:@escaping (DownloadResult) -> ()){
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            let downloadResult = DownloadResult(data: "New data!")
            completionHandler(downloadResult)
        }
    }
    
    // 下载数据 5
    func downloadData5(completionHandler:@escaping DownloadCompletion){
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            let downloadResult = DownloadResult(data: "New data!")
            completionHandler(downloadResult)
        }
    }
}

// 下载返回结果
struct DownloadResult {
    let data: String
}

// 定义类型
typealias DownloadCompletion = (DownloadResult) -> ()
    
/// 转义闭包
struct EscapingBootcamp: View {
    @StateObject var viewModel = EscapingViewModel()
    var body: some View {
        Text(viewModel.text)
            .font(.largeTitle)
            .fontWeight(.semibold)
            .foregroundColor(.blue)
            .onTapGesture {
                viewModel.getData()
            }
    }
}

3. Codable 对模型进行可编码协议

  3.1 实现

// Codable = Decodable + Encodable
// 可编码 = 可解码 + 可编码

// Decodable, Encodable = Codable
// Decodable: 表示可以用数据初始化客户模型,并且将数据解码为模型
struct CustomerModel: Identifiable, Codable{
    let id: String
    let name: String
    let points: Int
    let isPremium: Bool
    
    /*init(id: String, name: String, points: Int, isPremium: Bool){
        self.id = id
        self.name = name
        self.points = points
        self.isPremium = isPremium
    }
    
    enum CodingKeys: String, CodingKey{
        case id
        case name
        case points
        case isPremium
    }

    // 解码数据
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(String.self, forKey: .id)
        self.name = try container.decode(String.self, forKey: .name)
        self.points = try container.decode(Int.self, forKey: .points)
        self.isPremium = try container.decode(Bool.self, forKey: .isPremium)
    }
    
    // 编码数据
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(name, forKey: .name)
        try container.encode(points, forKey: .points)
        try container.encode(isPremium, forKey: .isPremium)
    }*/
}

class CodableViewModel: ObservableObject{
    @Published var customer: CustomerModel? = nil
    
    init() {
        getData()
    }
    
    func getData(){
        // 获取 JSON 数据
        guard let data = getJSONData() else { return }
        
        // 解码数据
        self.customer = try? JSONDecoder().decode(CustomerModel.self, from: data)
        
        /*do{
            self.customer = try JSONDecoder().decode(CustomerModel.self, from: data)
        } catch let error{
           print("Error decoding. \(error)")
        }*/
        
        /*if
         let localData = try? JSONSerialization.jsonObject(with: data,options: []),
         let dictionary = localData as? [String : Any],
         let id = dictionary["id"] as? String,
         let name = dictionary["name"] as? String,
         let point = dictionary["points"] as? Int,
         let isPremium = dictionary["isPremium"] as? Bool{
         
         let newCustomer = CustomerModel(id: id, name: name, points: point, isPremium: isPremium)
         customer = newCustomer
         }*/
    }
    
    func getJSONData() -> Data? {
        // 模拟网络 JSON 数据
        let customer = CustomerModel(id: "007", name: "Emily", points: 100, isPremium: false)
        let jsonData = try? JSONEncoder().encode(customer)
        /*let dictionary:[String : Any] = [
            "id":    "12345" ,
            "name":  "Joe",
            "points":  5 ,
            "isPremium": true
        ]
        // JSON 序列化
        let jsonData = try? JSONSerialization.data(withJSONObject: dictionary, options: [])*/
        return jsonData
    }
}

// 可编码协议
struct CodableBootcamp: View {
    @StateObject var viewModel = CodableViewModel()
    
    var body: some View {
        VStack(spacing: 20) {
            if let customer = viewModel.customer{
                Text(customer.id)
                Text(customer.name)
                Text("\(customer.points)")
                Text(customer.isPremium.description)
            }
        }
        .font(.title)
    }
}

  3.2 效果图:

猜你喜欢

转载自blog.csdn.net/u011193452/article/details/133377339