תחילת העבודה עם Places SDK ל-iOS‏ (Objective-C)

1. לפני שמתחילים

לפני שמתחילים לתכנת, צריך להגדיר כמה דברים.

Xcode

במדריך הזה משתמשים בכלי Xcode של Apple, יחד עם השפה Objective-C, כדי ליצור אפליקציית iOS פשוטה שפועלת באמולטור. לא צריך מכשיר פיזי. אפשר להוריד את Xcode בכתובת https://developer.apple.com/xcode/

CocoaPods

‫Places SDK ל-iOS זמין כ-CocoaPods pod. ‫CocoaPods הוא כלי קוד פתוח לניהול תלות בפרויקטים של Swift ו-Objective-C. אם הכלי הזה לא מותקן אצלכם, תצטרכו להתקין אותו לפני שתמשיכו. אפשר להתקין אותו מהטרמינל כך:

sudo gem install cocoapods

פרטים נוספים על CocoaPods זמינים במדריך לתחילת העבודה עם CocoaPods.

התקנת ה-SDK

כדי להתקין את ה-SDK, צריך ליצור קובץ Podfile בספריית הפרויקט. מערכת CocoaPods תשתמש בקובץ הזה כדי להוריד ולהגדיר את קשרי התלות הנדרשים. הדרך הכי קלה לעשות את זה היא ליצור פרויקט חדש ב-Xcode, להוסיף לו Podfile ולהתקין בו את ה-pods.

פותחים את Xcode ומוצג המסך'Welcome to Xcode' (ברוכים הבאים ל-Xcode). במסך הזה, בוחרים באפשרות 'יצירת פרויקט חדש ב-Xcode'.

4f1ecee473937c7b.png

במסך הבא תתבקשו לבחור תבנית לפרויקט החדש. בוחרים באפשרות 'אפליקציית תצוגה יחידה' ל-iOS ולוחצים על 'הבא'.

כשמתבקשים להזין את שם המוצר, אפשר לבחור כל שם שרוצים, אבל חשוב לשים לב למזהה החבילה שנוצר בשבילכם. תצטרכו את זה בהמשך.

72fbf25cb2db22ad.png

לוחצים על 'הבא' והפרויקט ייווצר בשבילכם. רושמים את הספרייה שבה הוא נוצר. סוגרים את Xcode ובאמצעות Terminal, מנווטים אל הספרייה הזו.

בטרמינל, מזינים את הפקודה הבאה:

pod init

יווצר קובץ בשם Podfile. עורכים אותו כדי להוסיף פוד ל-Google Maps באופן הבא:

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

שומרים אותו וסוגרים את Xcode. חשוב לסגור אותו, כי בשלב הבא תצטרכו לערוך את הפרויקט הבסיסי. אחרי שהתהליך יסתיים, תצטרכו לפתוח קובץ פרויקט אחר. אם לא סגרתם את Xcode לפני כן, יכול להיות שתתבלבלו ולא תדעו איפה כל דבר נמצא. עכשיו, בטרמינל, עוברים לספריית הפרויקט ומריצים את הפקודה pod install כך:

789c5bc62817f68a.png

אחרי שמסיימים, ה-pods יותקנו וייווצר קובץ חדש מסוג ‎ .xcworkspace. מעכשיו צריך להשתמש בזה לפרויקט. אבל לפני שמתחילים לכתוב קוד, צריך לקבל מפתח API.

2. קבלת מפתח API

בשלב הבא של ההפעלה, מפעילים את Maps SDK ל-iOS.

הגדרת הפלטפורמה של מפות Google

אם עדיין אין לכם חשבון ב-Google Cloud Platform ופרויקט עם חיוב מופעל, תוכלו לעיין במדריך תחילת העבודה עם הפלטפורמה של מפות Google כדי ליצור חשבון לחיוב ופרויקט.

  1. בCloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-codelab הזה.

  1. מפעילים ב-Google Cloud Marketplace את ממשקי ה-API וערכות ה-SDK של הפלטפורמה של מפות Google שנדרשים ל-codelab הזה. כדי לעשות זאת, פועלים לפי השלבים בסרטון הזה או בתיעוד הזה.
  2. יוצרים מפתח API בדף Credentials במסוף Cloud. אפשר לפעול לפי השלבים שמפורטים בסרטון הזה או בתיעוד הזה. כל הבקשות אל הפלטפורמה של מפות Google מחייבות מפתח API.

3. יצירת אפליקציה ל-Places API

אחרי שיצרתם פרויקט במסוף והפעלתם בו את Places API, אתם מוכנים להתחיל לכתוב את הקוד של האפליקציה הראשונה שלכם ל-Places API.

קודם, כשמתקינים את קובצי ה-Pod, נוצר קובץ ‎ .xcworkspace חדש. פותחים אותו באמצעות לחיצה כפולה עליו.

19d62f34c08e645c.png

בסייר הפרויקטים תופיע תיקייה חדשה בשם Pods. אם הפעולה הצליחה, תופיע תיקייה בשם GoogleMaps עם המסגרות.

8844d861f64c61aa.png

4. עורכים את הקובץ Info.plist.

כשמריצים את האפליקציה בפעם הראשונה, מערכת iOS מציגה תיבת דו-שיח שבה המשתמש מתבקש לתת הרשאה לגישה לשירותי המיקום. בתיבת הדו-שיח הזו תופיע מחרוזת שאתם מגדירים, ואותה צריך להזין בקובץ Info.plist. אם המחרוזת הזו לא קיימת, תיבת הדו-שיח לא תוצג והאפליקציה לא תפעל.

אפשר למצוא את הקובץ Info.plist בסייר הפרויקטים כאן:

c224c920ab3f1ef.png

בוחרים אותו ומוצג כלי העריכה של plist.

