简体   繁体   English

swift方法接受参数(如果符合协议)

[英]swift method accept parameter if conform a protocol

i have a protocol named WebServiceProtocol and method like this : 我有一个名为WebServiceProtocol的协议和类似这样的方法:

class func executeRequest(delegate:__SOMETHING__,url:String,postParameters:[String:String],headerParameters:[String:String]){
   //Do something and call delegate
}

i want to have a conditional argument that check if input conform WebServiceProtocol Accept it. 我想有一个条件参数,检查输入是否符合WebServiceProtocol接受它。

i'm tying to write a global class function that work with every input , maybe a ViewController or NSObject class. 我想写一个全局类函数,它可以处理每个输入,也许是ViewController或NSObject类。

in java for classes we did like this : 在Java中,对于类,我们这样做如下:

<? extends SomeClass>

Edit 编辑 在此处输入图片说明 WebService.swift 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() {

    }

}

Update 更新资料

You are trying to reference an instance in a type method. 您正在尝试在类型方法中引用实例。 Instead of this, 代替这个

WebService.executeRequest(self, url: "", postParameters: params, headerParameters: params)

write this: 写这个:

WebService.executeRequest(Authentication.self, url: "", postParameters: params, headerParameters: params)

Then later in for example Authentication : 然后在后面的Authentication

class Authentication: NSObject, WebServiceProtocol {

    // ...

    func someMethod() {
        WebService.executeRequest(self, url: "", postParameters: ["1": "2"], headerParameters: ["1": "2"])
    }

    // ...
}

Original answer 原始答案

You could make a generic function with a type constraint for your protocol: 您可以为协议创建一个具有类型约束的泛型函数:

func myFunc<T: WebServiceProtocol>(input: T) {
  // input surely conforms to WebServiceProtocol
}

This way, T can be any type, as long as it conforms to the WebServiceProtocol . 这样,T可以是任何类型,只要它符合WebServiceProtocol

For more details, see Type Constraints here . 有关更多详细信息,请参见此处的类型约束。

If you make the input take your protocol as the parameter type, the compiler will only compile if the parameter for that function implements that protocol, like above. 如果使输入将协议作为参数类型,则只有在该函数的参数实现了该协议的情况下,编译器才会编译,如上。

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 solution is good because Xcode will let you know if you're trying to pass in an object that doesn't conform to WebServiceProtocol . @JózsefVesza解决方案很好,因为Xcode会在您试图传递不符合WebServiceProtocol的对象时通知您。 However, if you want to be able to pass anything (as specified in the question) to your function you could do the following: 但是,如果您希望能够将任何内容(如问题中指定的那样)传递给函数,则可以执行以下操作:

func myFunc(obj: Any) {
    if let webService = obj as? WebServiceProtocol {
        // Do stuff with webService...
    }
}

You can make that method generic 您可以使该方法通用

class func executeRequest<T: WebServiceProtocol>(delegate: T,url:String,postParameters:[String:String],headerParameters:[String:String]) {

}

There is an article about how this approach and @Will M.'s differ each other. 一篇文章介绍了这种方法与@Will M.的区别。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM