Mevcut konumu iOS'ta kullanıcıdan nasıl alabilirim


Yanıtlar:


336

RedBlueThing'in yanıtı benim için oldukça iyi çalıştı. İşte nasıl yaptığımla ilgili bazı örnek kod.

Başlık

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface yourController : UIViewController <CLLocationManagerDelegate> {
    CLLocationManager *locationManager;
}

@end

MainFile

İnit yönteminde

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];

Geri arama işlevi

- (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

İOS 6'da delege işlevi kullanımdan kaldırıldı. Yeni delege

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

Bu nedenle yeni pozisyon almak için

[locations lastObject]

iOS 8

İOS 8'de, konumu güncellemeye başlamadan önce izin istenmelidir

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

Ayrıca uygulamanın Info.plist öğesine NSLocationAlwaysUsageDescriptionveya NSLocationWhenInUseUsageDescriptionanahtarları için bir dize eklemeniz gerekir . Aksi takdirde, yapılan aramalar startUpdatingLocationyok sayılır ve temsilciniz herhangi bir geri arama alamaz.

Ve sonunda konum okuma okuma bittiğinde stopUpdating konumu uygun bir yerde arayın.

[locationManager stopUpdatingLocation];

4
Kabul edilen yanıtı
tamamlamak

12
Bu örneğe dikkat edin, bu özellik değerleri daha yüksek pil tüketimine yol açar.
DanSkeel

36
ÖNEMLİ: Ayrıca, kullanıcı konumunu her değiştirdiğinde temsilci yöntemi çağrılırsa "stopUpdatingLocations" komutunu da çağırmanız gerekir. Bu nedenle yukarıda belirtilen pil problemi ve ayrıca bu delege yönteminde tetiklenen başka bir yöntem varsa, çağrı yapmaya devam edilecektir. Mutlu Kodlama Çocuklar !! Alkış !!
Apple_iOS0304

5
StackOverflow'u mükemmel yapan kullanıcı türüdür. Kod parçacıkları örnek niteliğindedir ve umarım daha fazla kişi cevaplarına dahil eder.
Danny

26
İOS 8.0+ için, projenizin Info.plist'e aşağıdaki anahtarları eklemeniz gerekir: NSLocationAlwaysUsageDescriptionkullanıyorsanız [self.locationManager requestAlwaysAuthorization]veya NSLocationWhenInUseUsageDescriptionkullanıyorsanız [self.locationManager requestWhenInUseAuthorization]. Ayrıca iOS 6.0+ ile iOS 7.0+ arasındaki desteği desteklemek için anahtar NSLocationUsageDescriptionveya 'Gizlilik - Konum Kullanımı Açıklaması' bulunur. Bağlantı hakkında daha fazla bilgi: developer.apple.com/library/ios/documentation/General/Reference/…
Sihad Begovic

79

İOS 6'da,

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

kullanımdan kaldırıldı.

Bunun yerine aşağıdaki kodu kullanın

- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations lastObject];
    NSLog(@"lat%f - lon%f", location.coordinate.latitude, location.coordinate.longitude);
}

İOS 6 ~ 8 için yukarıdaki yöntem hala gereklidir, ancak yetkilendirmeyi ele almanız gerekir.

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

Bu, kullanıcının yetkilendirmesini işleyen temsilci yöntemidir

#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
bu olmamalı [locations lastObject]mı?
Ian Dundas

1
Yukarıda belirtilen adımların aynısını denedim. Ama konsolda "Kullanıcı hala düşünüyor" yazdırılıyor. Yani, uygulamanın konumu kullanma yetkisi olmadığı anlamına mı geliyor? Evetse, uygulamanın konumu kullanmasına nasıl izin veririm? Lütfen yardım et.
kirans_6891


31

Bu Basit Adımları Deneyin ....

NOT: Simülatör araçlarını kullanıyorsanız lütfen cihaz konumunun enlemini ve logitude'unu kontrol edin. Varsayılan olarak, sadece hiçbiri.

Adım 1:CoreLocation Çerçeveyi .h dosyasına aktarın

#import <CoreLocation/CoreLocation.h>

2. Adım: Temsilci ekleyin CLLocationManagerDelege

@interface yourViewController : UIViewController<CLLocationManagerDelegate>
{
    CLLocationManager *locationManager;
    CLLocation *currentLocation;
}

Adım 3: Bu kodu sınıf dosyasına ekleyin

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self CurrentLocationIdentifier]; // call this method
}

4. Adım: Geçerli konumu algılama yöntemi

//------------ 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. Adım: Bu yöntemi kullanarak konum bilgisi alın

- (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'te (iOS 8+ için).

Info.plist

Her şey sırayla. Anahtarlar için NSLocationWhenInUseUsageDescriptionveya NSLocationAlwaysUsageDescriptionne tür bir hizmet istediğinize bağlı olarak info.plist dosyasına açıklayıcı dizenizi eklemeniz gerekir

kod

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 = []
    }
}

kullanım

self.locationManager = LocationManager()
self.locationManager.getlocationForUser { (userLocation: CLLocation) -> () in
            print(userLocation)
        }

8
i bu gibi durumlar için hızlı bir switch () olduğuna inanıyorum: ^)
Anton Tropashko

self.locationManager = LocationManager()bu satırı viewDidLoad yönteminde kullanın, böylece ARC örneği kaldırmaz ve konum için açılır pencere çok hızlı kaybolur.
Kunal Gupta


2

iOS 11.x Swift 4.0 Info.plist'in bu iki özelliğe ihtiyacı var

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We're watching you</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Watch Out</string>

Ve bu kod ... tabii ki bir 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")
    }

Ve elbette bu kodu da hangi viewDidLoad () içine koyabilirsiniz.

locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestLocation()

Ve bu ikisi istek içinKonumun gitmesi için, aka koltuğundan çıkmak zorunda kalıyorsun :)

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print(error)
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    print(locations)
}

1

Yazdığım bu hizmeti sizin için her şeyi halletmek için kullanabilirsiniz.

Bu hizmet izinleri isteyecek ve CLLocationManager ile uğraşmak zorunda kalmayacak, böylece gerek kalmayacak.

Bunun gibi kullanın:

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

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

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

0

Swift 5 için, konumu almak için hızlı bir kısa sınıf:

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
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.