859ca56f3b19da5.png

מעבירים את העכבר מעל אחד מהרכיבים וסמל הפלוס'+' מופיע. לוחצים עליו ורואים שמופיע ערך חדש. מזינים את הערך NSLocationAlwaysUsageDescription בתיבה הזו.

9fb225d6f5508794.png

מקישים על Enter כדי להוסיף את המקש החדש. אחר כך לוחצים פעמיים על העמודה Value (ערך) של המפתח הזה ומוסיפים מחרוזת:

5aefeb184187aa58.png

מידע נוסף על המחרוזת הזו זמין במסמכי התיעוד למפתחים של אפל.

5. עריכת App Delegate

בסייר הפרויקטים, מוצאים את הקובץ AppDelegate.m ופותחים אותו. משתמשים בקובץ הזה כדי להוסיף את מפתח ה-API.

בחלק העליון של הקובץ, מוסיפים את השורה הזו מיד מתחת לשורה #import:

@import GoogleMaps;

אחר כך, בפונקציה didFinishLaunchingWithOptions:, מוסיפים את השורה הבאה ממש לפני השורה return YES:

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

חשוב להשתמש במפתח ה-API שיצרתם קודם.

6. עריכת קובץ לוח התכנון

בסייר הפרויקטים, פותחים את הקובץ Main.storyboard. לוחצים על לחצן סרגל הצד בפינה השמאלית העליונה כדי לוודא שסרגל הצד פעיל.

352af28b970d9e2.png

לאחר מכן, בתחתית סרגל הצד, מוצאים את האפשרות Label Control (שליטה בתווית) ומוודאים שהאפשרות Object Library (ספריית אובייקטים) מסומנת.

adec7051ae949531.png

בסצנת בקר התצוגה בצד ימין, מוודאים שהאפשרות 'תצוגה' מסומנת:

e4827b92b5861e3e.png

אחר כך גוררים 7 תוויות ומשחררים אותן בתצוגה. מסדרים אותם כמו שמוצג כאן. חשוב להקפיד לגרור את הגדלים שלהם כך שיתאימו למה שמוצג. כדי לערוך את הטקסט בתווית, לוחצים עליה פעמיים ומקלידים את הערך הרצוי:

f8a9457772358069.png

לתווית התחתונה ביותר (הגדולה מאוד), עוברים לכלי לעריכת מאפיינים ומוודאים שהיא מוגדרת ל-0 שורות (ברירת המחדל היא 1). כך אפשר להציג כמה שורות.

a4abacf00d8888fe.png

7. יצירת חנויות לערכים

כדי להשתמש ב-3 תוויות הערך, צריך ליצור חנות. כך תוכלו לשנות את הערכים שלהם באמצעות קוד. כדי לעשות את זה, קודם צריך להפעיל את העורך המסייע. כדי לעשות את זה, קודם צריך לסגור את סרגל הצד של הנכסים בלחיצה על הלחצן שלו. (הכפתור הזה הוצג בשלב הקודם)

לאחר מכן, לוחצים על לחצן העוזר הדיגיטלי – זהו העיגול הכפול שמוצג כאן:

e92dcc4ceea20a51.png

מוודאים שהוא מעבד את הקובץ ViewController.h. אם לא, אפשר לשנות את ההגדרה באמצעות העורך בחלק העליון של חלון העזרה:

d42f0fcc18b84703.png

אחר כך, לוחצים על מקש CONTROL, גוררים כל תווית ומשחררים אותה מתחת לשורה @interface בקובץ ViewController.h בחלונית העזרה. יופיע חלון דו-שיח עם השאלה איזה סוג חיבור רוצים ליצור:

a44b7888ed0f62b.png

מוודאים שההגדרות הן כמו שמוצג (חיבור: שקע; סוג: UILabel; אחסון: חלש), ואז נותנים לכל אחת מהן שם. לצורך ה-codelab הזה, קראתי לתוויות Longitude, ‏ Latitude ו-Altitude בשמות 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. עריכת קובץ הכותרת של ממשקי API של מיקום ושל לקוח Google

לפני השלבים האחרונים – שבהם בונים את האפליקציה כדי להשתמש ב-Places API – צריך להגדיר עוד כמה משתנים בקובץ הכותרת (ViewController.h). אלה הם הכלי לניהול מיקומים מרכזיים ואובייקט מיקום מרכזי:

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

תצטרכו גם לקוח Google API:

@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. כדי לעשות את זה, מציינים את פונקציית הקריאה החוזרת שתקבל את רשימת הסבירויות של המקומות. ‫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. הרצת האפליקציה באמולטור

מריצים את האפליקציה באמצעות לחצן ההפעלה בסרגל הכותרת. כאן אפשר גם לבחור את סוג ההרצה, וכמו שאתם רואים, אני בודק באייפון 6 באמצעות האמולטור.

bbbe0b8820c8a913.png

כשלוחצים על לחצן ההפעלה, האפליקציה תיבנה ותופעל. תופיע בקשה לאפשר לאפליקציה לגשת למיקום, כולל המחרוזת המותאמת אישית שציינתם קודם.

b9bb2ace7e68f186.png

אחרי שתעשו את זה, קווי הרוחב והאורך יתעדכנו. כדי לשנות את המיקום, בוחרים בתפריט Debug (ניפוי באגים) ובוחרים מיקום. לדוגמה, אפשר לבחור את האפשרות 'נסיעה בכביש מהיר'

dcb1ce091d780f56.png

כשעושים את זה, המיקום מוצג עם המקומות האפשריים שמתעדכנים, כדי לדמות את הנסיעה בכביש המהיר.

649e3eeb2321ae03.png

זה הכול! הצלחת לגשת לפרטים של המקום הנוכחי באמצעות Google Places API ב-iOS.