我正在使用 MVVM 模式进行服务调用
代码:在视图控制器中
postGenericCallVM
正在调用并且响应也来了,但是print("testing viewmodel data in viewcontroller \(String(describing: postVM.postDataVM?.postCount))")
为零,为什么?
我哪里错了?
struct RequestObject {
var params: [String: Any]? = nil
var method: HTTPMethod
var urlPath: String
var isTokenNeeded: Bool
var isLoaderNeed: Bool = false
var isErrorNeed: Bool = false
var vc: UIViewController?
}
class APINetworkManager2: NSObject {
static let sharedInstance = APINetworkManager2()
fileprivate override init() {
super.init()
}
func serviceCall<T: Decodable>(requestObject: RequestObject, completion: @escaping (Result<APIResponse<T>, Error>) -> Void) {
guard let url = URL(string: requestObject.urlPath) else {
return
}
var urlRequest = URLRequest(url: url)
if requestObject.isTokenNeeded {
let token = "Bearer token" // Replace with your actual token
urlRequest.setValue(token, forHTTPHeaderField: "Authorization")
}
urlRequest.httpMethod = requestObject.method.rawValue
if let params = requestObject.params {
let paramsReq: [String: Any] = ["jsonrpc": "2.0", "params": params]
do {
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: paramsReq)
} catch {
completion(.failure(error))
return
}
}
let task = URLSession.shared.dataTask(with: urlRequest) { data, _, error in
if let data, let string = String(data: data, encoding: .utf8) {
print("debug check \(string)")
}
do {
let response = try JSONDecoder().decode(APIResponse<T>.self, from: data!)
DispatchQueue.main.async {
completion(.success(response))
}
} catch {
DispatchQueue.main.async {
completion(.failure(error))
}
}
}
task.resume()
}
}
这是我的VIewmodel代码在这里打印o/p
result view model: model data coming
class PostViewModel {
var postDataVM: PostGenResult?
func postGenericCallVM(){
let param = ["page_no" : "1"] as? [String:Any]
let requestObject = RequestObject(
params: param,
method: .post,
urlPath: "https://hsfjkhskdn",
isTokenNeeded: true,
isLoaderNeed: true,
isErrorNeed: true
)
APINetworkManager2.sharedInstance.serviceCall(requestObject: requestObject) { (result: Result<APIResponse<PostGenResult>, Error>) in
switch result {
case .success(let response):
self.postDataVM = response.result as? PostGenResult
print("result view model: \(self.postDataVM)")
case .failure(let error):
print("Error decoding JSON: \(error)")
}
}
}
}
o/p:在视图控制器中成功获取响应
结果视图模型:Optional(PracticeCode.PostGenResult(pageCount: 1, perPage: 10, postCount: 5, userReminder: [PracticeCode.UserReminder(id: 17, receiveID: 7, type: "Subscription", message: "Your Subscription is 2 后到期
这是我的视图控制器代码:这里
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
postVM.postGenericCallVM()
print("testing viewmodel data in viewcontroller \(postVM.postDataVM?.postCount)")
}
}
服务呼叫正在呼叫并且响应即将到来,但
testing viewmodel data in viewcontroller
给出零
在视图控制器中测试视图模型数据:nil
确实如此,因为您正在请求
async
任务,并且 postVM.postGenericCallVM()
需要一些时间进行回调。
//Will execute on background thread
APINetworkManager2.sharedInstance.serviceCall
另一方面,这些代码将同步执行。想了解更多详情,可以在这里贴日志。
print("Requesting")
postVM.postGenericCallVM()
print("testing viewmodel data in viewcontroller \(postVM.postDataVM?.postCount)")
然后你会看到打印输出的顺序应该是:
Requesting
testing viewmodel data in viewcontroller \(postVM.postDataVM?.postCount)
result view model: \(self.postDataVM)
如何处理?方法一,在
postGenericCallVM
函数中添加@escaping补全。
func postGenericCallVM(completion: @escaping (() -> Void)) {
...
switch result {
...
}
completion()
}
postVM.postGenericCallVM { [weak self] in
//TODO: Re-check postVM.postDataVM here
}
方法 2,使用
async await
func postGenericCallVM() async {
await withCheckedContinuation { continuetion in
...
APINetworkManager2.sharedInstance.serviceCall {
...
continuetion.resume(returning: ())
}
}
}
Task {
await postVM.postGenericCallVM()
print("\(postVM.postDataVM)")
}