gpt4 book ai didi

swift - 方法无法标记为@objc,因为参数 3 的类型无法在 Objective-C 中表示 - @objc func 中无法识别错误类型?

转载 作者:行者123 更新时间:2023-12-05 05:42:38 26 4
gpt4 key购买 nike

我试图从 Objective-C 类调用此函数,但遇到了问题。我收到错误消息“方法无法标记为@objc,因为参数 3 的类型无法在 Objective-C 中表示”

我假设问题出在“错误”参数上,但不明白问题到底是什么。我读过的所有内容都是关于 Swift 1 或 2 的,但这是在 Swift 5 中。

class NetworkManager {

struct DataModel: Decodable {
let id: String
let carID: String
let ownerId: String
let locationId: String?
let status: String
}

static let shared = NetworkManager()

@objc static func fetchCarWarranty(for carID: String, ownerID: String, completed: @escaping (Result<[DataModel], Error>) -> Void) {

let urlString = APIURL
let session = URLSession.shared
let url = URL(string: urlString)!
var request = URLRequest(url: url)

let task = session.dataTask(with: request) { data, response, error in

if let _ = error {
completed(.failure(error!))
return
}

guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
completed(.failure(error!))
return
}

guard let data = data else {
return
}

do {
let decoder = JSONDecoder()
let dataModel = try decoder.decode([DataModel].self, from: data)
completed(Result.success(dataModel))
} catch {
completed(.failure(error))
}
}
task.resume()
}
}

我考虑过从第二个 Swift 函数调用 fetchCarWarranty,但不确定这是否是一个值得遵循的好习惯。

此外,如果我从 objective-c 文件/类中调用它,我如何从该函数中获取值?

最佳答案

您不能在 Objective-C 中使用 Result,您需要一个像 dataTask(with:completion:) 那样的闭包,带有可选参数,例如 error 表示它不在“错误情况”中:

//Call that one when using Objective-C
@objc static func fetchCarWarranty(for carID: String, ownerID: String, completed: @escaping (([DataModel]?, Error?) -> Void)) {
fetchCarWarranty(for: carID, ownerID: ownerID) { result in
switch result {
case .success(let models):
completed(models, nil)
case .failure(let error):
completed(nil, error)
}
}
}

//Call that one when using Swift
static func fetchCarWarranty(for carID: String, ownerID: String, completed: @escaping (Result<[DataModel], Error>) -> Void) {
// Your method "Swifty" code
}

我为一个带有遗留 Objective-C 代码的应用程序做了这个。最后,您在内部使用 Result 调用 Swifty 方法。所以代码也是一样的。

您还可以为 Objective-C 兼容的闭包:

@objc static func fetchCarWarranty(for carID: String, ownerID: String, success: @escaping (([DataModel]) -> Void), failure: @escaping ((Error) -> Void)) {
fetchCarWarranty(for: carID, ownerID: ownerID { result in
switch result {
case .success(let models):
success(models)
case .failure(let error):
failure(error)
}
}
}

现在,问题是 DataModel 是一个 struct。如果您将其替换为:

// With temp [String] parameter instead of [DataModel]
@objc static func fetchCarWarranty(for carID: String, ownerID: String, completed: @escaping (([String]?, Error?) -> Void)) {
fetchCarWarranty(for: carID, ownerID: ownerID) { result in
switch result {
case .success(let models):
completed(["models"], nil) //Fake output
case .failure(let error):
completed(nil, error)
}
}
}

它有效,因为 String 对 Objective-C 可见。但是你看不到来自 Objective-C 的 Swift 结构。请参阅 documentation 或相关问题之一:

Is there a way to use Swift structs in Objective-C without making them Classes?
How to pass a Swift struct as a parameter to an Objective-C method
How to use Swift struct in Objective-C

关于swift - 方法无法标记为@objc,因为参数 3 的类型无法在 Objective-C 中表示 - @objc func 中无法识别错误类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71993027/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com