В части 1 этого ряда я представлю вам самие основы фреймворка CoreLocation и получения расположения устройства, в настоящий момент.
О CoreLocation
Платформа CoreLocation предоставляет приложению возможность получить текущее расположение устройства, если пользователь устройства предоставил доступ приложения к той информации.
Услуги расположения предоставлены в двух главных способах использовать эту платформу:
1. Standard Location Services — Эта служба предоставляет самую точную информацию расположения, используя множество методов включая celluar, Wi-Fi и GPS.
— Самый точный.
— Использует большую часть питания и может занять более длительное время, чтобы получить.
— Может только использоваться, когда приложение находится на переднем плане.
2. Significant Change Location Services — Эта служба использует сотовые данные, чтобы определить общее представление о том, где устройство расположено.
— Самый быстрый и использование наименьшее количество суммы питания определить расположение.
— Может также использоваться, чтобы уведомить приложение, когда существенное изменение в расположении произошло, даже если приложение не находится в фокусе.
Файлы проекта:
Можете загрузить файлы проекта в этом github репозитарии: github.com/shawngrimes/Location-and-Map-Sample
Добавление Location Frameworks
Первый шаг к добавляющим службам расположения к проекту должен добавить платформу CoreLocation
Выберите target и перейдите к вкладке «Build Phases».
1. Щелкните “+” кнопка под “Двоичным файлом Ссылки С Библиотеками”
2. Выберите платформу CoreLocation и нажмите «Add»
Location Manager
Со службами расположения создаете экземпляр CLLocationManager. Обычно есть один экземпляр этого на приложение, таким образом, я чувствую, что хорошее место для этого находится в Делегате Приложения, и затем каждое представление может получить доступ к текущему расположению от Делегата Приложения.
Чтобы запуститься, откройте App Delegate заголовочный файл:
1. Добавьте #import <CoreLocation/CoreLocation.h> вверх
2. Проверьте, чтобы App Delegate приложения соответствовал Core Location Delegate протоколу изменяя interface строку с interface CFAAppDelegate: UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
3. Определите свойство CLLocationManager, добавляя @property (strong, nonatomic) CLLocationManager *locationManager прямо перед end оператором.
App Delegate заголовочный файл должен теперь выглядеть подобным следующему:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
interface CFAAppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) CLLocationManager *locationManager;
Создание The Location Manager Object
Переключите App Delegate файл реализации (.m), и мы переходим, создают нашего менеджера расположения объект. Первая вещь, которую мы должны сделать, так как мы создали ее как свойство нашего делегата приложения, синтезируют свойство, так добавьте @synthesize locationManager = _ locationManager; под строкой, которая читает @synthesize window = _window;.
#import "CFAAppDelegate.h"
@implementation CFAAppDelegate
@synthesize window = _window;
@synthesize locationManager=_locationManager;
Теперь, когда наше свойство синтезируется, мы можем создать объект. Я обычно создаю его в приложении метода didFinishLaunchingWithOptions:. Менеджер Расположения объект создается подобный любому другому объекту, но есть три важных свойства, которые должны установить после того, как имеете alloc’d/init’d.
1. .purpose – свойство цели выведено на экран пользователю приложения, когда они запрошены позволить приложению использовать их расположение. Это дает шанс объяснить, к чему переходит приложение, делают с их информацией расположения.
2. .desiredAccuracy – требуемое свойство точности позволяет говорить устройство, как точный хотели бы, чтобы информация расположения была. Это должно быть установлено на основе потребностей приложения. Не устанавливайте это свойство в
kCLLocationAccuracyBest, если только должны знать, в каком городе они находятся. ПРИМЕЧАНИЕ: Это — «требуемая» точность, она не гарантируется. Устройство определит наилучшую имеющуюся информацию и обеспечит ее для, но, однако, не гарантируют уровня точности.
3. .distanceFilter – свойство фильтра расстояния говорит менеджеру расположения, как далеко устройство должно переместиться (горизонтально по сравнению с высотным изменением) прежде, чем инициировать новое событие расположения. Это измерено в метрах. Можете установить свойство в kCLDistanceFilterNone, который будет уведомлен относительно всех событий (это — также значение по умолчанию).
Завершенное создание нашего расположения управляет, похож на это:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
if(self.locationManager==nil){
_locationManager=[[CLLocationManager alloc] init];
//I'm using ARC with this project so no need to release
_locationManager.delegate=self;
_locationManager.purpose = @"We will try to tell you where you are if you get lost";
_locationManager.desiredAccuracy=kCLLocationAccuracyBest;
_locationManager.distanceFilter=500;
self.locationManager=_locationManager;
}
return YES;
}
Если выполняете это теперь, не должны замечать изменение в способе, которым работает приложение, также не будете начинать получать информацию расположения просто все же. Это прибывает следующий …
Starting Location Services
Теперь, когда нам сконфигурировали нашего менеджера расположения, мы требуем начать получать расположение. Чтобы запустить стандартную службу расположения, должны сначала проверить, чтобы удостовериться, что службы расположения включены. Это сделано с простым вызовом к [CLLocationManager locationServicesEnabled] поэтому после того, как мы установим нашего менеджера расположения выше и перед возвратом ДА; добавьте следующий код:
if([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
ПРИМЕЧАНИЕ: Если службы расположения не будут включены, и начинаете обновлять службы расположения, то пользователю предложат включить службы расположения. Это могло быть раздражающим конечному пользователю, если они должны ответить «Нет» каждый раз на запуски приложения.
Если выполните приложение теперь, то заметите, что пользователю предлагают включить службы расположения (и оно будет включать сообщение от.prompt свойства нашего менеджера расположения объект).
Получение изменений расположения
Мы запустили службы расположения, но теперь мы должны начать получать обновления к изменениям расположения. Это все сделано через протокол CLLocationManagerDelegate. Есть много доступных методов, чтобы реализовать для этого делегата, но самые важные три, вероятно:
– locationManager:didUpdateToLocation:fromLocation:
– locationManager:didFailWithError:
– locationManager:didChangeAuthorizationStatus:
locationManager:didUpdateToLocation:fromLocation:
Давайте запускаться с получения обновления в расположении и как обработать это. В нашем Делегате Приложения файл реализации (.m), добавьте следующего заполнителя метода ниже @synthesize … операторы и выше — (BOOL) приложение: (UIApplication *) приложение didFinishLaunchingWithOptions: (NSDictionary *) launchOptions метод:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
}
Одна из первых вещей, которые мне нравится делать, проверить метку времени обнаруженного newLocation. Когда сначала начнете обновлять службы расположения, менеджер расположения получит последнее известное расположение устройства, это могло быть часами или днями в зависимости от прошлого раза, когда службы расположения использовались. В моих приложениях мне нравится удостоверяться, что у меня есть недавнее расположение. Этот после кода будет только использовать расположение, которое было найдено за прошлые 15.0 секунд:
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0)
{
//Location timestamp is within the last 15.0 seconds, let's use it!
}
Следующая проверка, которую мне нравится выполнять, должна видеть, насколько точный newLocation. Это может быть сделано, смотря на.horizontalAccuracy свойство. Это свойство говорит, как точная информация расположения. Как я вышеизложенный, можете запросить иметь очень точные расположения, но не гарантируют его. На иллюстрации ниже, newLocation.coordinate — расположение, устройство думает, что это, но в истине оранжевый круг.horizontalAccuracy говорит, что это могло быть где угодно в том кругу.
Потребность приложения определит, как точный из расположения требуете. Снова, если просто требуете города, пользователь находится в, не будете требовать его, чтобы быть столь же точными, как будто пытались найти что-то в расстоянии пешком. В коде ниже, я установил свой порог точности к 35.0 метрам. Это довольно широко, но я нашел, что это работает хорошо в закрытом помещении, а также. Вставьте следующий код прямо после комментария//, метка времени Расположения в течение прошлых 15.0 секунд, давайте использовать его!
//Location timestamp is within the last 15.0 seconds, let's use it!
if(newLocation.horizontalAccuracy<35.0){
//Location seems pretty accurate, let's use it!
NSLog(@"latitude %+.6f, longitude %+.6fn",
newLocation.coordinate.latitude,
newLocation.coordinate.longitude);
NSLog(@"Horizontal Accuracy:%f", newLocation.horizontalAccuracy);
//Optional: turn off location services once we've gotten a good location
[manager stopUpdatingLocation];
}
Код выше распечатает новое расположение к консоли и затем выключит службы расположения. Это — дополнительный шаг, но если не требуете служб расположения еще, это — умная вещь выключить их, чтобы сохранить батарею пользователя.
Это — то, на что похож наш полный метод делегата:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0)
{
//Location timestamp is within the last 15.0 seconds, let's use it!
if(newLocation.horizontalAccuracy<35.0){
//Location seems pretty accurate, let's use it!
NSLog(@"latitude %+.6f, longitude %+.6fn",
newLocation.coordinate.latitude,
newLocation.coordinate.longitude);
NSLog(@"Horizontal Accuracy:%f", newLocation.horizontalAccuracy);
//Optional: turn off location services once we've gotten a good location
[manager stopUpdatingLocation];
}
}
Теперь мы можем выполнить проект снова. Если не разрешали приложение использовать службы расположения прежде, идете вперед и делаете это теперь. Мы ничего не сделали с расположением в этой точке кроме, распечатывают его к консоли. Если не знаете, как видеть консоль, удостоверьтесь, что Xcode — активное окно (НЕ средство моделирования), и нажмите ⌘⇧ C
Если выполняете проект на средстве моделирования и не устройстве, не можете видеть результаты в консоли. Это вызвано тем, что средству моделирования не включали службы расположения по умолчанию. Можете моделировать расположение, выбирая моделирование служб расположения в консоли:
можете также моделировать расположение в Средстве моделирования при помощи меню Debug
Как только расположение было выбрано, возможно, должны перезапустить приложение, чтобы заставить новое расположение показывать в консоли:
Поскольку мы встраивали менеджера расположения в Делегата Приложения, можете получить доступ к текущему расположению устройства где угодно в коде включением заголовочного файла AppDelegate (.h) в файле реализации контроллера представления (.m):
#import "CFAAppDelegate.h"
Затем каждый раз, когда должны получить доступ к расположению, можете использовать следующий бит кода:
//Make sure location services are enabled before requesting the location
if([CLLocationManager locationServicesEnabled]){
CFAAppDelegate *appDelegate=(CFAAppDelegate *)[UIApplication sharedApplication].delegate;
CLLocation *currentLocation=appDelegate.locationManager.location;
//Do what you want with the location...
}
Автор: MicRaiS