Как я могу реализовать протоколы в параметрах метода в Swift? - PullRequest
0 голосов
/ 15 октября 2019

Я хотел бы реализовать методы протокола в других параметрах метода.

Сначала я определил протокол, содержащий метод,

protocol MyProtocol {
    func myProtocolFunc();
}

, и я создал метод, взяв протоколв качестве параметра.

func myFunc(myProtocol : MyProtocol) {
    . . .
}

и когда я использую этот метод, я хочу переопределить protocolFunc().

myFunc( . . . )

Где мне переопределить protocolFunc() в моем методе myFunc()?

ps В Kotlin я сделал это, сделав так.

interface MyProtocol {
    fun myProtocolFunc();
}

fun myFunc(myProtocol : MyProtocol) {
    . . .
}

myFunc(object : MyProtocol {
    override fun myProtocolFunc() {
        . . .
    }
})

Я хочу сделать то же самое в быстром коде.

===============================================

Редактировать:

На самом деле,Я планирую создать класс Http Request.

Получив некоторые данные с веб-сервера, я бы хотел поработать с классом ViewController.

Поскольку Http-запрос выполняется в потоке, при извлечении некоторых данных с веб-сервера следующий код, касающийся данных, должен ждать.

Вот мой класс Http Request,

class HttpConnector {

    static let basicURL = "http://******"
    static func getData(url : String, parameters : String, listener : UIModifyAvailableListener) {
        if let fullURL = URL(string : "\(basicURL)\(url)") {
            var request = URLRequest(url : fullURL)
            request.httpMethod = "POST"
            request.httpBody = parameters.data(using: .utf8)
            let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
                guard let data = data, error == nil else {
                    print("error = \(error!)")
                    return
                }

                if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
                       print("statusCode should be 200, but is \(httpStatus.statusCode)")
                       print("response = \(response!)")
                   }

                if let result = String(data: data, encoding: .utf8) {
                    listener.taskCompleted(result: result)
                }

            })
            task.resume()
        }
    }
}

protocol UIModifyAvailableListener {
    func taskCompleted(result : String)
}

, и этот класс может быть вызван в ViewController следующим образом:

HttpConnector.getData("my_url", "my_parameter", [[some codes regarding UIModifyAvailableListener protocol]])

Если это не может быть выполнено в swiftЯ хочу получить несколько альтернатив.

1 Ответ

2 голосов
/ 15 октября 2019

В вашем протоколе измените функцию на переменную функции.

protocol UIModifyAvailableListener {
    var taskCompleted : ((result : String) -> Void)? {get set}
}

Затем в своем классе HttpConnector, который реализует UIModifyAvailableListener, добавьте следующее:

var taskCompleted : ((result : String) -> Void)?

В классе HttpConnectorметод (ы), вы можете вызвать taskCompleted следующим образом:

self.taskCompleted?(result)

Затем в вызывающем коде, который хочет быть вызванным с помощью taskCompleted (), просто установите var:

myHttpConnector.taskCompleted = 
{
    print("Done!")  // note if you want to reference self here, you'll probably want to use weakSelf/strongSelf to avoid a memory leak.
}

Кстати, это важный шаблон, если вы работаете с MVVM, так что ваша ViewModel может перезвонить в ViewController. Поскольку ViewModel никогда не будет иметь ссылку на свой ViewController, все, что он может сделать, это иметь свойства обратного вызова, которые ViewController может установить с помощью блоков закрытия кода, которые он хочет вызвать. А с помощью протокола ViewModel может быть смоделирован при выполнении модульных тестов с ViewController. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...