2014-11-01 3 views
1

Я вижу странное поведение в приложении iOS с поддержкой Rails/Heroku. Я постараюсь дать как можно больше деталей. Надеюсь, кто-то может указать на несколько возможных областей, где может возникнуть проблема.Несколько POST-запросов, возникающих

Я написал приложение iOS 7, используя XCode 5, где пользователь может входить в систему и публиковать новые статьи и комментарии. Я использую библиотеку AFNetworking для связи с моим серверным сервером (Rails 4, Heroku & Postgres). Я POSTING и GETing в формате JSON, поэтому я использую AFJSONRequsetOperation для обработки связи.

Любое использование моего Поста этот метод:

- (void) Post:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success 
     :(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON))failure 


// allocate a reachability object 
Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"]; 


reach.unreachableBlock = ^(Reachability*reach) 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject]; 
     [HUD flashMessage :@"Whoops" :@"No internet connection" :window]; 
    }); 

    failure(nil, nil, nil, nil); 
}; 

reach.reachableBlock = ^(Reachability*reach) 
{ 

    // prepare base URL and calculate signature 
    // Something like: https://myapp.herokuapp.com 
    NSURL *url = [NSURL URLWithString:BasePath]; 

    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 
    [httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
    [httpClient setDefaultHeader:@"Accept" value:@"application/json"]; 

    // Generates the POST URL 
    // Something like: https://myapp.herokuapp.com/api/v1/articles.json 
    NSString *basePath = [self GetPostURL]; 

    NSLog(@"Post %@ With parameters: %@", basePath, Parameters); 

    NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:basePath parameters:Parameters]; 

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:success failure:failure]; 

    [operation start]; 
}; 


[reach startNotifier]; 

}

Я сделал немного тестирования на моем iPhone 5. Просмотр списка статей в Tableview, просмотр деталей статьи в детальном а затем другой вид таблицы для просмотра и добавления комментариев. Я много тестировал и не заметил никаких проблем. В конце концов я увидел, что было 3 одинаковых комментария. Я подумал, что нужно дважды постучать по кнопке «Добавить», чтобы отключить эту кнопку. Я больше не думал об этом, потому что было невозможно воссоздать почти невозможно.

С тех пор я обновил свой телефон до iOS 8 и обновил свой XCode и SDK, чтобы отразить это. Я положил приложение на телефон моих друзей (iOS 8 & iPhone 5 C). Она использовала его в течение дня, не видя никаких проблем. Она просмотрела статьи, комментарии и добавила свои проблемы без проблем.

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

Когда она открыла приложение сегодня - оно вспыхнуло несколько раз, это выглядело как 10 или около того. Когда появилось табличное представление, статья, опубликованная вчера, появилась дважды. Точная статья (название, описание, лат/lng, изображение) появилась дважды, но с разными отметками времени.

Я думал, что приложение играет на своем телефоне, поэтому я проверил бэкэнд. Он имел две отдельные статьи, разные идентификаторы и временные метки, но в то же время точную копию.

Глядя на журналы, было что-то вроде 20/30 запросов GET из ее учетной записи. Кажется, что это соответствует вспышке при открытии. Он обновлял таблицу несколько раз.

Затем журналы показали запрос POST со всеми параметрами, которые она поставила накануне. Как будто она действительно опубликовала ту же статью сегодня, но, очевидно, она этого не сделала.

Кто-нибудь видел такие вещи раньше?

Единственное, что я могу думать о том, являются:

  • Контроллер просмотр статьи добавить не был разрушен после первоначального поста и каким-то образом был снова активен. Я предположил, что ARC будет справляться со всем этим?
  • Возможно, библиотека AFNetworking не покраснела и думает, что ей нужно снова отправить сообщение? Хотя почти 24 часа спустя.
  • Есть ли в библиотеке запрос пакетной обработки? Может быть, это может быть проблемой?
  • При отправке сообщения я использую 'dispatch_get_global_queue'. Это нормально?
  • При успешном добавлении статьи я снова перехожу к списку, используя приведенный ниже код. Может быть, с этим проблема, о которой я не знаю?

ArticleListViewController *articleList = (ArticleListViewController *)[self.storyboard instantiateInitialViewController]; articleList.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self articleList animated:YES completion:nil];

Я в недоумении, пытаясь даже повторить его, не говоря уже исправить. Я предполагаю, что я прав, указывая пальцем на приложение? Это не похоже на проблему с герою/рельсами.

Любая помощь была бы принята с благодарностью.

Update

Я только что этот вопрос еще раз. Вчера я проверил несколько тестов, добавив 3 статьи. Все работало, как ожидалось. Я бывал в приложении каждые несколько часов, чтобы убедиться, что все в порядке. Я только что открыл приложение, и он начал мигать/мерцать. Он обновил список новой статьей, опубликованной вчера. Я ничего не сделал, и он снова мерцал, и снова была добавлена ​​одна и та же статья (так что 2 дубликата с сегодняшней created_at date). Я продолжал ничего не делать, и через несколько секунд были обновлены еще 2 статьи, которые я добавил вчера. Одна статья была добавлена ​​3 раза, одна статья 2 раза, и одна статья была просто дублирована один раз. Это странное поведение.

Может ли быть какая-то глобальная переменная или что-то, что хранит все данные? Может быть, контроллеры не полностью удалены?

Brian

+0

Включается ли послеоперационное время от сервер iPhone? Что произойдет, если пользователь полностью добавит приложение до завершения отправки сообщения, есть ли повторная попытка при следующем запуске? – zaph

+0

Привет Заф. Каждый запрос GET/POST имеет временную метку, прикрепленную к iPhone. Каждая статья имеет собственную метку времени, столбец «created_at» из db. Я не писал код для повторного запуска при следующем запуске, если библиотека/iOS не обрабатывает это для вас? Кроме того, в этом случае POST завершился полностью - проблем не возникло, и пользователь не отказался от него. –

+0

Как вы обрабатываете POST на iPhone, который не увенчался успехом? – zaph

ответ

2

После бесконечных испытаний. Я нашел проблему.

Дубликат POST (ы) произошел случайным образом. Когда это произошло, казалось, что это происходит только 1% времени, иногда через 5 минут, иногда через день.

В конечном итоге я понял, что это как-то связано с переключением с 3G на WiFi. Добавление статьи о 3G, а затем переход на WiFi приведет к дублированию.

Проблема с блоками Reachability в моем вышеприведенном коде. Я начинаю опознаватель достижимости и настраиваю два блока для достижимых и недоступных. Эти блоки попадают, когда телефон изменяет состояние достижимости. Таким образом, переход от 3G к Wi-Fi снова ударил по достижимому блоку, что привело к дублированию POST.

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

[reach stopNotifier]; 

Или реализовать достижимости как:

-(BOOL)reachable { 
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"]; 
    NetworkStatus internetStatus = [r currentReachabilityStatus]; 
    if(internetStatus == NotReachable) { 
     return NO; 
} 
    return YES; 
} 

// In POST method 
if([self reachable]) 
{ 
    // Do POST 
}else{ 
    // No connection 
} 
Смежные вопросы