بدء استخدام Places SDK for iOS (Objective-C)

1. قبل البدء

قبل البدء في الترميز، هناك بعض المتطلبات الأساسية التي عليك إعدادها.

Xcode

يستخدم هذا البرنامج التعليمي أداة Xcode من Apple، بالإضافة إلى لغة Objective-C لإنشاء تطبيق iOS بسيط يعمل في محاكي. لست بحاجة إلى جهاز مادي. يمكنك الحصول على Xcode من خلال الرابط https://developer.apple.com/xcode/

CocoaPods

تتوفّر حزمة تطوير البرامج (SDK) الخاصة بخدمة "أماكن Google" لنظام التشغيل iOS كحزمة CocoaPods. ‫CocoaPods هي أداة مفتوحة المصدر لإدارة التبعيات في مشاريع Swift وObjective-C. إذا لم تكن هذه الأداة متوفّرة لديك، عليك تثبيتها قبل المتابعة. يمكن تثبيته من الوحدة الطرفية على النحو التالي:

sudo gem install cocoapods

لمزيد من التفاصيل حول CocoaPods، يُرجى الاطّلاع على دليل بدء استخدام CocoaPods.

تثبيت حزمة تطوير البرامج (SDK)

لتثبيت حزمة SDK، عليك إنشاء ملف Podfile في دليل مشروعك سيستخدمه CocoaPods لتنزيل الملحقات المطلوبة وضبطها. أسهل طريقة لإجراء ذلك هي إنشاء مشروع جديد في Xcode، وإضافة ملف Podfile إليه، وتثبيت وحدات Pod فيه.

افتح Xcode وستظهر لك شاشة "مرحبًا بك في Xcode". في هذه الصفحة، انقر على "إنشاء مشروع Xcode جديد".

4f1ecee473937c7b.png

في الشاشة التالية، سيُطلب منك اختيار نموذج لمشروعك الجديد. اختَر "تطبيق عرض واحد" لنظام التشغيل iOS، ثم اضغط على "التالي".

عندما يُطلب منك إدخال اسم المنتج، يمكنك اختيار أي اسم تريده، ولكن احرص على تدوين معرّف الحزمة الذي يتم إنشاؤه لك. ستحتاج إلى ذلك لاحقًا.

72fbf25cb2db22ad.png

انقر على "التالي" وسيتم إنشاء المشروع لك. دوِّن المجلد الذي تم إنشاؤه فيه. أغلِق Xcode وانتقِل إلى هذا الدليل باستخدام "نافذة الأوامر الطرفية".

باستخدام "الوحدة الطرفية"، أدخِل الأمر التالي:

pod init

سيتم إنشاء ملف باسم Podfile لك. عدِّله لإضافة وحدة GoogleMaps على النحو التالي:

target '{YOUR APP NAME}' do
pod 'GoogleMaps'
end

احفظه وأغلِق Xcode. احرص على إغلاقه، لأنّك ستعدّل المشروع الأساسي في الخطوة التالية. ستفتح ملف مشروع مختلفًا بعد الانتهاء من ذلك، ومن الشائع أن يختلط الأمر على المطوّر بشأن مكان كل شيء إذا لم يغلق Xcode سابقًا. الآن، في نافذة طرفية، انتقِل إلى دليل مشروعك ونفِّذ الأمر "pod install" على النحو التالي:

789c5bc62817f68a.png

بعد الانتهاء، سيتم تثبيت الحِزم وإنشاء ملف ‎ .xcworkspace جديد. استخدِم هذا الحساب للمشروع من الآن فصاعدًا. ولكن قبل البدء في الترميز، ستحتاج إلى مفتاح واجهة برمجة التطبيقات.

2. الحصول على مفتاح واجهة برمجة التطبيقات

في خطوة التفعيل التالية، فعِّل حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" لتطبيقات iOS.

إعداد Google Maps Platform

إذا لم يكن لديك حساب على Google Cloud Platform ومشروع مفعَّل فيه نظام الفوترة، يُرجى الاطّلاع على دليل البدء باستخدام Google Maps Platform لإنشاء حساب فوترة ومشروع.

  1. في Cloud Console، انقر على القائمة المنسدلة الخاصة بالمشروع واختَر المشروع الذي تريد استخدامه في هذا الدرس العملي.

  1. فعِّل واجهات برمجة التطبيقات وحِزم تطوير البرامج (SDK) في Google Maps Platform المطلوبة لهذا الدرس العملي في Google Cloud Marketplace. لإجراء ذلك، اتّبِع الخطوات الواردة في هذا الفيديو أو هذه المستندات.
  2. أنشئ مفتاح واجهة برمجة التطبيقات في صفحة بيانات الاعتماد في Cloud Console. يمكنك اتّباع الخطوات الواردة في هذا الفيديو أو هذه المستندات. تتطلّب جميع الطلبات إلى "منصة خرائط Google" مفتاح واجهة برمجة تطبيقات.

