如何使用 AppAuth 库使我的 API 调用更可重用?

问题描述 投票:0回答:1

为了熟悉 SwiftUI 应用程序开发,我正在使用 AppAuth 库 制作一个具有登录功能的简单应用程序。我已经可以使用基本的登录和注销功能,并且可以使用收到的访问令牌发出请求。目前,所有请求都是从单个类发出的。对于真正的应用程序,我想拆分请求并将它们放在不同的文件中。这就是我在用户登录后发出基本 API 请求以获取用户数据的方式:

class AuthStore: ObservableObject {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    private var authState : OIDAuthState?
    
    @Published var isAuthenticated = false

    func getUserData() {
        let userEndpoint = URL(string: "https://example.com/my-api/user/1")!
        
        self.authState?.performAction() { accessToken, idToken, error in
            if error != nil {
                print("Error fetching fresh tokens: \(error?.localizedDescription ?? "Unknown error")")
                return
            }
            
            guard let accessToken = accessToken else {
                return
            }
            
            // Add Bearer token to request
            var urlRequest = URLRequest(url: userEndpoint)
            urlRequest.allHTTPHeaderFields = ["Authorization": "Bearer \(accessToken)"]
            
            let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
                
                print("Performing patron information request")
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                    return
                }
                
                if let data = data {
                    do {
                        let decodedData = try JSONDecoder().decode(User.self, from: data)
                        self.patron = decodedData
                    } catch {
                        print("JSON Decoding error: \(error.localizedDescription)")
                    }
                }
            }
            
            task.resume()
    }
}

如何使需要访问令牌的 API 请求更加通用和可重用?我想到的解决方案之一是使用泛型,如下所示:

func getData(url: URL) -> T {
        self.authState?.performAction() { accessToken, idToken, error in
            if error != nil {
                print("Error fetching fresh tokens: \(error?.localizedDescription ?? "Unknown error")")
                return
            }
            
            guard let accessToken = accessToken else {
                return
            }
            
            // Add Bearer token to request
            var urlRequest = URLRequest(url: url)
            urlRequest.allHTTPHeaderFields = ["Authorization": "Bearer \(accessToken)"]
            
            let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
                
                print("Performing patron information request")
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                    return
                }
                
                if let data = data {
                    do {
                        let decodedData = try JSONDecoder().decode(T.self, from: data)
                        self.patron = decodedData
                    } catch {
                        print("JSON Decoding error: \(error.localizedDescription)")
                    }
                }
            }
            
            task.resume()
    }
}

或者向

AuthStore
类添加一个方法会更好,该方法返回一个新的访问令牌,然后可以在其他地方使用该令牌来发出请求?

ios swiftui appauth
1个回答
0
投票

如果您没有使用外部库的限制,那么我建议使用Alamofire,它是 GitHub 上用于 Apple 应用程序开发的最佳网络库。此外,它支持所有平台,您可以将其与 CocoaPods、SPM 或 Carthage 集成到您的应用程序中,它支持所有依赖项管理器。

为了使您的代码更具可重用性,您可以遵循这篇文章,它向 Alamofire 请求添加了一个层,它可能是您可以为应用程序编写的最干净、最有组织的网络层。

© www.soinside.com 2019 - 2024. All rights reserved.