0

Lấy vị trí người dùng trên thiết bị ios sử dụng core location framework

Trong bài viết này sẽ hướng dẫn tập chung cách thêm tính năng GPS vào trong ứng dụng của iphone để lấy vị trí của người sử dụng. Ngoài ra tôi cũng sẽ đề cập đến việc phối hợp thông tin GPS vào bản đồ. Việc này sẽ khá thuận tiện ... . Dịch vụ định vị cung cấp một phương pháp để cải thiện ứng dụng của người dùng bằng cách nâng cao trải nghiệm của người sử dụng. Nếu bạn đang pháp triển một ứng dụng đi du lịch, bạn có thể căn cứ vào vị trí hiện tại của người dùng để tìm kiếm các nhà hàng hay khách sạn gần đó. Bạn cũng có thể tìm thấy các tính năng vị trí trong hầu hết các ứng dụng chụp ảnh (những ứng dụng mà có thể lưu thông tin vị trí ảnh chụp). Framwork này cung cấp các giao diện Objective-C cần thiết cho việc thu thập thông tin về vị trí của người dùng. Với tọa độ GPS thu được, bạn có thể sử dụng API để giải mã, phân tích các đường đi trên thực tế hoặc sử dụng để hiển thị vị trí trên bản đồ. Trong bài hướng dẫn này tôi sẽ xây dựng một ứng dụng đơn giản cho bạn thấy làm thế nào để sử dụng "Core Location Framwork". Dưới đây là những việc mà chúng ta sẽ thực hiện:

  • Xây dựng một giao diện đơn giản để hiển thị phối hợp GPS và địa chỉ.
  • Tìm hiểu cách sử dụng Core Location API để lấy vị trí hiện tại
  • Sử dụng các API đã được xây dựng để xác dịch các tọa độ GPS và địa chỉ đường xá.
  • Tạo Project và thiết kế giao diện Đầu tiên tạo một Xcode project mới sử dụng Single View Template. Đặt tên cho Project này là MyLocationDemo và thiết lập các thông số như sau:

1.png

Sau khi đã tạo thành công project, Đến Storyboard và bắt đầu thiết kế giao diện người sử dụng. Trong View, Thêm ba nhãn lần lượt là Latitude, Longitude, và Address. Hãy đặt thêm một Label khác nhau cho mỗi nhãn tương ứng để sau đó chúng ta sẽ sử dụng các Label này để hiển thị các tọa độ GPS và địa chỉ. Dưới cùng, chúng ta thêm một nút - đặt tên là "Get My Location". Giao diện người dùng của bạn sẽ giống như hình dưới đây: 2.png

Đối với các Label chúng ta cũng có thể thay đổi các thuộc tính chỉnh font chữ, hoặc kích thước chữ hiển thị cho những nội dung cần thiết. 32.png

**Thiết lập một kết nối giữa các Variable và thành phần của giao diện. **

Chúng ta sẽ cùng thiết lập các yêu tố trong giao diện người sử dụng với các biến. Trong Storyboard, chọn the View Controller và chuyển sang Assistant Editor.

4.png

Bấm vào giữ phím điều khiển rồi chọn nhãn “For Latitude Value” rồi kéo nó về phía “ViewController.h” đặt con trỏ giữa @interface@end keywords bạn sẽ thấy một cửa sổ cho phép bạn chèn một outlet. Đặt tên cho outlet là latitudeLabel 5.png

Tương tự, hãy lặp lại các bước này để tạo ra các outlet đới với những nhãn còn lại. Cuối cùng. hãy tạo ra một method xử lý sự kiện cho nút “Get My Location” và đặt tên là “getCurrentLocation”. Method này sẽ được gọi khi người dùng bấm chọn nút này 6.png

Nếu bạn làm theo những gì được hướng dẫn ở trên thì Code của file ViewController.h sẽ giống như dưới đây:

#import <UIKit/UIKit.h> @interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *latitudeLabel;

@property (weak, nonatomic) IBOutlet UILabel *longitudeLabel;

