iOS에서 사용자로부터 현재 위치를 얻는 방법


답변:


336

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

iOS 6에서는 델리게이트 기능이 더 이상 사용되지 않습니다. 새로운 대의원은

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

따라서 새로운 위치 사용을 얻으려면

[locations lastObject]

iOS 8

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];

4
허용 된 답변을 칭찬하는 간단한 코드 스 니펫을 게시 해 주셔서 +1
AngeloS

12
이 예제에서주의를 기울이면 이러한 속성 값으로 인해 배터리 소모량이 높아집니다.
DanSkeel

36
중요 : 또한 "stopUpdatingLocations"를 수행해야합니다. 그렇지 않으면 사용자가 위치를 변경할 때마다 대리자 메서드가 호출됩니다. 따라서 위에서 언급 한 배터리 문제 및이 대리자 메서드에서 다른 메서드가 트리거되는 경우 계속 호출됩니다. 행복한 코딩 녀석! 건배!!
Apple_iOS0304

5
당신은 StackOverflow를 훌륭하게 만드는 사용자 유형입니다. 코드 스 니펫은 모범적이며 더 많은 사람들이 답변에 포함시키기를 바랍니다.
Danny

26
iOS 8.0 이상의 경우 프로젝트의 Info.plist에 다음 키를 포함해야합니다 : NSLocationAlwaysUsageDescription사용 중이 [self.locationManager requestAlwaysAuthorization]거나 사용중인 NSLocationWhenInUseUsageDescription경우 [self.locationManager requestWhenInUseAuthorization]. 또한 iOS 6.0 이상에서 iOS 7.0 이상까지 지원하려면 키 NSLocationUsageDescription또는 '개인 정보-위치 사용 설명'을 포함하십시오. 링크에 대한 자세한 정보 : developer.apple.com/library/ios/documentation/General/Reference/...
Sihad 베고 비치

79

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;
    }
}

10
그렇지 않아야 [locations lastObject]합니까?
Ian Dundas

1
위에서 언급 한 것과 동일한 단계를 시도했습니다. 그러나 콘솔에 "사용자 생각"이 인쇄됩니다. 그렇다면 앱이 위치를 사용할 권한이 없다는 의미입니까? 그렇다면 앱에서 위치를 사용하도록 허용하는 방법 도와주세요.
kirans_6891


31

이 간단한 단계를 시도하십시오 ....

참고 : 시뮬레이터 수단을 사용하는 경우 장치 위치 위도 및 경도를 확인하십시오. 기본적으로 아무것도 없습니다.

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);
          ------*/
     }];
}

14

Swift에서 (iOS 8 이상용).

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)
        }

8
나는 다음과 같은 경우에 신속하게 switch ()가 있다고 생각합니다 : ^)
Anton Tropashko

self.locationManager = LocationManager()ARC가 인스턴스를 제거하지 않고 위치에 대한 팝업이 너무 빨리 사라지도록 viewDidLoad 메소드에서이 행을 사용하십시오.
Kunal Gupta


2

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)
}

1

내가 작성한 이 서비스 를 사용 하여 모든 것을 처리 할 수 ​​있습니다.

이 서비스는 권한을 요청하고 CLLocationManager를 처리하므로 처리 할 필요가 없습니다.

다음과 같이 사용하십시오.

LocationService.getCurrentLocationOnSuccess({ (latitude, longitude) -> () in
    //Do something with Latitude and Longitude

    }, onFailure: { (error) -> () in

      //See what went wrong
      print(error)
})

0

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
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.