MVVM 模式服务调用响应未快速传入 Viewcontroller 中

问题描述 投票:0回答:1

我正在使用 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

json swift web-services mvvm
1个回答
0
投票

确实如此,因为您正在请求

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)")
}
© www.soinside.com 2019 - 2024. All rights reserved.