【问题标题】:Alamofire/Swiftyjson - Pass JSON type to Objc protocol delegateAlamofire/Swiftyjson - 将 JSON 类型传递给 Objc 协议委托
【发布时间】:2016-04-12 00:54:54
【问题描述】:

借助 Alamofire 和 Swiftyjson,我可以通过下面的代码向我的服务器发起 HTTP 请求并检索 JSON 对象。

但我无法将来自 Swiftyjson 的自定义类 JSON 作为我的委托方法的参数传递。

我应该怎么做才能修复这个错误?

有错误的代码行:

optional func didReceiveUserInfo(userInfo: JSON) //This the line I get the error

错误: 方法不能是 @objc 协议的成员,因为在 Objective-C 中无法表示参数的类型

这是我正在使用的完整代码:

import UIKit
import Alamofire
import SwiftyJSON

@objc protocol UserModelDelegate {
    optional func didReceiveUserInfo(userInfo: JSON) //This is the line I get the error
}

class UserModel: NSObject, NSURLSessionDelegate {

    // Instantiate the delegate
    var delegate: UserModelDelegate?

    override init() {
        super.init()
    }

    func getUserInfo(token: String) {

        let url = "http://test.app/api/userInfo"

        let headers = [
            "Authorization":"Bearer \(token)",
            "Content-Type": "application/x-www-form-urlencoded"
        ]

        Alamofire.request(.GET, url, headers: headers).responseJSON { response in

            switch response.result {

                case .Success(let data):
                    let json = JSON(data)
                    self.delegate?.didReceiveUserInfo?(json) //This is where I pass the JSON custom class type as an argument

                case .Failure(let error):
                print("Request failed with error: \(error)")
            }
        }
    }
}

【问题讨论】:

    标签: ios json swift swifty-json


    【解决方案1】:

    我可能会让协议要求不是可选的,在这种情况下,这样做是完全有意义的,因为您的代表只有一个要求。您面临的问题是因为您需要 JSON 对象类型与 Objective-C 兼容。您可以通过使该类继承自 Objective-C 类(如 NSObject)来实现。 您应该做的另一件事是在 UserModel 中声明 delegate 属性为 weak 一个,以避免保留循环。

    编辑:如何使 swift 类与 Objective-C 兼容的示例:

    class JSON: NSObject {
    //the code
    }
    

    注意:我之前说过你需要在类中添加一个@objc 属性。这实际上没有必要,除非你想让你的类在 Objective-C 中以其他名称可见。

    有关 Swift 和 Objective-C 互操作性的更多信息read here

    【讨论】:

    • 感谢您的回答。问题是我想有第二个要求,以防请求失败。不确定是否理解您关于使该类从 Objective-C 类继承并添加 @objc 属性的答案。怎么做?抱歉,我对 iOS 开发很陌生。
    • @sbkl 我在回答中添加了更多信息。
    • @sbkl 还请注意,您可以使您的协议要求不是可选的,并使用默认实现以防用户不想通过使用协议扩展来实现它。更多信息在这里:developer.apple.com/library/ios/documentation/Swift/Conceptual/…
    • 我已经检查了文档,但不确定如何在我的情况下实现它。 JSON 类来自 swiftyjson 库。我应该修改这个类以使其符合 Objective-C 吗?
    • 我宁愿使协议与 objetive-c 不兼容,并进行协议扩展以提供您要求的默认实现,以防请求失败。这是我所说的一个例子:stackoverflow.com/a/30744501/1763631
    【解决方案2】:

    代码如下:

    import UIKit
    import Alamofire
    import SwiftyJSON
    
    protocol UserModelDelegate {
    
        func didReceiveUserInfo(userInfo: JSON)
    
    }
    
    class UserModel: NSObject {
    
        // Instantiate the delegate
        var delegate: UserModelDelegate?
    
        override init() {
    
            super.init()
    
        }
    
        func getUserInfo(token: String) {
    
            let url = "http://test.app/api/userInfo"
    
            let headers = [
                "Authorization":"Bearer \(token)",
                "Content-Type": "application/x-www-form-urlencoded"
            ]
    
    
            Alamofire.request(.GET, url, headers: headers).responseJSON { response in
            switch response.result {
                case .Success(let data):
    
                    if (data as? [String:AnyObject])!["error"] == nil {
    
                        let json = JSON(data)                
    
                        self.delegate?.didReceiveUserInfo(json)
    
                    } else {
    
                        self.delegate?.didReceiveUserInfo(nil)
    
                    }
                case .Failure(let error):
                    print("Request failed with error: \(error)")
                }
            }
        }
    }
    

    【讨论】:

    • 我建议您将 var delegate: UserModelDelegate? 更改为 weak var delegate: UserModelDelegate? 以避免保留周期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多