day01-初始搭建

283 阅读2分钟

前言:一直想尝试做个mac端的东西,今天有机会了,在B站学习的音乐APP全栈,于是就想到了后台如果用mac端做如何,边学习边搭建

1、技术选择,采用Swift+MVVM+RxSwift结构搭建整个项目

Swift:这个当代苹果端开发,不会就废废了。

MVVM:一直在用,但一直不用不到精髓,多多练习,欢迎指教。

RxSwift:基本上Swift的MVVM大概率离不开RxSwift。

2、UI搭建选择

这个我单独拿出来说是因为,SwiftUI我真不会,只好使用storyboard搭建。

3、项目初始化

注意:在使用Xcode 14版本时,通过cocoapods安装第三方框架要把cocoapods更新到最新的版本,ruby环境也更新到最新(别问我为什么这么做,全是眼泪)

引入的库

image.png 这里使用HandyJSON进行解析,这个是我用过最傻瓜式的解析方式,考虑的最少,别的框架我也用过,但是如果不确定服务端返回到底有啥东西,就可能各种崩溃。HandyJSON就可以少操心。

4、上代码

先展示一下基本的项目结构

image.png

Network层

BaseAPIProtocol.swift

import Foundation
import Moya

protocol BaseAPIProtocol: TargetType {
    var timeout: Double { get }
    
}

extension BaseAPIProtocol {
    var baseURL: URL {
        return URL(string: NetworkConfig.baseURL)!
    }
    
    var method: Moya.Method {
        return .post
    }
    
    var headers: [String : String]? {
        return ["":""]
    }
    
    var validationType: ValidationType {
        return .successCodes
    }
    
    var timeout: Double {
        return 30.0
    }
}

Network层

BaseAPIProtocol.swift
import Foundation
import Moya

struct NetworkConfig {
    static var baseURL: String {
        return "http://localhost:88/"
    }
    
    static let contentType = "application/json"
}

Api.swift

import Foundation
import Moya
import Alamofire

enum API {
    case siginIn(username: String, password: String)
}

extension API: BaseAPIProtocol {
    var path: String {
        switch self {
        case .siginIn:
            return "users/"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .siginIn:
            return .get
        }
    }
    
    var task: Moya.Task {
        var parameters: [String : Any] = [:]
        switch self {
        case .siginIn(let username, let password):
            parameters = ["username": username, "password": password] as [String : Any]
            return .requestParameters(parameters: parameters, encoding: URLEncoding.default)
        }
        
    }
}

登录部分

我的登录部分叫Sigin in,看到很多国际大厂这么叫,所以我打算国际化一点,嘿嘿。

先搭起一个简单的功能模块,测试一下能否请求到之前简单搭起后端的功能。

UserinfoModel.swift

import Foundation
import HandyJSON

struct UserinfoModel: HandyJSON {
    var id: String = ""
    var username: String = ""
    var nickname: String = ""
    var gender: String = ""
    var email: String = ""
    var phone: String = ""
}

SigninViewModel.swift

import Foundation
import Moya
import RxSwift
import RxCocoa

// 先订阅,再发送

class SigininViewModel: NSObject {
    let signinSubject = PublishSubject<UserinfoModel>()
    let disbg = DisposeBag()
    
    lazy var userInfo: UserinfoModel = UserinfoModel()
    
    func getUserInfo(username: String, password: String) -> Void {
        let signinProvider = MoyaProvider<API>()
        signinProvider.rx.request(.siginIn(username: username, password: password)).subscribe { [self] resopnse in
            print("----响应为\(resopnse)--\(try! resopnse.mapString())")
            if let userinfo: UserinfoModel = UserinfoModel.deserialize(from: try! resopnse.mapString()) {
                signinSubject.onNext(userinfo)
            } else {
                print("有空值\(resopnse)--\(try! resopnse.mapString())")
            }
            
        } onFailure: { error in
            print(error)
        }
        
    onDisposed: {
        
    }.disposed(by: disbg)
    }
}

SigninViewController.swift

import Cocoa
import RxSwift

class SigninViewController: NSViewController {
    
    lazy var signinViewModel: SigininViewModel = SigininViewModel()
    let disbg: DisposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        signIn(username: "a", password: "b")
        // Do view setup here.
    }
    
    // 先订阅,再发送,rx使用要记牢
    
    func signIn(username: String, password: String) -> Void {
        signinViewModel.signinSubject.subscribe { [weak self] userInfo in
            self?.signinViewModel.userInfo = userInfo
        }.disposed(by: disbg)
        signinViewModel.getUserInfo(username: username, password: password)
    }
    
    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}

5、调试

调试一下看看是否成功

啊这。。。

搜素了一下(还得是谷歌)确定是沙盒问题,好像不是Xcode 14的问题,之前的版本好像也有这个问题,但是我没碰到。

我勾选了这两个就OK了,可以请求到东西了