2014年8月29日 星期五

CLLocationManager programmatically using Swift and Object-C language

【說明】

此份筆記將紀錄如何取得目前裝置的經緯度。

此份專案有兩個頁面,其功能皆相同,但是第一個頁面所取得的經緯度為當下所偵測到的經緯度,第二個頁面取得的經緯度會一直更新,也就是說可以偵測移動的經緯度。


【專案開發步驟】

建立專案:

使用Single View Application模板建立一個名為location的專案,使用iPhone裝置。

設計使用者介面:

使用TabBarController包著兩個NavigationController,每個NavigationController各帶有一個View,編號1的TapBarItem名稱為First,File's owner設定為ViewController,編號2的TapBarItem名稱為Second,File's owner設定為SecondViewController,並讓Storyboard內會用到的元件與相對應的Class做連結,如下圖所示。

使用者介面

加入Location的Frameworks:

<Swift>
加入Frameworks至專案內,在Class內import即可,如下所示。

加入CoreLocation的Frameworks

在Class內import即可。

import CoreLocation

<Object-C>
加入Frameworks至專案內,在Class內import即可,如下所示。

#import <CoreLocation/CoreLocation.h>

修改ViewController:

建立CLLocationManager實體,如下所示。

<Swift>

var locationManager: CLLocationManager = CLLocationManager()

<Object-C>

宣告資料型態為CLLocationManager,名為locationManager的變數,並宣告可以Getter/Setter,如下所示。

@property (strongnonatomicCLLocationManager *locationManager;

在viewDidLoad時建立實體,並使用預設的初始值,如下所示。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.locationManager = [[CLLocationManager allocinit];
}

當按鈕按下後要取得目前的經緯度,並顯示在TextField內,如下所示。

<Swift>

@IBAction func getPosition(sender: UIButton) {
    locationManager.startUpdatingLocation()
    var latitude: CLLocationDegrees = locationManager.location.coordinate.latitude
    var longitude: CLLocationDegrees = locationManager.location.coordinate.longitude
    latitudeField.text = NSString(format: "%f", latitude)
    longitudeField.text = NSString(format: "%f", longitude)
}

<Object-C>

- (IBAction)getPosition:(UIButton *)sender {
    [self.locationManager startUpdatingLocation];
    CLLocationDegrees latitude = self.locationManager.location.coordinate.latitude;
    CLLocationDegrees longitude = self.locationManager.location.coordinate.longitude;
    self.latitudeField.text = [NSString stringWithFormat:@"%.f", latitude];
    self.longitudeField.text = [NSString stringWithFormat:@"%.f", longitude];
}
locationManager開始更新目前的位置。取得緯度。取得經度。顯示緯度在TextField內。顯示經度在TextField內。

修改SecondViewController:

要能偵測持續偵測經緯度必須使用CLLocationManagerDelegate,而要使用代理人機制就必須要有三步驟:

1.  告訴代理人是誰,在viewDidLoad內新增程式碼,如下所示。

<Swift>

override func viewDidLoad() {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
    locationManager.distanceFilter = 3.0
}

<Object-C>

- (void)viewDidLoad {
    [super viewDidLoad];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.locationManager.distanceFilter = 3.0;
}
告訴CLLocationManagerDelegate代理人是自己。設定所需要的精準度。設定距離多久偵測一次,單位為meters。

2.  代理人需採納Protocol,如下所示。

<Swift>

class SecondViewController: UIViewController, CLLocationManagerDelegate {
}

<Object-C>
@interface SecondViewController ()<CLLocationManagerDelegate>
@end

3.  代理人實作Method,如下所示。

<Swift>

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    var locationArray: NSArray = locations
    var location: CLLocation = locationArray.lastObject as CLLocation
    var latitude: CLLocationDegreeslocation.coordinate.latitude
    var longitude: CLLocationDegreeslocation.coordinate.longitude
    latitudeField.text = NSString(format: "%f", latitude)
    longitudeField.text = NSString(format: "%f", longitude)
}

<Object-C>

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations lastObject];
    CLLocationDegrees latitude = location.coordinate.latitude;
    CLLocationDegrees lontitude = location.coordinate.longitude;
    self.latitudeField.text = [NSString stringWithFormat:@"%f", latitude];
    self.longitudeField.text = [NSString stringWithFormat:@"%f", lontitude];
}

當按鈕被按下後就開始偵測,如下所示。

<Swift>

@IBAction func getPosition(sender: UIButton) {
    locationManager.startUpdatingLocation()
}

<Object-C>

- (IBAction)getPosition:(UIButton *)sender {
    [self.locationManager startUpdatingLocation];
}

當Switch打開時開始偵測,關閉時停止偵測,如下所示。

<Swift>

@IBAction func switchChange(sender: UISwitch) {
    if sender.on {
        self.locationManager.startUpdatingLocation()
    } else {
        self.locationManager.stopUpdatingLocation()
        latitudeField.text = nil
        longitudeField.text = nil
    }
}

<Object-C>

- (IBAction)switchChange:(UISwitch *)sender {
    if (sender.isOn) {
        [self.locationManager startUpdatingLocation];
    } else {
        [self.locationManager stopUpdatingLocation];
        self.latitudeField.text = nil;
        self.longitudeField.text = nil;
    }
}
當停止偵測時也將latitudeField與LongitudeField內的文字清除。


【執行結果】

    



【專案範例】

沒有留言:

張貼留言