swift 方法接受参数如果符合协议
swift method accept parameter if conform a protocol
我有一个名为 WebServiceProtocol
的协议和这样的方法:
class func executeRequest(delegate:__SOMETHING__,url:String,postParameters:[String:String],headerParameters:[String:String]){
//Do something and call delegate
}
我想要一个条件参数来检查输入是否符合 WebServiceProtocol
接受它。
我想写一个全局 class 函数,它可以处理每个输入,可能是 ViewController 或 NSObject class.
在 java 中对于 classes 我们是这样做的 :
<? extends SomeClass>
编辑
WebService.swift
import Foundation
protocol WebServiceProtocol {
func onDataReceived(data:NSDictionary!)
func onFailure()
}
class WebService:NSObject{
class func executeRequest(delegate:WebServiceProtocol,url:String,postParameters:[String:String],headerParameters:[String:String]){
if let URL: NSURL = NSURL(string: url){
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
request.HTTPBody = arrayToHttpParams(postParameters).dataUsingEncoding(NSUTF8StringEncoding)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){
response, data, error in
if error == nil {
if let jsonString = NSString(data: data, encoding: NSUTF8StringEncoding){
if let dictionary = Helper.parseJson(jsonString as String) {
delegate.onDataReceived(dictionary)
println(dictionary)
return;
}
}
println("failure !")
delegate.onDataReceived(nil)
}
else{
delegate.onFailure()
}
}
}
}
class func arrayToHttpParams(params:[String:String])->String{
var mergedParams = [String]();
for (key,value) in params {
mergedParams.append(key+"="+value)
}
return "&".join(mergedParams);
}
}
Authentication.swift
protocol AuthenticationLoginProtocol {
func onSuccess(data:NSDictionary)
func onFailure(data:NSDictionary)
}
class Authentication:NSObject,WebServiceProtocol{
func attempLogin(delegate:ViewController,emial:String,password:String){
var params = [String:String]();
params["key1"]="value1"
params["key2"]="value2"
WebService.executeRequest(self, url: "", postParameters: params, headerParameters: params)
}
func onDataReceived(data: NSDictionary!) {
}
func onFailure() {
}
}
更新
您正试图在 type 方法中引用一个实例。而不是这个,
WebService.executeRequest(self, url: "", postParameters: params, headerParameters: params)
这样写:
WebService.executeRequest(Authentication.self, url: "", postParameters: params, headerParameters: params)
然后稍后在例如Authentication
:
class Authentication: NSObject, WebServiceProtocol {
// ...
func someMethod() {
WebService.executeRequest(self, url: "", postParameters: ["1": "2"], headerParameters: ["1": "2"])
}
// ...
}
原回答
您可以为您的协议创建一个具有类型约束的通用函数:
func myFunc<T: WebServiceProtocol>(input: T) {
// input surely conforms to WebServiceProtocol
}
这样,T可以是任何类型,只要符合WebServiceProtocol
.
有关详细信息,请参阅类型约束 here。
如果您让输入将您的协议作为参数类型,编译器将仅在该函数的参数实现该协议的情况下进行编译,如上所示。
import UIKit
protocol WebServiceProtocol {
}
class ViewController: UIViewController {
@IBOutlet weak var testLabel: UILabel!
func takeProtocolAsInput(input: WebServiceProtocol) {
}
func otherFunc() {
takeProtocolAsInput(A())
// Compile-time error: B does not conform to WebServiceProtocol
takeProtocolAsInput(B())
}
}
class A: WebServiceProtocol {
}
class B {
}
@József Vesza 解决方案很好,因为 Xcode 会在您尝试传入不符合 WebServiceProtocol
的对象时通知您。但是,如果您希望能够将任何内容(如问题中指定的那样)传递给您的函数,您可以执行以下操作:
func myFunc(obj: Any) {
if let webService = obj as? WebServiceProtocol {
// Do stuff with webService...
}
}
您可以使该方法通用
class func executeRequest<T: WebServiceProtocol>(delegate: T,url:String,postParameters:[String:String],headerParameters:[String:String]) {
}
关于这种方法和@Will M. 的方法有何不同,article。
我有一个名为 WebServiceProtocol
的协议和这样的方法:
class func executeRequest(delegate:__SOMETHING__,url:String,postParameters:[String:String],headerParameters:[String:String]){
//Do something and call delegate
}
我想要一个条件参数来检查输入是否符合 WebServiceProtocol
接受它。
我想写一个全局 class 函数,它可以处理每个输入,可能是 ViewController 或 NSObject class.
在 java 中对于 classes 我们是这样做的 :
<? extends SomeClass>
编辑
import Foundation
protocol WebServiceProtocol {
func onDataReceived(data:NSDictionary!)
func onFailure()
}
class WebService:NSObject{
class func executeRequest(delegate:WebServiceProtocol,url:String,postParameters:[String:String],headerParameters:[String:String]){
if let URL: NSURL = NSURL(string: url){
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
request.HTTPBody = arrayToHttpParams(postParameters).dataUsingEncoding(NSUTF8StringEncoding)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){
response, data, error in
if error == nil {
if let jsonString = NSString(data: data, encoding: NSUTF8StringEncoding){
if let dictionary = Helper.parseJson(jsonString as String) {
delegate.onDataReceived(dictionary)
println(dictionary)
return;
}
}
println("failure !")
delegate.onDataReceived(nil)
}
else{
delegate.onFailure()
}
}
}
}
class func arrayToHttpParams(params:[String:String])->String{
var mergedParams = [String]();
for (key,value) in params {
mergedParams.append(key+"="+value)
}
return "&".join(mergedParams);
}
}
Authentication.swift
protocol AuthenticationLoginProtocol {
func onSuccess(data:NSDictionary)
func onFailure(data:NSDictionary)
}
class Authentication:NSObject,WebServiceProtocol{
func attempLogin(delegate:ViewController,emial:String,password:String){
var params = [String:String]();
params["key1"]="value1"
params["key2"]="value2"
WebService.executeRequest(self, url: "", postParameters: params, headerParameters: params)
}
func onDataReceived(data: NSDictionary!) {
}
func onFailure() {
}
}
更新
您正试图在 type 方法中引用一个实例。而不是这个,
WebService.executeRequest(self, url: "", postParameters: params, headerParameters: params)
这样写:
WebService.executeRequest(Authentication.self, url: "", postParameters: params, headerParameters: params)
然后稍后在例如Authentication
:
class Authentication: NSObject, WebServiceProtocol {
// ...
func someMethod() {
WebService.executeRequest(self, url: "", postParameters: ["1": "2"], headerParameters: ["1": "2"])
}
// ...
}
原回答
您可以为您的协议创建一个具有类型约束的通用函数:
func myFunc<T: WebServiceProtocol>(input: T) {
// input surely conforms to WebServiceProtocol
}
这样,T可以是任何类型,只要符合WebServiceProtocol
.
有关详细信息,请参阅类型约束 here。
如果您让输入将您的协议作为参数类型,编译器将仅在该函数的参数实现该协议的情况下进行编译,如上所示。
import UIKit
protocol WebServiceProtocol {
}
class ViewController: UIViewController {
@IBOutlet weak var testLabel: UILabel!
func takeProtocolAsInput(input: WebServiceProtocol) {
}
func otherFunc() {
takeProtocolAsInput(A())
// Compile-time error: B does not conform to WebServiceProtocol
takeProtocolAsInput(B())
}
}
class A: WebServiceProtocol {
}
class B {
}
@József Vesza 解决方案很好,因为 Xcode 会在您尝试传入不符合 WebServiceProtocol
的对象时通知您。但是,如果您希望能够将任何内容(如问题中指定的那样)传递给您的函数,您可以执行以下操作:
func myFunc(obj: Any) {
if let webService = obj as? WebServiceProtocol {
// Do stuff with webService...
}
}
您可以使该方法通用
class func executeRequest<T: WebServiceProtocol>(delegate: T,url:String,postParameters:[String:String],headerParameters:[String:String]) {
}
关于这种方法和@Will M. 的方法有何不同,article。