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

时间:2015-05-14 12:59:53

标签: ios swift delegates

我有一个名为WebServiceProtocol的协议和这样的方法:

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

我希望有一个条件参数来检查输入是否符合WebServiceProtocol接受它。

我正在努力编写一个适用于所有输入的全局类函数,可能是ViewController或NSObject类。

在java中我们这样做的类:

<? extends SomeClass>

修改 enter image description here 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() {

    }

}

4 个答案:

答案 0 :(得分:4)

更新

您正尝试在类型方法中引用实例。而不是这个,

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

答案 1 :(得分:2)

如果输入将您的协议作为参数类型,编译器将仅在该函数的参数实现该协议时进行编译,如上所述。

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 {

}

答案 2 :(得分:1)

@JózsefVesza解决方案很好,因为如果你试图传递一个不符合WebServiceProtocol的对象,Xcode会通知你。但是,如果您希望能够将任何内容(如问题中所指定的)传递给您的函数,则可以执行以下操作:

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

答案 3 :(得分:0)

您可以将该方法设为通用

<style>
#map-canvas {
    margin: 0px;
    padding: 0px;
}
</style>

<script>
function initialize2() {

    var myLatlng = new google.maps.LatLng(-25.363882,131.044922);

    var mapOptions = {
        zoom: 4,
        center: myLatlng
    }

    var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

    var marker = new google.maps.Marker({
        position: myLatlng,
        map: map,
        title: 'Hello World!'
    });
}

google.maps.event.addDomListener(window, 'load', initialize2);

</script>

<div id="map-canvas" style="width:450px;height:300px;"></div>

关于这种方法和@Will M.彼此之间的区别,有一个article