@property (weak, nonatomic) IBOutlet UILabel *addressLabel;

-(IBAction)getCurrentLocation:(id)sender;

Adding Core Location Framwork

Để lấy vị trí của người sử dụng, như đã đề cập trước đó chúng ta sẽ sử dụng CoreLocation framwork được cung cấp bởi iOS SDK. Theo mặc định thì CoreLocation framework không đi kèm trong bất cứ project Xcode nào. Chúng ta phải thêm nó thủ công. trong Navigator chọn “MylocationDemo”, trong khu vực nội dung này tiếp tục chọn tên Project của chúng ta và bên dưới nhấp vào “Link Binary with Libraries” sau đó click vào nút (+) để add CoreLocation framwork vào. 7.png

Code

Chúng ta chuyển sang phần cốt lõi của hướng dẫn này. Chương trình này cho phép lấy vị trí của người dùng dựa theo kinh độ, vĩ độ nó thậm chí có thể cung cấp cho người dùng vị trí được cập nhật liên tục nếu như người dùng di chuyển. Cũng giống như các thư viện khác trong iOS SDK, CoreLocation sử dụng các Delegate Pattern. Để làm việc với CoreLocation framework thì trong View Controller của chúng ta nên phù hợp với các giao thức CLLocationManagerDelegate. Giao thức này xác định các phương pháp được sử dụng để nhận vị trí kèm theo hướng được cập nhật từ một đối tượng CLLocationManagerDelegate. Để cho các View Controller biết về CLLocationManagerDelegate thì trước tiên chúng ta phải import tập tin header tương ứng. Trong file “ViewController.h” hãy thêm lệnh #import và rồi implement “CLLocationManagerDelegate”

#import <CoreLocation/CoreLocation.h>

@interface ViewController : UIViewController <CLLocationManagerDelegate>

Tiếp theo mở file “ViewController.m” để khai báo một biến instance và đặt tên nó là locationManager

@implementation ViewController {

CLLocationManager *locationManager;

Trong đó CLLocationManager là đối tượng mà sẽ cung cấp cho chúng ta dữ liệu vị trí. Hãy thêm đoạn code sau vào viewDidLoad method để cập nhật nhanh chóng đối tượng CLLocationManager:

-(void)viewDidLoad

{ [super viewDidLoad];

locationManager = [[CLLocationManager alloc] init];

Khi khởi tạo một đối tượng CLLocationManager thì chúng ta chỉ có thể gọi phương thức startUpdatingLocation tới location service. Service này sẽ liên tục gửi stream dữ liệu vị trí cho ứng dụng Hãy thêm đoạn mã sau vào method getCurrentLocation điều này sẽ nối lên button “Get My Location”:

-(IBAction)getCurrentLocation:(id)sender {

locationManager.delegate = self;

ocationManager.desiredAccuracy = kCLLocationAccuracyBest;

[locationManager startUpdatingLocation]; }

Như đã thảo luận trước đó, các dữ liệu về vị trí sẽ được cung cấp cho ứng dụng của bạn. Ở đây, chúng ta đặt ViewController như một đối tượng delegate. Để nắm bắt được những sự kiện liên quan đến vị trí, chúng ta phải thực hiện các phương pháp delegate theo như định nghĩa trong protocol. Thêm đoạn code sau đây vào ViewController.m và đặt chúng ngay dưới method "getCurrentLocation"

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {

NSLog(@"didFailWithError: %@", error);

UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

[errorAlert show]; }

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

NSLog(@"didUpdateToLocation: %@", newLocation);

CLLocation *currentLocation = newLocation;

if (currentLocation != nil) {

_longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];

_latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]; } }

