完善Swift API GET函数

编程入门 行业动态 更新时间:2024-10-27 05:21:54
本文介绍了完善Swift API GET函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在做一个练习项目,其中iOS应用程序从jsonplaceholder.typicode打印/posts列表,并且当用户选择一个时,将加载详细的视图控制器,并显示有关该帖子的更多信息(作者和评论数).

I'm working on a practice project where the iOS app prints a list of /posts from jsonplaceholder.typicode, and when the user selects one a detailed view controller is loaded and further information about that post is displayed (author and number of comments).

我对三个不同的端点分别进行了三个GET请求,因为它们每个都需要不同的返回类型和不同的参数(或根本不需要).

I've made three separate GET requests for the three different endpoints, as each of them require different return types and different parameters (or none at all).

我想尽可能多地使用这三个代码之间的共同点,并将其放在一个新的函数中以整理类,但是我觉得我可以做更多的事情.

I wanted to take as much code as possible that's in common between the three and put it in a new function to tidy up the class, but I feel as though I could do a lot more.

是否有一种方法可以使这些Structs的返回类型更通用,并且可以通过Switch来确定将json响应映射到哪个类型?任何指导将不胜感激.

Is there a way to make the return type of these Structs more generic, with a Switch to determine which to map the json response to? Any guidance would be greatly appreciated.

import UIKit struct Post: Codable { let userId: Int let id: Int let title: String let body: String } struct Author: Codable { let name: String } struct Comment: Codable { let postId: Int let id: Int let name: String let email: String let body: String } enum Result<Value> { case success(Value) case failure(Error) } class APIManager { static let sharedInstance = APIManager() func getUrl(for path: String) -> URL { var urlComponents = URLComponents() urlComponents.scheme = "https" urlComponents.host = "jsonplaceholder.typicode" urlComponents.path = path guard let url = urlComponents.url else { fatalError("Could not create URL from components") } return url } func getPosts(completion: ((Result<[Post]>) -> Void)?) { let url = getUrl(for: "/posts") var request = URLRequest(url: url) request.httpMethod = "GET" let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let task = session.dataTask(with: request) { (responseData, response, responseError) in DispatchQueue.main.async { if let error = responseError { completion?(.failure(error)) } else if let jsonData = responseData { let decoder = JSONDecoder() do { let posts = try decoder.decode([Post].self, from: jsonData) completion?(.success(posts)) } catch { completion?(.failure(error)) } } else { let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Data was not retrieved from request"]) as Error completion?(.failure(error)) } } } task.resume() } func getAuthor(for userId: Int, completion: ((Result<String>) -> Void)?) { let url = getUrl(for: "/users/\(userId)") var request = URLRequest(url: url) request.httpMethod = "GET" let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let task = session.dataTask(with: request) { (responseData, response, responseError) in DispatchQueue.main.async { if let error = responseError { completion?(.failure(error)) } else if let jsonData = responseData { let decoder = JSONDecoder() do { let author = try decoder.decode(Author.self, from: jsonData) completion?(.success(author.name)) } catch { completion?(.failure(error)) } } else { let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Data was not retrieved from request"]) as Error completion?(.failure(error)) } } } task.resume() } func getComments(for postId: Int, completion: ((Result<[Comment]>) -> Void)?) { let url = getUrl(for: "/posts/\(postId)/comments") var request = URLRequest(url: url) request.httpMethod = "GET" let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let task = session.dataTask(with: request) { (responseData, response, responseError) in DispatchQueue.main.async { if let error = responseError { completion?(.failure(error)) } else if let jsonData = responseData { let decoder = JSONDecoder() do { let comments = try decoder.decode([Comment].self, from: jsonData) completion?(.success(comments)) } catch { completion?(.failure(error)) } } else { let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Data was not retrieved from request"]) as Error completion?(.failure(error)) } } } task.resume() } }

推荐答案

只需利用通用的Result类型:

class APIManager { static let sharedInstance = APIManager() private func getUrl(for path: String) -> URL { var urlComponents = URLComponents() urlComponents.scheme = "https" urlComponents.host = "jsonplaceholder.typicode" urlComponents.path = path guard let url = urlComponents.url else { fatalError("Could not create URL from components") } return url } private func postsURL() -> URL { return getUrl(for: "/posts") } private func usersURL(for userId : Int) -> URL { return getUrl(for: "/users/\(userId)") } private func commentsURL(for postId : Int) -> URL { return getUrl(for: "/posts/\(postId)/comments") } func getPosts(completion: @escaping (Result<[Post]>) -> Void) { getInfo(for: postsURL(), completion: completion) } func getAuthor(for userId: Int, completion: @escaping (Result<Author>) -> Void) { getInfo(for: usersURL(for: userId), completion: completion) } func getComments(for postId: Int, completion: @escaping (Result<[Comment]>) -> Void) { getInfo(for: commentsURL(for: postId), completion: completion) } private func getInfo<T: Decodable>(for url : URL, completion: @escaping (Result<T>) -> Void) { let task = URLSession.shared.dataTask(with: url) { (data, _, error) in DispatchQueue.main.async { if let error = error { completion(.failure(error)) } else { let decoder = JSONDecoder() do { let comments = try decoder.decode(T.self, from: data!) completion(.success(comments)) } catch { completion(.failure(error)) } } } } task.resume() } }

并使用它

let manager = APIManager.sharedInstance manager.getAuthor(for: 1) { result in switch result { case .success(let author) : print(author.name) case .failure(let error) : print(error) } }

更多推荐

完善Swift API GET函数

本文发布于:2023-11-23 09:00:11,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1620852.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   Swift   API

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!