3- إنشاء تطبيق Places API

بعد إنشاء مشروع في وحدة التحكّم وتفعيل Places API فيه والحصول على مفتاح واجهة برمجة التطبيقات، يمكنك البدء في كتابة الرمز البرمجي لأول تطبيق يستخدم Places API.

عند تثبيت ملفات pod في وقت سابق، تم إنشاء ملف ‎ .xcworkspace جديد لك. افتح هذا الملف من خلال النقر عليه مرّتين.

19d62f34c08e645c.png

ستلاحظ في "مستكشف المشروع" (Project Explorer) أنّه لديك الآن مجلد جديد باسم "Pods". إذا نجحت هذه العملية، سيظهر لك مجلد GoogleMaps يحتوي على الأُطر.

8844d861f64c61aa.png

4. عدِّل ملف Info.plist.

عند تشغيل التطبيق لأول مرة، سيظهر لك مربع حوار على نظام التشغيل iOS يطلب من المستخدم منح الإذن بالوصول إلى خدمات الموقع الجغرافي. سيوفّر مربّع الحوار هذا سلسلة تحدّدها، ثم تضعها في ملف Info.plist. إذا لم يكن هذا السلسلة النصية متوفّرة، لن يظهر مربّع الحوار، ولن يعمل تطبيقك.

يمكنك العثور على ملف Info.plist في "مستكشف المشاريع" هنا:

c224c920ab3f1ef.png

اختَرها وسيظهر لك محرّر ملفات plist.

859ca56f3b19da5.png

مرِّر مؤشر الماوس فوق أيّ من العناصر، وسيظهر لك رمز "+". انقر عليه، وسيظهر إدخال جديد. أدخِل القيمة NSLocationAlwaysUsageDescription في هذا المربّع.

9fb225d6f5508794.png

اضغط على Enter لإضافة المفتاح الجديد. بعد ذلك، انقر مرّتين على عمود "القيمة" لهذا المفتاح، وأضِف سلسلة:

5aefeb184187aa58.png

لمزيد من المعلومات حول هذه السلسلة، يُرجى الاطّلاع على مستندات مطوّري Apple هنا.

5- تعديل App Delegate

في "مستكشف المشاريع"، ابحث عن AppDelegate.m وافتحه. ستستخدم هذا الملف لإضافة مفتاح واجهة برمجة التطبيقات.

في أعلى الملف، أضِف ما يلي مباشرةً أسفل سطر ‎ #import:

@import GoogleMaps;

بعد ذلك، في الدالة didFinishLaunchingWithOptions: ‎، أضِف ما يلي قبل السطر return YES:‎

[GMSServices provideAPIKey:@"<Add your API Key>"];

احرص على استخدام مفتاح واجهة برمجة التطبيقات الذي أنشأته سابقًا.

6. تعديل ملف لوحة العرض القصصي

في "مستكشف المشاريع"، افتح ملف Main.storyboard. تأكَّد من تفعيل الشريط الجانبي من خلال الضغط على زر الشريط الجانبي في أعلى يسار الشاشة.

352af28b970d9e2.png

بعد ذلك، في أسفل الشريط الجانبي، ابحث عن "عنصر التحكّم في التصنيف" من خلال التأكّد من تحديد "مكتبة العناصر".

adec7051ae949531.png

في "مشهد أداة التحكّم في العرض" (View Controller Scene) على يمين الشاشة، تأكَّد من تحديد "العرض" (View):

e4827b92b5861e3e.png

بعد ذلك، اسحب 7 تصنيفات وأفلِتها في العرض. رتِّبها كما هو موضّح هنا. احرص على سحب أحجامها لتتطابق مع ما هو معروض. يمكنك تعديل النص في التصنيف من خلال النقر عليه مرّتين وكتابة القيمة المطلوبة:

f8a9457772358069.png

بالنسبة إلى التصنيف السفلي (الكبير جدًا)، انتقِل إلى "محرّر الخصائص" وتأكَّد من ضبطه على 0 سطر (القيمة التلقائية هي 1). سيسمح ذلك بعرض أسطر متعددة.

