답변:
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];
또한 앱의 Info.plist에 NSLocationAlwaysUsageDescription
또는 NSLocationWhenInUseUsageDescription
키에 대한 문자열을 추가해야합니다 . 그렇지 않으면에 대한 호출 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()
ARC가 인스턴스를 제거하지 않고 위치에 대한 팝업이 너무 빨리 사라지도록 viewDidLoad 메소드에서이 행을 사용하십시오.
Xcode 문서에는 풍부한 지식과 샘플 앱이 있습니다. 위치 인식 프로그래밍 안내서를 확인하십시오 .
LocateMe의 샘플 프로젝트는 수정의 효과를 보여 CLLocationManager 의 다른 정밀도 설정을
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()
그리고 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
}
}