چابک به طور گسترده از خدمات مکانی (Location Services) پشتیبانی میکند. از جمله این خدمات رصد موقعیت مکانی کاربر (Geo-tracking یا location tracking)، تعیین محدوده جغرافیایی (Geo-fencing)، پوش بر اساس موقعیت مکانی (Location-Based Push Notifications) و پوش خودکار مکانی (Geofence Push Notifications) است.
ارسال موقعیت مکانی بدون پیادهسازی کتابخانه موقعیت مکانی چابک
اگر سرویس لوکیشن در اپلیکیشنتان پیادهسازی شده و قصد اضافه کردن کتابخانه جدید برای ارسال موقعیت مکانی را ندارید، از طریق کد زیر میتوانید موقعیت مکانی کاربران را برای چابک ارسال کنید:
- (void) publishLocation:(CLLocation *)location {
NSDate *date = location.timestamp;
double lat = location.coordinate.latitude;
double lng = location.coordinate.longitude;
NSTimeInterval ts = [date timeIntervalSince1970] * 1000;
NSDictionary *payload = @{
@"lat": @(lat),
@"lng": @(lng),
@"ts" : @(ts)
}
[PushClientManager.defaultManager publishEvent:@"geo" data:payload];
}
از ارسال موقعیت مکانی در فاصله زمانی کمتر از ۱۰ ثانیه خودداری کنید.
مجوز های مورد نیاز موقعیت مکانی
برای استفاده از امکان موقعیت مکانی، نیازمند دریافت مجوزهای زیر می باشد که توضیحات لازم برای هر بخش در زیر آورده شده است :
- دسترسی به موقعیت مکانی
- مجوز استفاده از موقعیت مکانی
۱- دسترسی به موقعیت مکانی
برای استفاده از موقعیت مکانی در حالت Background Mode
، ابتدا وارد بخش Capabilities
پروژه خود شده و از قسمت Background Modes
گزینه Location updates
را فعال کنید.
در صورت فعال نمودن گزینه فوق، کلید
location
باید به فایلinfo.plist
اضافه شود، همانند کد زیر :
<key>UIBackgroundModes</key>
<array>
....
<string>location</string>
....
</array>
۲- مجوز استفاده از موقعیت مکانی
استفاده از موقعیت مکانی دارای دو حالت، WhileInUse
, Always
است که شرح آنها به صورت زیر می باشد :
- WhenInUse : استفاده از موقعیت مکانی، زمانی که نرم افزار در حالت
Foreground
باشد - Always : استفاده از موقعیت مکانی، در تمام حالات اجرای نرم افزار (
Foreground
,Background
)
برای استفاده از هر یک از این حالات کلید دلخواه را در فایل info.plist
قرار دهید، متن قرار گرفته شده در تگ string
متن پیامی است که پس از اعلان دریافت مجوز موقعیت مکانی به کاربر نشان داده خواهد شد.
<key>NSLocationAlwaysUsageDescription</key>
<string>App would like to use your location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow use to access your current location so we can autofill your start/end</string>
در نسخه
iOS 11
باید تمام کلید ها به همراه کلیدNSLocationAlwaysAndWhenInUseUsageDescription
در فایلinfo.plist
قرار داده شود.
<key>NSLocationAlwaysUsageDescription</key>
<string>App would like to use your location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow use to access your current location so we can autofill your start/end</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Allow use to access your current location Always or InUse</string>
ارسال موقعیت مکانی در هنگام باز شدن اپلیکیشن
با فعال کردن قابلیت enableLocationOnLaunch
، کتابخانه چابک به هنگام باز شدن برنامه و در صورت پیدا کردن موقعیت مکانی کاربر، موقعیت آن را توسط انتشار رویداد به سرور ارسال می کند.
برای ارسال داده خاصی همراه با انتشار رویداد فوق می توانید داده خود را property به
locationOnLaunchWithDictionary
داده تا همراه با انتشار رویداد ارسال شود.
[self.manager.enableLocationOnLaunch = YES];
کلاس CoreGeoLocation
در ابزار جدید چابک، امکان دریافت موقعیت مکانی کاربر فراهم شده است. برای استفاده از کلاس CoreGeoLocation
می توانید کلاس فوق را به کلاس خود import کنید:
#import "CoreGeoLocation.h"
.
.
.
CoreGeoLocation *locationManager = [CoreGeoLocation sharedInstance];
برای استفاده از قابلیت مکان یابی، پیکربندی های لازم که در بخش پیش نیازهای مکانیابی بیان شده را مطالعه کرده و از آن پیروی کنید.
دریافت موقعیت مکانی
ابتدا پیکربندی متناسب برای دریافت موقعیت مکانی را تعیین کرده و با استفاده از متد startLocationUpdate
شروع به دریافت موقعیت مکانی کاربر کنید. به قطعه کد زیر دقت کنید:
CoreGeoLocation *locationManager = [CoreGeoLocation sharedInstance];
[locationManager addDelegate:self];
[locationManager setDistanceFilter:50];
[locationManager setPausesAutomaticUpdate:NO];
[locationManager setLocationAutorization:kAlways];
[locationManager setAllowBackgroundLocationUpdates:YES];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startLocationUpdate];
رویداد دریافت موقعیت مکانی
جهت دریافت موقعیت های مکانی باید CoreGeoLocationDelegate
را به @interface
کلاس خود اضافه کنید و متد زیر را پیاده سازی کنید :
- (void) receivedLocationUpdates:(NSArray<CLLocation *> *)locations{
NSInteger length = locations.count;
CLLocation *lastLocation = [locations lastObject];
double latitude = lastLocation.coordinate.latitude;
double longitude = lastLocation.coordinate.longitude;
NSLog(@"%zd new locations was received, last location (lat:'%f') , (lng:'%f')",
length,latitude,longitude);
self.locationManager.customizeGeoData = ^NSDictionary * _Nullable
(CLLocation * _Nullable location) {
NSDictionary *data = @{@"speed":@(location.speed),
@"user":@"ADP"
};
return data;
};
}
چابک بصورت خودکار اقدام به publish موقعیت مکانی میکند، برای افزودن داده مورد نیاز همراه با موقعیت مکانی، باید Closures
customizeGeoData
را پیاده سازی کنید. برای جلوگیری publish موقعیت مکانی توسط چابک، مقدار بازگشتی ClosurescustomizeGeoData
را nil قرار دهید.
مکان یابی بر اساس مدت زمان و فاصله
با استفاده از متد trackMeUntil:byMeter
می توانید موقعیت کاربر را بر اساس فاصله و بازه زمانی (برحسب ثانیه) تعیین شده دنبال کنید :
CoreGeoLocation *locationManager = [CoreGeoLocation sharedInstance];
[locationManager trackMeUntil:3600 byMeter:100];
دقت داشته باشید که مدت زمان در متد
trackMeUntil
برحسب ثانیه است. به عنوان مثال در کد بالا مدت زمان ۳۶۰۰ ثانیه تعیین شده است.
متد فوق بعد از دریافت موقعیت مکانی، رویداد
receivedLocationUpdates:locations
را فراخوانی می کند. همچنین پس از پایان زمان تعیین شد به صورت خودکار عملیات مکان یابی را متوقف می سازد، با متوقف کردن موقعیت کاربر رویدادdidStoppedTrackingMe
فراخوانی خواهد شد.
برای بررسی وضعیت مکان یابی کاربر می توانید از متد زیر استفاده کنید :
trackingStateEnumType trackingState = [locationManager trackingMeState];
if (trackingState == kTracking) {
NSLog(@"We are tracking user...");
} else if (trackingState == kStopped) {
NSLog(@"Tracking user was stopped...");
} else {
NSLog(@"Tracking user interval was expired...");
}
جهت متوقف سازی عملیات مکان یابی کار کاربر متد فوق را فراخوانی کنید :
[locationManager stopTracking];
دریافت یک موقعیت مکانی
به کمک متد requestSingleLocation
می توانید تنها یک موقعیت مکانی دریافت کنید.
[locationManager requestSingleLocation:^(CLLocation * _Nullable location, NSError * _Nullable error) {
if (location != nil) {
NSLog(@"Single location was received");
}
}];
فراخوانی متد فوق ممکن است به عملکرد متدهای
trackMeUntil:byMeter
وstartLocationUpdate
اختلال ایجاد کند.
با فراخوانی متد
requestSingleLocation
چابک اقدام به publish موقعیت مکانی نمیکند.
دریافت موقعیت مکانی در حالت Terminated
امکان دریافت موقعیت مکان حتی در حالتی که اپلیکشن شما Terminate
شده باشد نیز وجود دارد.
[locationManager startMonitoringSignificantLocationChanges];
برای فعال شدن این قابلیت باید حتما
authorization
مربوط به location روی حالتkAlways
باشد.
متد فوق ممکن است پس از پیمودن ۵۰۰ متر یا بیشتر اپلیکیشن را به صورت کامل در background اجرا کند. برای داشتن تغییرات موقعیت کاربری به صورت مداوم باید کلید
launchOptions
را از رویدادdidFinishLaunchingWithOptions
و در صورت اجرا شدن توسطlocation
متدstartLocationUpdate
را فراخوانی کنید. قطعه کد زیر بیانگر این نکته می باشد.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]){
//App was launch by location update
CoreGeoLocation *locationManager = [CoreGeoLocation sharedInstance];
[locationManager startLocationUpdate];
}
}
محدوده جغرافیایی
جهت استفاده از قابلیت Geofence
باید متد startMonitoringRegion
را فراخوانی کنید. متد فوق دارای سه overload می باشد :
-(void) startMonitoringRegion:(CLRegion *_Nonnull) region;
-(void) startMonitoringRegion:(CLLocationCoordinate2D) center radius:(CLLocationDistance) radius identifier:(NSString *_Nonnull) identifier;
-(void) startMonitoringRegion:(CLRegion *_Nonnull) region
expireCount:(NSInteger) count
expireTs:(NSTimeInterval) ts
enterMessage:(NSString *_Nullable) enter
exitMessage:(NSString *_Nullable) exit;
برای استفاده قابلیت Geofence شما نیاز به استفاده از
startLocationUpdate
و یاstartMonitoringSignificantLocationChanges
نیست.
نمونه کد فوق استفاده از قابلیت geofence را به شما نشان می دهد :
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(35.759227, 51.401044);
CLRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:150 identifier:@"adpDigitalCompany"];
[_locationManager startMonitoringRegion:region];
چنانچه می خواهید یک geofence را start کنید که بتوانید بصورت بسیار ساده آن را مدیریت کنید، می توانید از قطعه کد زیر استفاده کنید :
زمان انقضای تاریخ geofence به صورت
unix millisecond
می باشد.
NSInteger count = 20; // count for enter to region
CLLocationDistance radius = 150; // per meter
CLLocationDegrees lat = 35.759227;
CLLocationDegrees lng = 51.401044;
NSString *exit = @"You exit to AdpDigital company building.....";
NSString *enter = @"Hi dear user, You are close to AdpDigital company building.....";
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(lat, lng);
NSTimeInterval expireTs = [[NSDate dateWithTimeIntervalSinceNow:3600] timeIntervalSince1970];
CLRegion *region = [[CLCircularRegion alloc] initWithCenter:coordinate
radius:radius
identifier:@"adpDigitalCompany"];
[_locationManager startMonitoringRegion:region expireCount:count expireTs:expireTs enterMessage:enter exitMessage:exit];
رویدادهای محدوده جغرافیایی
پس از فراخوانی متد startMonitoringRegion
رویدادهای زیر فرخوانی خواهند شد :
-(void) didEnterToRegion:(CLRegion *)region{
NSLog(@"Hi dear user, You are close to AdpDigital company building.....");
}
-(void) didExitFromRegion:(CLRegion *)region{
NSLog(@"You exit to AdpDigital company building.....");
}
-(void) didStartMonitoringRegion:(CLRegion *)region{
NSLog(@"Start monitoring %@ region",region.identifier);
}
برای متوقف سازی geofence می توانید از متد های زیر استفاده کنید :
[_locationManager stopMonitoringAllRegions];
[_locationManager stopMonitoringRegion:region];