a4abacf00d8888fe.png

7. إنشاء منافذ للقيم

بالنسبة إلى التصنيفات الثلاثة "القيمة"، عليك إنشاء منفذ بيع. سيسمح لك ذلك بتغيير قيمها باستخدام الرمز البرمجي. لإجراء ذلك، عليك أولاً تفعيل "مساعد التحرير". لإجراء ذلك، عليك أولاً إغلاق الشريط الجانبي للخصائص من خلال النقر على الزر الخاص به لإزالته. (ظهر هذا الزرّ في الخطوة السابقة)

بعد ذلك، انقر على زر "المساعد"، وهو الزر الذي يتضمّن دائرتَين كما هو موضّح هنا:

e92dcc4ceea20a51.png

تأكَّد من أنّه يعرض ملف ViewController.h. إذا لم يكن الأمر كذلك، يمكنك تغييره باستخدام المحرّر في أعلى نافذة المساعد:

d42f0fcc18b84703.png

بعد ذلك، أثناء الضغط باستمرار على مفتاح CONTROL، اسحب كل تصنيف وأفلِته أسفل سطر @interface في ملف ViewController.h في "المساعد". سيظهر مربّع حوار يسألك عن نوع الاتصال الذي تريد إجراؤه:

a44b7888ed0f62b.png

تأكَّد من أنّ الإعدادات كما هو موضّح (الاتصال: Outlet، النوع: UILabel، التخزين: Weak)، ثم امنح كلّ إعداد اسمًا. لأغراض هذا الدرس البرمجي، أطلقت على تصنيفات خط الطول وخط العرض والارتفاع الأسماء lblLongitude وlblLatitude وlblAltidude على التوالي. اسحب أيضًا التصنيف الكبير من الأسفل، وأطلِق عليه اسم lblPlaces.

عند الانتهاء، من المفترض أن يظهر ملف ViewController.h على النحو التالي:

#import <UIKit/UIKit.h>
@import GoogleMaps;

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
@property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
@property (weak, nonatomic) IBOutlet UILabel *lblAltitude;
@property (weak, nonatomic) IBOutlet UILabel *lblPlaces;

@end

8. تعديل ملف العنوان الخاص بواجهات برمجة التطبيقات الخاصة بالموقع الجغرافي وGoogle Client

قبل الخطوات النهائية التي يتم فيها إنشاء التطبيق لاستخدام واجهة برمجة التطبيقات للأماكن، عليك إعداد بعض المتغيرات الإضافية في ملف العنوان (ViewController.h). في ما يلي Core Location Manager وأحد عناصر Core Location:

@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;

ستحتاج أيضًا إلى برنامج Google API Client:

@property GMSPlacesClient *placesClient;

أخيرًا، عليك تعديل ملف العنوان لكي يطبّق الصف CLLocationManagerDelegate:

@interface ViewController : UIViewController<CLLocationManagerDelegate>

عند الانتهاء، يجب أن يظهر ملف العنوان على النحو التالي:

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


@interface ViewController : UIViewController<CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;
@property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
@property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
@property (weak, nonatomic) IBOutlet UILabel *lblAltitude;
@property (weak, nonatomic) IBOutlet UILabel *lblPlaces;

@property GMSPlacesClient *placesClient;
@end

9- تعديل أداة التحكّم في العرض

الخطوة الأولى هي تعديل الدالة viewDidLoad لتهيئة Location Manager وطلب إذن المستخدم بالوصول إلى الموقع الجغرافي، ثم بدء تشغيل Location Manager حتى يتمكّن من تتبُّع الموقع الجغرافي الحالي. عليك أيضًا إعداد برنامج Google Places API.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
        // Or [self.locationManager requestWhenInUseAuthorization];
    }
    [self.locationManager startUpdatingLocation];
    
    self.locationManager.delegate = self;
    self.location = [[CLLocation alloc] init];
    self.placesClient = [GMSPlacesClient sharedClient];
}

10. التعامل مع إشعارات الموقع الجغرافي

ستعاود أداة إدارة الموقع الجغرافي الاتصال بوحدة التحكّم في العرض مع آخر المعلومات عن الموقع الجغرافي من خلال استدعاء الدالة didUpdateLocations. عليك إضافة هذا الرمز إلى ViewController.m. تبدو الدالة على النحو التالي:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    // Enter code here
}

يجب أن تنفّذ هذه الدالة عدة مهام.

أولاً، سيخزّن الموقع الجغرافي في ذاكرة التخزين المؤقت مع آخر موقع جغرافي تم تلقّيه:

