Alamofire/Swiftyjson - 将 JSON 类型传递给 Objc 协议委托

Posted

技术标签:

【中文标题】Alamofire/Swiftyjson - 将 JSON 类型传递给 Objc 协议委托【英文标题】:Alamofire/Swiftyjson - Pass JSON type to Objc protocol delegate 【发布时间】: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)")
            
        
    

【问题讨论】:

【参考方案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 不兼容,并进行协议扩展以提供您要求的默认实现,以防请求失败。这是我所说的一个例子:***.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? 以避免保留周期。

以上是关于Alamofire/Swiftyjson - 将 JSON 类型传递给 Objc 协议委托的主要内容,如果未能解决你的问题,请参考以下文章

无法解析数据 JSON alamofire SwiftyJSON

使用 Alamofire + SwiftyJSON 定义全局变量

swift、Alamofire、SwiftyJSON:如何解析 arrayObject

在 Swift 中将 Alamofire 结果解析为对象(使用:Alamofire、SwiftyJSON 和 ObjectMapper)

数据未使用 Alamofire + SwiftyJSON 加载到 UITableView

使用 Alamofire + SwiftyJSON 获取 JSON 数组