最近又把 RxSwift复习了下,写了一个小 Demo 主要是构建网路模块,Demo 我已经上传,在文章末尾处可以下载,接下来就一步步去构建:
第一步(数据层):使用 ObjectMapper 构建 Model
//
// LoginModel.swift
// RxSwiftDemo01
//
// Created by macOSJack on 2024/11/5.
//
import Foundation
import ObjectMapper
class LoginModel:Mappable{
var username:String?
var password:String?
required init?(map: ObjectMapper.Map) {}
func mapping(map: ObjectMapper.Map) {
username<-map["username"]
password<-map["password"]
}
}
(网络层)第二步:接口, IP 请求配置
//
// api.swift
// RxSwiftDemo01
//
// Created by macOSJack on 2024/11/5.
//
import Foundation
import Moya
let ApiProvider = Moya.MoyaProvider<APi>(plugins: [RequestLoadingPlugin()])
//
enum APi{
case login
case changepassword
}
let apiTask = ApiTask()
extension APi:TargetType{
var baseURL: URL {
return URL.init(string: "http://localhost:8080/SpringMVC")!
}
var path: String {
switch self{
case .login:
return "/user/login"
case .changepassword:
return "/changePsd"
default:
return "/"
break;
}
}
var method: Moya.Method {
switch self{
case .login,.changepassword:
return .post
default:
return .get
}
}
var task: Moya.Task {
switch self{
case .login:
return apiTask.login(username: "jack", password: "123")
case.changepassword:
return apiTask.changePsd(oldPsd: "123", newPsd: "456")
}
}
var headers: [String : String]? {
return ["Content-Type":"application/x-www-form-urlencoded"]
}
var sampleData: Data{
return "{username:'sdsds',password:'8246343'}".data(using: String.Encoding.utf8)!
}
}
第三步:网络请求任务
//
// Task.swift
// RxSwiftDemo01
//
// Created by macOSJack on 2024/11/5.
//
import Foundation
import Moya
class ApiTask:NSObject{
func login(username:String,password:String) -> Moya.Task {
return Moya.Task
.requestParameters(parameters: ["username":username,"password":password], encoding: URLEncoding.default)
// .requestData(jsonToData(jsonDic: ["username":username,"password":password], target: APi.login)!)
}
func changePsd(oldPsd:String,newPsd:String) -> Moya.Task {
Moya.Task.requestData(jsonToData(jsonDic: ["oldPsd":oldPsd,"newPsd":newPsd], target: APi.changepassword)!)
}
private func jsonToData(jsonDic:Dictionary<String,Any>,target:APi)->Data?{
if !JSONSerialization.isValidJSONObject(jsonDic){
print("it's not json!")
}
let data = try? JSONSerialization.data(withJSONObject: jsonDic, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonStr = String(data: data!, encoding: String.Encoding.utf8)
print("\(target)--->json:\(jsonStr)")
return data
}
private func jsonToString(jsonDic:Dictionary<String,Any>,target:APi)->String?{
if !JSONSerialization.isValidJSONObject(jsonDic){
print("it's not json!")
}
let data = try? JSONSerialization.data(withJSONObject: jsonDic, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonStr = String(data: data!, encoding: String.Encoding.utf8)
print("\(target)--->json:\(jsonStr)")
return jsonStr
}
}
第四步:网络请求组件
//
// RequestuserLoadingPlugin.swift
// RxSwiftDemo01
//
// Created by macOSJack on 2024/11/5.
//
import Foundation
import Moya
import Result
import ObjectMapper
import RxSwift
import RxCocoa
class RequestLoadingPlugin:PluginType{
func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
var myRequest = request
myRequest.timeoutInterval = 20.0
return myRequest
}
func willSend(_ request: RequestType, target: TargetType) {
print("开始请求\(request)")
}
func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
print("结束请求\(target)")
switch result{
case .success(let response):
print(String(data: response.data, encoding: String.Encoding.utf8))
break
case .failure(let moyaErr):
print("请求失败:\(moyaErr.localizedDescription)")
break
}
}
}
extension Observable{
func mapObject<T:Mappable>(type:T.Type) -> Observable<T> {
return self.map{
response in
guard let dic = response as? [String:Any] else
{
throw RxSwiftMoyaError.ParseJsonError
}
return Mapper<T>().map(JSON: dic["data"] as! [String:Any])!
}
}
func mapArray<T:Mappable>(type:T.Type) -> Observable<[T]> {
return self.map{
response in
guard let array = response as? [Any] else{
throw RxSwiftMoyaError.OtherError
}
guard let dicArr = array as? [[String:Any]] else{
throw RxSwiftMoyaError.ParseJsonError
}
return Mapper<T>().mapArray(JSONArray: dicArr)
}
}
}
enum RxSwiftMoyaError:String{
case ParseJsonError
case OtherError
}
extension RxSwiftMoyaError:Swift.Error{}
第五步:Moya+RxSwift 构建 ViewModel 层
//
// LoginViewModel.swift
// RxSwiftDemo01
//
// Created by macOSJack on 2024/11/5.
//
import Foundation
import Moya
import RxSwift
class LoginViewModel:NSObject{
func login() -> Observable<LoginModel> {
return ApiProvider.rx.request(.login).filterSuccessfulStatusCodes().asObservable().mapJSON().mapObject(type: LoginModel.self)
}
}
到此为止,一个简易的网络请求层构建好了.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。