self.location = locations.lastObject;

بعد ذلك، يجب تعديل التصنيفات الثلاثة لخط العرض وخط الطول والارتفاع:

self.lblLatitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];

self.lblLongitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];

self.lblAltitude.text = [NSString stringWithFormat:@"%f", self.location.altitude];

بعد ذلك، ستطلب بيانات من Places API باستخدام Places Client. يمكنك إجراء ذلك من خلال تحديد دالة ردّ الاتصال التي ستتلقّى قائمة باحتمالات الأماكن. تحدّد Places API مدى احتمال وجودك في مكان معيّن استنادًا إلى موقعك الجغرافي. تعرض هذه الطريقة أسماء الأماكن المحتملة، بالإضافة إلى قيمة بين 0 و1 تتضمّن احتمال وجودك في ذلك المكان.

[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

بعد ذلك، يمكنك تنفيذ دالة معاودة الاتصال. سيتم تكرار هذه العملية في قائمة الاحتمالات، مع إضافة الأماكن واحتمالاتها.

[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

  if (error != nil) {
    NSLog(@"Current Place error %@", [error localizedDescription]);
    return;
  }
  NSMutableString *strPlaces = [NSMutableString stringWithString:@""];

  for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods) {
    GMSPlace* place = likelihood.place;
    NSLog(@"Current Place name %@ at likelihood %g", place.name,
            likelihood.likelihood);
    NSLog(@"Current Place address %@", place.formattedAddress);
    NSLog(@"Current Place attributions %@", place.attributions);
    NSLog(@"Current PlaceID %@", place.placeID);
    [strPlaces appendString:place.name];
    [strPlaces appendString:@" "];
    [strPlaces appendFormat:@"%g",likelihood.likelihood];
    [strPlaces appendString:@"\n"];
  }
  self.lblPlaces.text = strPlaces;
}];

عند الانتهاء، من المفترض أن تبدو وظيفة didUpdateLocations على النحو التالي:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    
    self.location = locations.lastObject;
    self.lblLatitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];
    self.lblLongitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];
    self.lblAltitude.text = [NSString stringWithFormat:@"%f", self.location.altitude];
    
    NSLog(@"%@", self.location.description);
    
    [self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

        if (error != nil) {
            NSLog(@"Current Place error %@", [error localizedDescription]);
            return;
        }
        NSMutableString *strPlaces = [NSMutableString stringWithString:@""];
        
        for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods)  
        {
            GMSPlace* place = likelihood.place;
            NSLog(@"Current Place name %@ at likelihood %g", place.name, likelihood.likelihood);
            NSLog(@"Current Place address %@", place.formattedAddress);
            NSLog(@"Current Place attributions %@", place.attributions);
            NSLog(@"Current PlaceID %@", place.placeID);
            [strPlaces appendString:place.name];
            [strPlaces appendString:@" "];
            [strPlaces appendFormat:@"%g",likelihood.likelihood];
            [strPlaces appendString:@"\n"];
        }
        self.lblPlaces.text = strPlaces;
    }];
}

أنت الآن جاهز لتشغيل تطبيقك واختباره.

11. تشغيل التطبيق في المحاكي

يمكنك تشغيل التطبيق باستخدام زر التشغيل في شريط العنوان. يتيح لك ذلك أيضًا اختيار نوع التشغيل، وكما ترى هنا، أختبر التطبيق على هاتف iPhone 6 باستخدام المحاكي.

bbbe0b8820c8a913.png

عند الضغط على زر التشغيل، سيتم إنشاء التطبيق وتشغيله. سيظهر لك طلب السماح للتطبيق بالوصول إلى الموقع الجغرافي، بما في ذلك السلسلة المخصّصة التي حدّدتها سابقًا.

b9bb2ace7e68f186.png

بعد إجراء ذلك، سيظهر لك تعديل على خطوط الطول والعرض. لتغيير الموقع الجغرافي، اختَر قائمة "تصحيح الأخطاء"، ثم اختَر موقعًا جغرافيًا. على سبيل المثال، يمكنك اختيار "قيادة على الطريق السريع".

dcb1ce091d780f56.png

عند إجراء ذلك، سيظهر لك الموقع الجغرافي مع تحديث الأماكن المحتملة، ما يحاكي القيادة على الطريق السريع.

649e3eeb2321ae03.png

هذا كل ما في الأمر! تمكّنت من الوصول إلى تفاصيل المكان الحالي باستخدام Google Places API على iOS.