Alamofire/Swiftyjson - 将 JSON 类型传递给 Objc 协议委托
Alamofire/Swiftyjson - Pass JSON type to Objc protocol delegate
借助 Alamofire 和 Swiftyjson,使用下面的代码,我能够向我的服务器发起 HTTP 请求并检索 JSON 对象。
但我无法将来自 Swiftyjson 的自定义 class 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)")
}
}
}
}
我可能会让协议要求不是可选的,在这种情况下,这样做是完全有意义的,因为您的代表只有一个要求。您面临的问题是因为您需要 JSON
对象类型 Objective-C 兼容。您可以通过使 class 继承自 Objective-C class(如 NSObject
)来实现。
您应该做的另一件事是将 UserModel
中的 delegate
属性 声明为 weak
,以避免保留循环。
编辑: 如何使 swift class 与 Objective-C 兼容的示例:
class JSON: NSObject {
//the code
}
注意:我之前说过您需要向 class 添加 @objc 属性。这实际上是没有必要的,除非你想让你的 class 在 Objective-C.
中使用其他名称可见
有关 Swift 和 Objective-C 互操作性的更多信息 read here。
这是有效的代码:
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)")
}
}
}
}
借助 Alamofire 和 Swiftyjson,使用下面的代码,我能够向我的服务器发起 HTTP 请求并检索 JSON 对象。
但我无法将来自 Swiftyjson 的自定义 class 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)")
}
}
}
}
我可能会让协议要求不是可选的,在这种情况下,这样做是完全有意义的,因为您的代表只有一个要求。您面临的问题是因为您需要 JSON
对象类型 Objective-C 兼容。您可以通过使 class 继承自 Objective-C class(如 NSObject
)来实现。
您应该做的另一件事是将 UserModel
中的 delegate
属性 声明为 weak
,以避免保留循环。
编辑: 如何使 swift class 与 Objective-C 兼容的示例:
class JSON: NSObject {
//the code
}
注意:我之前说过您需要向 class 添加 @objc 属性。这实际上是没有必要的,除非你想让你的 class 在 Objective-C.
中使用其他名称可见有关 Swift 和 Objective-C 互操作性的更多信息 read here。
这是有效的代码:
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)")
}
}
}
}