简体   繁体   English

Method cannot be marked @objc because the type of parameter 3 cannot be represented in Objective-C - @objc func 中无法识别错误类型?

[英]Method cannot be marked @objc because the type of the parameter 3 cannot be represented in Objective-C - Error type not recognized in @objc func?

I'm trying to call this function from an objective C class but am running into an issue.我试图从目标 C class 调用这个 function 但遇到了问题。 I get the error "Method cannot be marked @objc because the type of the parameter 3 cannot be represented in Objective-C"我收到错误消息“方法无法标记为@objc,因为参数 3 的类型无法在 Objective-C 中表示”

I'm assuming the issue is with the “Error” parameter but don't understand what the issue is exactly.我假设问题出在“错误”参数上,但不明白问题到底是什么。 Everything I've read has been dealing with Swift 1 or 2 but this is in Swift 5.我读过的所有内容都在处理 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()
    }
}

I've thought of calling fetchCarWarranty from a second Swift function but not sure if this is a good practice to follow or not.我想过从第二个 Swift function 调用fetchCarWarranty但不确定这是否是一个值得遵循的好习惯。

Also, how can I get the value from this function if I'm calling it from an objective-c file/ class?另外,如果我从 objective-c 文件/class 调用它,我如何从这个 function 中获取值?

You can't use Result in Objective-C, you need a closure like the one for dataTask(with:completion:) , with optional parameters like error to indicate it's not in "error case":您不能在 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
}

I did this for an app with legacy Objective-C code.我为具有遗留 Objective-C 代码的应用程序执行此操作。 You call in the end the Swifty method with Result internally.您最后在内部调用带有Result的 Swifty 方法。 so the code does the same.所以代码也是一样的。

You could also for the Objective-C compatible one have to closures:您还可以为 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)
        }
    }
}

Now, the issue is that DataModel is a struct .现在,问题是DataModel是一个struct If you replace that with:如果您将其替换为:

// 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)
        }
    }
}

It works, because String is visible by Objective-C. But you can't see a Swift struct from Objective-C. See the documentation , or one the related questions:它有效,因为String可见字符串。但是您看不到 Objective-C 中的 Swift 结构。请参阅文档,或相关问题之一:

Is there a way to use Swift structs in Objective-C without making them Classes? 有没有办法在 Objective-C 中使用 Swift 结构而不使它们成为类?
How to pass a Swift struct as a parameter to an Objective-C method 如何将 Swift 结构作为参数传递给 Objective-C 方法
How to use Swift struct in Objective-C 如何在 Objective-C 中使用 Swift 结构

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swift 2.0 Method 无法标记@objc 因为参数的类型无法在Objective-C中表示 - Swift 2.0 Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C Swift 5 方法不能标记为@objc 因为参数2的类型不能在Objective-C中表示 - Swift 5 Method cannot be marked @objc because the type of the parameter 2 cannot be represented in Objective-C 方法不能标记为@objc,因为其结果类型无法在Objective-C中表示 - Method cannot be marked @objc because its result type cannot be represented in Objective-C 属性不能被标记为@objc,因为它的类型不能在 Objective-C 中表示 - Property cannot be marked @objc because its type cannot be represented in Objective-C 方法不能是 @objc 协议的成员,因为它的结果类型不能在 Objective-C 中表示 - Method cannot be a member of an @objc protocol because its result type cannot be represented in Objective-C 无法用@objc标记方法,参数无法在Objective-C中表示 - Unable to mark method with @objc, parameter cannot be represented in Objective-C 领域 - 属性不能标记为动态,因为其类型无法在Objective-C中表示 - Realm - Property cannot be marked dynamic because its type cannot be represented in Objective-C 属性无法标记为@NSManaged,因为其类型无法在Objective-C中表示 - Property cannot be marked @NSManaged because its type cannot be represented in Objective-C 抛出方法不能是@objc协议的成员,因为它返回类型'Bool'的值 - Throwing method cannot be a member of an @objc protocol because it returns a value of type 'Bool' Throwing 方法不能是 @objc 要求的实现,因为它返回类型为“Bool”的值 - Throwing method cannot be an implementation of an @objc requirement because it returns a value of type `Bool`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM