Swift 网络请求工具类
Posted 北冥鱼_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift 网络请求工具类相关的知识,希望对你有一定的参考价值。
一、首先定义 API 类:
import Foundation
import UIKit
// 声明 APIDelegate 回调方法
protocol APIDelegate: AnyObject
func loginFailed(error: Error)
func loginSucceeded(userId: String)
func announcementsFailed(error: Error)
func announcementsLoaded(announcements: [Announcement])
func orgLoaded(org: [Employee])
func orgFailed(error: Error)
func eventsLoaded(events: [Event])
func eventsFailed(error: Error)
func productsLoaded(products: [Product])
func productsFailed(error: Error)
func purchasesLoaded(purchases: [PurchaseOrder])
func purchasesFailed(error: Error)
func userLoaded(user: UserInfo)
func userFailed(error: Error)
class API
// 声明 server 地址与端口, 如 "http://localhost:8080/"
let server = AppDelegate.configuration.server
let session: URLSession
weak var delegate: APIDelegate?
var token: Token?
init()
session = URLSession(configuration: .default)
func login(username: String, password: String)
let eventsEndpoint = server + "api/users/login"
let eventsURL = URL(string: eventsEndpoint)!
var urlRequest = URLRequest(url: eventsURL)
urlRequest.httpMethod = "POST"
let data = "\\(username):\\(password)".data(using: .utf8)!
let basic = "Basic \\(data.base64EncodedString())"
urlRequest.addValue(basic, forHTTPHeaderField: "Authorization")
let task = session.dataTask(with: urlRequest) data, _, error in
guard let data = data else
if error != nil
DispatchQueue.main.async
self.delegate?.loginFailed(error: error!)
return
let decoder = JSONDecoder()
if let token = try? decoder.decode(Token.self, from: data)
self.handleToken(token: token)
else
do
let error = try decoder.decode(APIError.self, from: data)
DispatchQueue.main.async
self.delegate?.loginFailed(error: error)
catch
DispatchQueue.main.async
self.delegate?.loginFailed(error: error)
task.resume()
func handleToken(token: Token)
self.token = token
Logger.logDebug("user \\(token.user.id)")
DispatchQueue.main.async
self.delegate?.loginSucceeded(userId: token.user.id.uuidString)
func logout()
token = nil
delegate = nil
UIApplication.appDelegate.showLogin()
//swiftlint:disable identifier_name
func submitPO(po: PurchaseOrder) throws
let url = URL(string: server + "api/" + "purchases")!
var request = URLRequest(url: url)
if let token = token?.token
let bearer = "Bearer \\(token)"
request.addValue(bearer, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let coder = JSONEncoder()
coder.dateEncodingStrategy = .iso8601
let data = try coder.encode(po)
request.httpBody = data
let task = loadTask(
request: request,
success: self.poSuccess,
failure: self.delegate?.purchasesFailed(error:))
task.resume()
private func poSuccess(po: PurchaseOrder)
getPurchases()
private func request(_ endpoint: String) -> URLRequest
let url = URL(string: server + "api/" + endpoint)!
var request = URLRequest(url: url)
if let token = token?.token
let bearer = "Bearer \\(token)"
request.addValue(bearer, forHTTPHeaderField: "Authorization")
return request
func loadTask<T: Decodable>(
request: URLRequest,
success: ((T) -> Void)?,
failure: ((Error) -> Void)?
) -> URLSessionTask
return session.dataTask(with: request) data, _, error in
guard let data = data else
if error != nil
DispatchQueue.main.async
failure?(error!)
return
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
if let items = try? decoder.decode(T.self, from: data)
DispatchQueue.main.async
success?(items)
else
do
let error = try decoder.decode(APIError.self, from: data)
DispatchQueue.main.async
failure?(error)
catch
DispatchQueue.main.async
failure?(error)
func getAnnouncements()
let req = request("announcements")
let task = loadTask(
request: req,
success: self.delegate?.announcementsLoaded(announcements:),
failure: self.delegate?.announcementsFailed(error:))
task.resume()
func getOrgChart()
let req = request("employees")
let task = loadTask(
request: req,
success: self.delegate?.orgLoaded(org:),
failure: self.delegate?.orgFailed(error:))
task.resume()
func getEvents()
let req = request("events")
let task = loadTask(
request: req,
success: self.delegate?.eventsLoaded(events:),
failure: self.delegate?.eventsFailed(error:))
task.resume()
func getProducts()
let req = request("products")
let task = loadTask(
request: req,
success: self.delegate?.productsLoaded(products:),
failure: self.delegate?.productsFailed(error:))
task.resume()
func getPurchases()
let req = request("purchases")
let task = loadTask(
request: req,
success: self.delegate?.purchasesLoaded(purchases:),
failure: self.delegate?.purchasesFailed(error:))
task.resume()
func getUserInfo(userID: String)
let req = request("users/\\(userID)")
let task = loadTask(
request: req,
success: self.delegate?.userLoaded(user:),
failure: self.delegate?.userFailed(error:))
task.resume()
二、使用方法:
- 在 AppDelegate 声明
// 声明变量
static var configuration: Configuration!
var api: API!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
// 初始化变量
AppDelegate.configuration = Configuration.load()
api = API()
return true
- 其中 Configuration:
import Foundation
struct Configuration: Codable
struct UI: Codable
struct Button: Codable
let cornerRadius: Double
let borderWidth: Double
let button: Button
struct BusinessRules: Codable
let maxPOExpense: Double
let server: String
let debug: Bool
let ui: UI
let rules: BusinessRules
// MARK: - Local Settings
extension Configuration
var firstDayOfWeek: DaysOfWeek
if UserDefaults.standard.object(forKey: "firstDayOfWeek") != nil
return DaysOfWeek(rawValue: UserDefaults.standard.integer(forKey: "firstDayOfWeek"))!
return .sunday
extension Configuration
//swiftlint:disable force_try
static func load() -> Configuration
let url = Bundle.main.url(forResource: "configuration", withExtension: "json")!
let data = try! Data(contentsOf: url)
let decoder = JSONDecoder()
return try! decoder.decode(Configuration.self, from: data)
- 在 controller 中使用:
var api: API return (UIApplication.shared.delegate as! AppDelegate).api
let skin: Skin = .login
override func viewDidLoad()
super.viewDidLoad()
api.delegate = self
Styler.shared.style(background: view, buttons: [signInButton], with: skin)
以上是关于Swift 网络请求工具类的主要内容,如果未能解决你的问题,请参考以下文章