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

iOS 사용자로부터 현재 위치를 얻으려면 어떻게해야합니까?



답변

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


답변

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


답변

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


답변

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


답변

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