ฉันจะรับตำแหน่งปัจจุบันจากผู้ใช้ใน iOS ได้อย่างไร
ฉันจะรับตำแหน่งปัจจุบันจากผู้ใช้ใน iOS ได้อย่างไร
คำตอบ:
คำตอบของ RedBlueThing ทำงานได้ค่อนข้างดีสำหรับฉัน นี่คือตัวอย่างโค้ดของวิธีที่ฉันทำ
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface yourController : UIViewController <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
}
@end
ในวิธีการเริ่มต้น
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
จะถูกละเว้นและผู้รับมอบสิทธิ์ของคุณจะไม่ได้รับการโทรกลับใด ๆ
และในตอนท้ายเมื่อคุณเสร็จสิ้นการอ่านสถานที่โทรหยุดการปรับปรุงสถานที่ในสถานที่ที่เหมาะสม
[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 นั้น
- (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 มีความมั่งคั่งของความรู้และตัวอย่างแอพพลิเค - ตรวจสอบให้ความรู้สถานที่ตั้ง Programming คู่มือ
LocateMeโครงการตัวอย่างแสดงให้เห็นถึงผลกระทบของการปรับเปลี่ยนที่CLLocationManagerการตั้งค่าความถูกต้องที่แตกต่างกันของ
Info.plist iOS 11.x Swift 4.0 ต้องการคุณสมบัติทั้งสองนี้
<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
}
}