TEST APPLICATION với vị trí giả. Bây giờ, chúng ta có thể biên dịch các ứng dụng và thử nghiệm nó bằng cách sử dụng các giả lập, mô phỏng. Có thể rằng bạn sẽ tự hỏi bằng các nào có thể sử dụng iPhone Similator để kiểm tra ứng dụng nhận biết vị trí? Hay làm thế nào để có thể giả lập lấy vị trí hiện tại? Không có cách nào có thể mô phỏng để có được vị trí hiện tại nếu như máy tính của bạn không có GPS tích hợp (thậm chí trong trường hợp bạn có, Xcode cũng sẽ không sử dụng nó) Tuy nhiên, trong môi trường mô phỏng nó cho phép bạn giả mạo một vị trí giả. Sau khi khởi động ứng dụng, bấm vào nút "Get My Location" Đây là lần đầu tiên chạy ứng dụng, nó sẽ nhắc nhở và cảnh báo người dùng về việc yêu cầu cho truy cập quyền quản lý vị trí.

8.png

Hãy nhớ chấp nhận (OK), tuy nhiên ứng dụng sẽ không thể nào truy cập dịch vụ về vị trí, nó sẽ thông báo lỗi. Chúng ta có thể dễ dàng giải thích tại sao hiện tượng này có thể xay rả. Vì theo mặc định, mô phỏng không biết được vị trí của mình. Trong thanh menu, hãy chọn "Debug" --> "Location". Vị trí mặc định được thiết lập là "None". Đó là lý do tại sao chúng ta lại nhận được message là "Fail to Get Your Loc ation". Bây giờ hãy thay đổi Location setting bằng "Apple" hoặc "Apple store". Bây giờ thì App của bạn sẽ hiển thị kinh độ và vĩ độ (giả) 9.png

Xcode cung cấp một cách khác để mô phỏng địa điểm. Trong khi chạy các ứng dụng bạn có thể thay đổi đến các địa điểm khác bằng cách sử dụng các mũI tên ở thanh menu bar trên cùng của khu vực Debug. 10.png

TÌM ĐỊA CHỈ. Một class cung cấp dịch vụ để chuyển đổi giữa một GPS và ddiahj chỉ người dùng có thể ... sử dụng được đó là CLGeocoder. Bằng việc xác định kinh độ và vĩ độ của một vị trí nhất định, chúng ta có thể sử dụng CLGeocoder để tìm một địa chỉ mà người sử dụng có thể hiểu được. Kết quả (ví dụ như một địa điểm) sẽ được trả về bởi CLGeocoder và lưu lại tại CLPlacemark object. Về dự án Xcode của chúng ta. Hãy thêm hai biến instance là: Geocoder và placemark: Khởi tạo "geocoder" trong method "viewDidLoad"

@implementation ViewController {

CLLocationManager *locationManager;

CLGeocoder *geocoder;

CLPlacemark *placemark; }

-(void)viewDidLoad { [super viewDidLoad]; locationManager = [[CLLocationManager alloc] init];

geocoder = [[CLGeocoder alloc] init]; }

Cập nhật lại method "didUpdateToLocation" để bao gồm các đoạn mã hóa địa lý ngược:

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

NSLog(@"didUpdateToLocation: %@", newLocation);

CLLocation *currentLocation = newLocation;

if (currentLocation != nil) {

_longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];

_latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]; }

// Reverse Geocoding NSLog(@"Resolving the Address");

