CLLocationManager: нет сети, сохраняйте координаты и отправляйте повторно, когда сеть станет доступной?

#iphone #ios #cllocationmanager

#iPhone #iOS #cllocationmanager

Вопрос:

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

A: хранить и извлекать данные локально?

B: поручить CLLocationManager повторно отправить, когда подключение вернется?

Морщина: я непрерывно собираю данные о движущейся цели, поэтому мне может потребоваться сохранить несколько или много координат в массиве, пока сетевое соединение не вернется. Дополнительная морщина: я очень новичок в разработке iOS 🙂

Я считаю, что это соответствующая часть моего кода:

     NetworkStatus internetStatus = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus];

    if( internetStatus != NotReachable ) {
        NSData* data = [NSURLConnection sendSynchronousRequest:post returningResponse:response error:error];

        if( data == nil ) {
            NSLog( @"Doh!" );
        }
        else {
            NSLog(@"Data sent! %@", data);
        }
    }
    else {
         NSLog(@"No connection");
    }
 

Волшебство должно произойти в этом последнем еще

Есть желающие? Спасибо!

Ответ №1:

GPS будет работать без сети, поэтому вы можете сохранять каждое полученное вами обновление местоположения. Лучший способ сделать это в базе данных SQLite с идентификатором, широтой (двойной), долготой и меткой времени. Возможно, вам понадобится какой-то способ различать сеансы, чтобы вы могли сохранять каждый из них как путь. Возможно, вам понадобится флажок «уже отправлено это местоположение на сервер».

Вы могли бы использовать массив, но его нужно было бы сохранить. Вы делаете это, записывая список из массива. Подход SQLite более надежный.

Этот подход будет лучше всего работать на устройствах с чипом GPS (iPhone, некоторые iPad). Обычно это не будет работать так же хорошо на iPad Touch или WiFi (им не нужно подключение, но для работы им нужны маршрутизаторы WiFi).

Ответ №2:

Похоже, у вас должен быть какой-то другой способ управления отправкой данных, а не оставлять их в руках вашего диспетчера местоположения. Вы можете перенести работу с CLLocationManager на какой-либо другой метод, установленный на таймере или уведомлении, когда есть работа.

Ответ №3:

Если все, что вы хотите сохранить, это просто координаты, то, я думаю NSUserDefaults , это было бы самым простым решением для реализации. Есть несколько разных подходов, которые будут работать, вот один, который хранит все координаты в виде строки, разделенной ; для пар координат и , между долготой и широтой.

 - (void)saveCoordinate:(CLLocationCoordinate2D)coordinate {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *previousCoordinatesString = [defaults objectForKey:@"previousCoordinates"];

    NSString *newCoordinatesString;

    // check to see if the string has ever been saved for that key
    if (previousCoordinatesString) {
        newCoordinatesString = [NSString stringWithFormat:@"%@;%f,%f", previousCoordinatesString, coordinate.latitude, coordinate.longitude];
    }

    else {
        newCoordinatesString = [NSString stringWithFormat:@"%f,%f", coordinate.latitude, coordinate.longitude];
    }

    [defaults setObject:newCoordinatesString forKey:@"previousCoordinates"];
}
 

Чтобы получить сохраненные координаты, извлеките строку из NSUserDefaults , а затем проанализируйте каждую пару координат. Если в пользовательских значениях по умолчанию ничего нет, вернитесь NO . После анализа каждой координаты отправьте ее на сервер. Если устройство отключено, сохраните строку на потом.

 - (BOOL)fetchCoordinates {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *previousCoordinatesString = [defaults objectForKey:@"previousCoordinates"];

    // check to make sure the string exists
    if (!previousCoordinatesString) return NO;

    NSArray *coordinateStringsArray = [previousCoordinatesString componentsSeparatedByString:@";"];
    NSMutableString *coordinatesToSave = [[NSMutableString alloc] init];
    for (NSString *coordinateString in coordinateStringsArray) {
        NSArray *coordinatesArray = [coordinateString componentsSeparatedByString:@","];
        if (coordinatesArray.count > 1) {
            float lattitude = [[coordinatesArray objectAtIndex:0] floatValue];
            float longitude = [[coordinatesArray objectAtIndex:1] floatValue];

            CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(lattitude, longitude);
            if (![self sendCoordinatesToServer:coordinate]) {
                [coordinatesToSave appendFormat:@";%f,%f", lattitude, longitude];
            }
        }
    }

    if (coordinatesToSave.length > 0) {
        [defaults setObject:coordinatesToSave forKey:@"previousCoordinates"];
        return YES;
    }

    return NO;
}

- (BOOL)sendCoordinatesToServer:(CLLocationCoordinate2D)coordinate {
    if (/*check for network connection*/) {
        // send to server
        return YES;
    }

    return NO;
}
 

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