BOYYANG/1/blog/美少女 汽车 动漫人物风景桌面壁纸_彼岸壁纸

swift如何通过Alamofire库封装http请求

作者: boyyang
分类: Swift
发布: 2024-09-21 04:40:40
更新: 2025-03-23 12:36:44
浏览: 276

   作为一个垃圾前端的通病,在接触一个新鲜玩意儿的时候,总是想先了解一下整个开发过程中需要的一些东西,先搞个demo出来,至于细节后面慢慢补,管它三七二十一,先上手再说。

   学习swift,swift ui 也算有几天了,现在至少清楚后续学习的大致方向了。学习swift当然swift语法是必要的,一些基本概念还是要了解的。有过前端js,ts后端go,python语言的学习后,swift的一些类,结构体上手也就轻松了许多。

    swift就类似于前端的js,后端的go,swift ui 顾名思义就是ui了,和前端的通过css,html等构建页面有一定区别,swift ui 有很多系统组件,通过这些组件像搭积木一样来实现各种页面布局等等。只是说每个ui组件有非常多的属性,扩展,方法等等。

   有了swift,以及swift ui的一些了解后,那其实就是数据层面的一些东西了,如何请求后端数据,如何将其渲染到页面,页面如何交互。有了这些也就七七八八了,后续也就是如何打包上架了。

   为了一些定制化的请求,大家懂的都懂,后端返回的数据接口一般来说都是有统一规定的,至于http的那些状态码,国内应该很少用这玩意儿,统统200,统统200哈。

   简单对Alamofire进行二次封装还是有必要的,不然怎么装逼呢。

封装APIService (APIService.swift)

import Foundation
import Alamofire

public struct Response<T: Decodable> : Decodable{
    var code: Int
    var msg: String
    var data: T
}

public struct APIService {
    let baseURL = URL(string: "http://localhost:9527")!
    
    public static let shared = APIService()
    
    public func GET<T: Decodable>(endpoint: Endpoint, params: [String: Any]?, of: T.Type = T.self, completionHandler: @escaping (Result<T, Error>) -> Void) {
        
        let queryURL = baseURL.appendingPathComponent(endpoint.path())
        
        AF.request(queryURL, method: .get, parameters: params).responseDecodable(of: Response<T>.self){ res in
            print(res.result)
            switch res.result{
            case let .success(result):
                completionHandler(.success(result.data))
            case let .failure(error):
                completionHandler(.failure(error))
            }
        }
    }
}

统一管理API接口(API.swift)


public enum Endpoint{
    
    case imageList

    func path() -> String {
        switch self {
        case .imageList:
            return "/file/list/public"
        }
    }
    
}

使用(imageData.swift)

import Foundation

struct ImageList: Decodable {
    var count: Int
    var infos: [ImageListInfo]
}

struct ImageListInfo: Decodable, Hashable {
    var id: Int
    var file_path: String
    var file_name: String
    var status: Bool
    var w: Int
    var h: Int
}

class ImageModel: ObservableObject  {
    
    @Published var list: [ImageListInfo] = []
    @Published var page: Int = 1
    @Published var limit: Int = 10
    
    init(){
        self.getList()
        
    }
    
    
    func getList(){
        
        APIService.shared.GET(
            endpoint: .imageList,
            params: [
                "page": self.page,
                "limit": self.list,
                "id": "1"
            ],
            of: ImageList.self
        ){res in
            switch res{
            case let .success(data):
                DispatchQueue.main.async{
                    self.list = data.infos
                }
            case let .failure(err):
                print(err)
            }
        }
    }
    
}

渲染UI视图(Home.swift)

//
//  Home.swift
//  Unsplash
//
//  Created by boyyang on 2024/9/15.
//

import SwiftUI

struct Home: View {
    
    @State private var gridColumns = Array(repeating: GridItem(.flexible()), count: 3)
    @ObservedObject var imgList: ImageModel = ImageModel()
    
    
    var body: some View {
    
        LazyVGrid(columns: gridColumns) {
            
            ForEach(imgList.list, id: \.id){image in
                
                NavigationLink(destination: ImagePreview()) {
                    Rectangle()
                        .overlay {
                            AsyncImage(url:URL(string:"https://minio.boyyang.cn/boyyang/\(image.file_path)")){image in
                                image.image?.resizable()
                                    .aspectRatio(contentMode: .fill)
                                
                            }
                        }
                }
                .cornerRadius(8.0)
                .aspectRatio(1, contentMode: .fit)
            }
        }
    }
    
}

#Preview {
    Home()
}


#swift
#swift ui