Відповіді:
Відповідь RedBlueThing працював для мене досить добре. Ось приклад коду того, як я це зробив.
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface yourController : UIViewController <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
}
@end
У методі init
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
Функція зворотного дзвінка
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(@"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
NSLog(@"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
У iOS 6 функція делегата була застарілою. Новим делегатом є
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
Тому для отримання нової позиції використовуйте
[locations lastObject]
В iOS 8 дозволу слід чітко запитати перед початком оновлення місцезнаходження
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[self.locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
Вам також потрібно додати рядок для клавіш NSLocationAlwaysUsageDescription
або NSLocationWhenInUseUsageDescription
клавіші до Info.plist програми. Інакше дзвінки до startUpdatingLocation
ігноруються, і ваш делегат не отримає зворотного дзвінка.
І наприкінці, коли ви закінчите зчитування розташування виклику stopUpddalization location у відповідному місці.
[locationManager stopUpdatingLocation];
NSLocationAlwaysUsageDescription
якщо ви використовуєте [self.locationManager requestAlwaysAuthorization]
або NSLocationWhenInUseUsageDescription
використовуєте [self.locationManager requestWhenInUseAuthorization]
. Також для підтримки iOS 6.0+ та iOS 7.0+ можна включити ключ NSLocationUsageDescription
або "Опис конфіденційності - опис використання місцезнаходження". Більше інформації за посиланням: developer.apple.com/library/ios/documentation/General/Reference/…
В iOS 6, the
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
застаріло.
Замість цього використовуйте наступний код
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
CLLocation *location = [locations lastObject];
NSLog(@"lat%f - lon%f", location.coordinate.latitude, location.coordinate.longitude);
}
Для iOS 6 ~ 8 вищезазначений метод все ще необхідний, але вам потрібно обробити авторизацію.
_locationManager = [CLLocationManager new];
_locationManager.delegate = self;
_locationManager.distanceFilter = kCLDistanceFilterNone;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0 &&
[CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse
//[CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedAlways
) {
// Will open an confirm dialog to get user's approval
[_locationManager requestWhenInUseAuthorization];
//[_locationManager requestAlwaysAuthorization];
} else {
[_locationManager startUpdatingLocation]; //Will update location immediately
}
Це метод делегата, який обробляє авторизацію користувача
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined: {
NSLog(@"User still thinking..");
} break;
case kCLAuthorizationStatusDenied: {
NSLog(@"User hates you");
} break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
case kCLAuthorizationStatusAuthorizedAlways: {
[_locationManager startUpdatingLocation]; //Will update location immediately
} break;
default:
break;
}
}
[locations lastObject]
?
Ви використовуєте рамку CoreLocation для доступу до інформації про місцезнаходження свого користувача. Вам потрібно буде створити об'єкт CLLocationManager та викликати повідомлення асинхронного startUpdatingLocation . Ви отримаєте зворотні дзвінки з місцезнаходженням користувача через CLLocationManagerDelegate, який ви постачаєте.
ПРИМІТКА. Будь ласка, перевірте широту та широту розташування пристрою, якщо ви використовуєте засоби імітації. За замовчуванням його немає жодного.
Крок 1: Імпорт CoreLocation
рамки у .h файл
#import <CoreLocation/CoreLocation.h>
Крок 2: Додайте делегат CLLocationManagerDelegate
@interface yourViewController : UIViewController<CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
Крок 3: Додайте цей код у файл класу
- (void)viewDidLoad
{
[super viewDidLoad];
[self CurrentLocationIdentifier]; // call this method
}
Крок 4: Метод виявлення поточного місцезнаходження
//------------ Current Location Address-----
-(void)CurrentLocationIdentifier
{
//---- For getting current gps location
locationManager = [CLLocationManager new];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
//------
}
Крок 5. Отримайте місцезнаходження за допомогою цього методу
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
currentLocation = [locations objectAtIndex:0];
[locationManager stopUpdatingLocation];
CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
{
if (!(error))
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(@"\nCurrent Location Detected\n");
NSLog(@"placemark %@",placemark);
NSString *locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
NSString *Address = [[NSString alloc]initWithString:locatedAt];
NSString *Area = [[NSString alloc]initWithString:placemark.locality];
NSString *Country = [[NSString alloc]initWithString:placemark.country];
NSString *CountryArea = [NSString stringWithFormat:@"%@, %@", Area,Country];
NSLog(@"%@",CountryArea);
}
else
{
NSLog(@"Geocode failed with error %@", error);
NSLog(@"\nCurrent Location Not Detected\n");
//return;
CountryArea = NULL;
}
/*---- For more results
placemark.region);
placemark.country);
placemark.locality);
placemark.name);
placemark.ocean);
placemark.postalCode);
placemark.subLocality);
placemark.location);
------*/
}];
}
Info.plist
Насамперед. Вам потрібно додати свій описовий рядок у файл info.plist для ключів NSLocationWhenInUseUsageDescription
або NSLocationAlwaysUsageDescription
залежно від того, яку послугу ви запитуєте
Код
import Foundation
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate {
let manager: CLLocationManager
var locationManagerClosures: [((userLocation: CLLocation) -> ())] = []
override init() {
self.manager = CLLocationManager()
super.init()
self.manager.delegate = self
}
//This is the main method for getting the users location and will pass back the usersLocation when it is available
func getlocationForUser(userLocationClosure: ((userLocation: CLLocation) -> ())) {
self.locationManagerClosures.append(userLocationClosure)
//First need to check if the apple device has location services availabel. (i.e. Some iTouch's don't have this enabled)
if CLLocationManager.locationServicesEnabled() {
//Then check whether the user has granted you permission to get his location
if CLLocationManager.authorizationStatus() == .NotDetermined {
//Request permission
//Note: you can also ask for .requestWhenInUseAuthorization
manager.requestWhenInUseAuthorization()
} else if CLLocationManager.authorizationStatus() == .Restricted || CLLocationManager.authorizationStatus() == .Denied {
//... Sorry for you. You can huff and puff but you are not getting any location
} else if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
// This will trigger the locationManager:didUpdateLocation delegate method to get called when the next available location of the user is available
manager.startUpdatingLocation()
}
}
}
//MARK: CLLocationManager Delegate methods
@objc func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .AuthorizedAlways || status == .AuthorizedWhenInUse {
manager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
//Because multiple methods might have called getlocationForUser: method there might me multiple methods that need the users location.
//These userLocation closures will have been stored in the locationManagerClosures array so now that we have the users location we can pass the users location into all of them and then reset the array.
let tempClosures = self.locationManagerClosures
for closure in tempClosures {
closure(userLocation: newLocation)
}
self.locationManagerClosures = []
}
}
Використання
self.locationManager = LocationManager()
self.locationManager.getlocationForUser { (userLocation: CLLocation) -> () in
print(userLocation)
}
self.locationManager = LocationManager()
використовуйте цей рядок у методі viewDidLoad, щоб ARC не видаляв примірник, а спливаюче вікно для розташування занадто швидко зникає.
Документація Xcode має безліч знань і зразків програм - перевірте Посібник з програмування поінформованості про місцеположення .
LocateMe приклад проект ілюструє вплив зміни в CLLocationManager різних параметрів точності «сек
Ці iOS властивості потребують iOS 11.x Swift 4.0 Info.plist
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We're watching you</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Watch Out</string>
І цей код ... переконайтесь, звичайно, що ваш CLLocationManagerDelegate
let locationManager = CLLocationManager()
// MARK location Manager delegate code + more
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
print("User still thinking")
case .denied:
print("User hates you")
case .authorizedWhenInUse:
locationManager.stopUpdatingLocation()
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .restricted:
print("User dislikes you")
}
І звичайно цей код теж, який ви можете помістити в viewDidLoad ().
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestLocation()
І ці двоє для запиту Місцеположення, щоб поїхати, він же заощадить вам, що потрібно встати з місця :)
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
Ви можете використовувати цю службу, яку я написав, щоб обробити все за вас.
Ця послуга вимагає дозволів та обробляє справу з CLLocationManager, тому не потрібно.
Використовуйте так:
LocationService.getCurrentLocationOnSuccess({ (latitude, longitude) -> () in
//Do something with Latitude and Longitude
}, onFailure: { (error) -> () in
//See what went wrong
print(error)
})
Для Swift 5, ось короткий короткий клас, щоб отримати місцезнаходження:
class MyLocationManager: NSObject, CLLocationManagerDelegate {
let manager: CLLocationManager
override init() {
manager = CLLocationManager()
super.init()
manager.delegate = self
manager.distanceFilter = kCLDistanceFilterNone
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// do something with locations
}
}