[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) { NSLog(@"Found placemarks: %@, error: %@", placemarks, error);

``if (error == nil && [placemarks count] > 0){placemark = [placemarks lastObject];`

_ addressLabel.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@", placemark.subThoroughfare, placemark.thoroughfare, placemark.postalCode, placemark.locality, placemark.administrativeArea, placemark.country]; } else { NSLog(@"%@", error.debugDescription); } } ]; }

Chúng ta sử dụng method "reverseGeocodeLocation" để dịch các dữ liệu xác định vị trí vào một địa chỉ con người có thể hiểu và đọc được. Các hoạt động mã hóa địa lý không xảy ra trên thiết bị. Phương pháp này thay vì gửi dữ liệu cho máy chủ mã hóa địa lý trong Cloud để giải quyết. Khác với các dữ liệu vị trí, bạn phải cung cấp xử lý có chứa mã thực thi sau khi địa chỉ được giải quyết. Trong trường hợp này, chúng tôi sẽ cập nhật các nhãn địa chỉ để hiển thị địa chỉ trên màn hình. Cú pháp của completionHandler có thể mới đối với chúng ta. Thay vì sử dụng các delegate để cung cấp các thông tin phản hồi, CLGeocoder sử dụng "block" để tương tác, xử lý các response. Việc sử dụng block, chúng ta không cần viết một phương pháp riêng biệt mà chỉ cần viết vài dòng lệnh để thực thi sau khi lời gọi về geocoding đã hoàn tất. Sau khi hoàn thành một yêu cầu geocoding, các completionHandler sẽ được gọi tự động. Địa chỉ giải quyết được lưu trong mảng CLPlacemark. Dữ liệu này bao gồm các thông tin ví dụ như Quốc gia, thành phố, và địa chỉ đường phố. Vì vậy chúng ta chỉ đơn giản là chọn những đối tượng cần hiển thị từ mảng Placemark. Hãy chạy lại ứng dụng một lần nữa. Đừng quên chọn 1 vị trí xác định để trình giả lập hiểu. Chúng ta sẽ nhận được địa chỉ của nó.

11.png

TIẾT KIỆM PIN Ứng dụng này hoạt động nhưng nó tiêu thụ rất nhiều năng lượng. Vậy làm thế nào để tiết kiệm được khả năng tiêu thụ pin? Chúng ta cùng check lại code một lầ n nữa, khi người sử dụng ấn vào nút "Get My Location" chúng ta sẽ gọi đến method "startUpdatingLocation" để lấy vị trí của người sử dụng.

-(IBAction)getCurrentLocation:(id)sender {

locationManager.delegate = self;

locationManager.desiredAccuracy = kCLLocationAccuracyBest;

[locationManager startUpdatingLocation];

}

Nhưng vấn đề là method này sẽ báo báo các dữ liệu vị trí liên tục. Nó tiếp tục cập nhận vị trí và đưa ra vị trí update một cách liên tục thậm chí là chúng ta không hề di chuyển. Dưới đây là thông số debug: 12.png

Như chúng ta có thể thấy didUpdateToLocation được gọi nhiều lần. Vậy làm thế nào để bạn có thể nói liên lạc với location manager để dừng việc cập nhật vị trí lại? Chúng ta có thể sử dụng "stopUpdatingLocation" để disable việc update vị trí liên tục này. Chúng ta có thể ngừng cập nhật vị trí mỗi khi chúng ta lấy vị trí hiện tại:

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

NSLog(@"didUpdateToLocation: %@", newLocation);

CLLocation *currentLocation = newLocation;

if (currentLocation != nil) {

_longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];

_latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];

}

// Stop Location Manager

[locationManager stopUpdatingLocation];

NSLog(@"Resolving the Address");

[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {

NSLog(@"Found placemarks: %@, error: %@", placemarks, error);

if (error == nil && [placemarks count] > 0) {

placemark = [placemarks lastObject];

_addressLabel.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@", placemark.subThoroughfare, placemark.thoroughfare, placemark.postalCode, placemark.locality, placemark.administrativeArea, placemark.country];

} else { NSLog(@"%@", error.debugDescription); } } ]; }

13.png

Và hãy thử chạy lại ứng dụng một lần nữa để kiểm tra các thông báo đầu ra. Chúng ta sẽ thấy rằng didUpdateToLocation chỉ được gọi 1 lần và dừng lại. Trong khuân khổ bài viêt này tôi cung cấp cho bạn một bản demo nhỏ, đơn giản để hiển thị cách sử dụng CoreLocation framework. Đây là một ứng dụng cơ bản, nếu chúng ta muốn xây dựng một app trong thực tế đừng quên xử lý các trường hợp báo lỗi khác nhau ví dụ như lỗi network v.v…

source code: http://www.mediafire.com/download/q2o2rwg200eosdy/[TAMPN]+[StydyReport]+-+Get+the+User+Location+in+iOS+App.zip


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí