2015-09-10 2 views
0

У меня есть служба, которая содержит несколько функций, которые подготавливают данные для отправки в веб-службу.iOS - Возвращаемый запрос данных async для ViewController

По существу я собираю свои данные в ViewController, передаю его в Сервис, обрабатываю его и преобразовываю, а затем передаю эту информацию классу, который отвечает за передачу данных (GET, POST, PUT, DELETE)

ie.

ViewController:

var model = MyModel() 
var service = MyService() 

service.createNewDBEntryOnServer(model) 

Услуги:

func createNewDBEntryOnServer(model: MyModel) -> MyModel { 

    var jsonToPost = JSONService.modelToJSON(model) 

    networkService.post("ext-url", jsonToPost, completion { data, response, error) in { 

     //Data returned here from JSONService 
     dispatch_async(dispatch_get_main_queue(), { 
      //Can return this data to ViewController for processing 
     }) 
    }) 
    return MyModel() 
} 

метод NETWORKSERVICE 'пост' использует NSURLSession.sharedSession(), и выполняет асинхронный запрос к веб-службы с помощью session.dataTaskWithRequest

Я могу вернуть данные просто отлично, но поскольку между моим ViewController и моим NetworkService есть слой, я не уверен, как обнаружить разница с возвратом на MyService до и после запроса данных асинхронной передачи. В некоторых случаях мне нужно было бы отобразить UIActivityIndicator, поэтому моему ViewController, например, пришлось бы ждать ответа async перед выполнением segue.

ответ

1

Как насчет добавления параметра обратного вызова завершения в createNewDBEntryOnServer? Итак:

var model = MyModel() 
var service = MyService() 

var queued = service.createNewDBEntryOnServer(model, completion {model} in { 
    // this is called asynchro 
    waiterPopup.dismiss(); 

    self.updateModel(model); 
}); 

if (queued) 
     waiterPopup.show(); 

Примечание: для того, чтобы избавиться от возможного удаления контроллеров, прежде чем обратный вызов называется, используйте слабый указатель на себя, как:

var queued = service.createNewDBEntryOnServer(model, completion {model} in { 
    // this is called asynchro 
    if (!weakSelf) 
    return; 

    weakSelf.dismissWaiter(); 
    weakSelf.updateModel(model); 
}); 
1

Служба может публиковать уведомление через NSNotificationCenter, к которому может быть подключен контроллер вида, а затем перейти и извлечь данные из службы. Если вы используете делегат внутри службы для прямого вызова контроллера представления, существует вероятность того, что контроллер представления фактически не существует в этой точке (в зависимости от вашего графического интерфейса и времени жизни контроллеров).

Лично я мог бы сделать что-то, что является деталью реализации модели, и ваши контроллеры представят запрос от модели, которая сама использует класс обслуживания. Но это ни правильно, ни неправильно, просто мое предпочтение.

Нет оснований избегать использования центра уведомлений, за исключением того факта, что, возможно, он вам незнакомец, но асинхронная деятельность, использующая его при завершении, является очень распространенным образцом в iOS. Другие шаблоны состоят в том, чтобы использовать блок завершения или делегат (т. Е. Обратный вызов). Но если вы возвращаетесь к объекту GUI, тогда существует реальная возможность того, что объект не существует во время обратного вызова, поэтому проверки должны быть введены в действие, чтобы справиться с этой ситуацией, если вы используете этот шаблон.

+0

Является ли мой подход типичный способ делать вещи в iOS? Этот шаблон проектирования я сильно использую в .NET, но для синхронных подключений. Лучше избегать использования NSNotificationCenter? – TeddyRuxpin

+0

Я добавил еще несколько предложений в ответ на ваш комментарий. – Gruntcakes

Смежные вопросы