1. לפני שמתחילים
ב-Codelab הזה תלמדו איך ליצור אפליקציה ל-iOS פשוטה שמשתמשת ב-Navigation SDK של Google Maps Platform כדי לנווט ליעד שהוגדר מראש.
כך תיראה האפליקציה שלכם בסיום.

דרישות מוקדמות
- ידע בסיסי בפיתוח אפליקציות ל-iOS ב-Swift.
- היכרות מסוימת עם מושגים בסיסיים של Google Maps SDK, כמו יצירת מפה שממוקדת במיקום ספציפי.
מה תלמדו
- איך ליצור אפליקציית iOS Swift פשוטה שמשתמשת ב-Navigation SDK כדי לנווט ליעד.
- איך משלבים את Navigation SDK ממאגר Cocoapods מרוחק.
- איך מנהלים את הרשאות המיקום ואת הסכם המשתמש עם התנאים למשתמשי קצה של Navigation SDK.
- איך מאתחלים את ה-SDK.
- איך מגדירים יעד ומתחילים את ההנחיות לניווט.
מה תצטרכו
- הגרסה היציבה האחרונה של XCode.
- חשבון Google ופרויקט שמופעל בו חיוב.
- מכשיר iOS או מכשיר מדומה שפועל ב-XCode Simulator. לא משנה באיזו אפשרות תבחרו, היא צריכה לעמוד בדרישות המינימליות של Navigation SDK.
2. להגדרה
אם עדיין אין לכם חשבון ב-Google Cloud Platform ופרויקט בענן עם חיוב מופעל, אתם צריכים להגדיר את הפרויקט ב-Google Cloud לפי ההוראות לתחילת העבודה עם Google Maps Platform.
בחירת פרויקט בענן של Google במסוף
ב-Cloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-codelab הזה.

הפעלת Navigation SDK בפרויקט
מפעילים את ממשקי ה-API וערכות ה-SDK של Google Maps Platform שנדרשים ל-Codelab הזה ב-Google Cloud Marketplace.
במסוף Google Cloud, עוברים אל APIs & Services > Library (ממשקי API ושירותים > ספרייה) ומחפשים את Navigation SDK.
אמורה להופיע תוצאת חיפוש אחת.

לוחצים על Navigation SDK כדי לפתוח את דף פרטי המוצר. לוחצים על הפעלה כדי להפעיל את ה-SDK בפרויקט.
חוזרים על התהליך הזה עבור Google Maps SDK ל-iOS.
יצירת מפתח API
יוצרים מפתח API בדף Credentials במסוף Cloud. כל הבקשות אל Google Maps Platform דורשות מפתח API. בדף Credentials במסוף. לוחצים על '+Create Credentials' (יצירת אמצעי אימות) בחלק העליון של הדף ובוחרים באפשרות 'API Key' (מפתח API) מבין האפשרויות.
לשימוש בסביבת ייצור, מומלץ להגדיר הגבלה על האפליקציה עבור מפתח ה-API, אבל זה לא חובה בסדנת התכנות הזו.
3. קבלת קבצי הפרויקט לדוגמה
בקטע הזה מוסבר איך להגדיר פרויקט בסיסי ריק של אפליקציית XCode על ידי שיבוט קבצים ממאגר GitHub של שיעור ה-Codelab הזה. במאגר Github יש גרסאות של קוד ה-codelab לפני ואחרי השינויים. ה-codelab יתחיל עם תבנית פרויקט ריקה ויתפתח למצב הסופי. אם נתקעתם, תוכלו להשתמש בפרויקט המוגמר במאגר כהפניה.
שיבוט המאגר או הורדת הקוד
עוברים לספרייה שבה רוצים לאחסן את ה-codelab.
אחר כך משכפלים את המאגר או מורידים את הקוד:
git clone https://github.com/googlemaps-samples/codelab-navigation-101-ios-swift
אם לא התקנתם את git, לחצו על הלחצן הזה כדי לקבל את הקוד:
כדי שתוכלו להתחיל לעבוד כמה שיותר מהר, במאגר יש קוד לתחילת הדרך בתיקייה Starter שיעזור לכם לעקוב אחרי ההוראות ב-Codelab הזה. יש גם פרויקט Solution מוכן מראש, למקרה שתרצו לדלג קדימה או לבדוק את ההתקדמות שלכם בכל שלב. כדי להשתמש בפרויקט הפתרון, צריך לפעול לפי ההוראות שבקטע 'התקנה באמצעות Cocoapods' שבהמשך, ואז להריץ את הפקודה 'pod update' מהתיקייה solution/Navigation SDK Codelab.
אחרי שמשכפלים את המאגר באופן מקומי, משתמשים ב-XCode כדי לפתוח את התיקייה Starter כפרויקט קיים. בודקים שהפרויקט נבנה ומופעל.
חיבור מכשיר או הגדרה של XCode Simulator
4. הוספת Navigation SDK לאפליקציה
יש שלוש דרכים לשלב את Navigation SDK בפרויקט XCode:בשיעור הזה משתמשים ב-CocoaPods. לפרטים על שילוב באמצעות Swift Package Manager או על התקנה ידנית באמצעות הורדת ה-SDK, אפשר לעיין במאמר יצירת פרויקט Xcode והתקנת Navigation SDK במסמכי התיעוד של Navigation SDK.
התקנה באמצעות Cocoapods
אם עדיין לא התקנתם את הכלי CocoaPods, אתם יכולים להתקין אותו ב-macOS על ידי הפעלת הפקודה הבאה מהטרמינל. פרטים נוספים מופיעים במדריך למתחילים לשימוש ב-CocoaPods.
sudo gem install cocoapods
יוצרים קובץ חדש בשם Podfile בתיקיית הפרויקט, בתוך התיקייה starter/Navigation SDK Codelab (ב-XCode, בוחרים באפשרות File > New > File > Other > Empty, שומרים בשם Podfile)
מוסיפים את התוכן הבא לPodfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '15.0'
target 'Navigation SDK Codelab' do
pod 'GoogleNavigation', '9.1.1'
end
חיסכון של Podfile.
פותחים טרמינל ומשנים את הספרייה למיקום שבו שמרתם את קובץ ה-Podfile (זה אמור להיות התיקייה starter/Navigation SDK Codelab במאגר של ה-codelab)
cd "<path-to-starter-project-folder>/Navigation SDK Codelab"
מריצים את הפקודה pod install. הפקודה הזו מתקינה את ממשקי ה-API שצוינו ב-Podfile, יחד עם יחסי תלות
pod install
סוגרים את Xcode ואז פותחים את קובץ ה- .xcworkspace של הפרויקט כדי להפעיל את Xcode. מעכשיו והלאה, צריך להשתמש בקובץ .xcworkspace כדי לפתוח את הפרויקט.
בודקים שנוספה ספריית Pods למבנה הפרויקט, ושבספרייה הזו יש Pods בשם GoogleMaps ו-GoogleNavigation.

הוספת מפתח API
מוסיפים את מפתח ה-API ל-AppDelegate.swift באופן הבא:
- מוסיפים את הצהרות הייבוא הבאות:
import GoogleMaps
import GoogleNavigation
- מוסיפים את הנתונים הבאים לשיטת
application(_:didFinishLaunchingWithOptions:):
GMSServices.provideAPIKey("YOUR_API_KEY")
מחליפים את YOUR_API_KEY במפתח ה-API שיצרתם בשלב הקודם.
מבצעים build של הפרויקט ומתקנים את השגיאות.
5. הגדרת הרשאות שניתנות לאפליקציה
ערכת ה-SDK לניווט מסתמכת על אותות GPS כדי לספק מיקום מדויק על הכביש והנחיות מפורטות, ולכן האפליקציה שלכם תצטרך לבקש מהמשתמש להעניק גישה לנתוני מיקום מדויקים.
כדי לעשות זאת, צריך להוסיף כמה מאפיינים לקובץ Info.plist של האפליקציה ב-Xcode, להוסיף קוד לאפליקציה כדי לבקש הרשאה מהמשתמש בזמן הריצה ולטפל בשגיאות כמו הרשאה שלא ניתנה או מיקום שלא זמין.
פותחים את Info.plist ב-Xcode. הוא אמור להיראות כך.

שליחת בקשה להרשאת מיקום מדויק
כדי להוסיף ערכים חדשים, מעבירים את סמן העכבר מעל השורה Information Property List (רשימת מאפייני מידע) עד שמופיע סמל הפלוס (+). לוחצים על הסמל '+' כדי לראות תיבת דו-שיח עם שמות נכסים מוצעים, אבל אפשר גם להוסיף נכסים באופן ידני.
מוסיפים את המאפיינים והערכים הבאים לקובץ Info.plist:
נכס | ערך |
פרטיות – תיאור השימוש במיקום תמיד ובמהלך השימוש | "האפליקציה הזו דורשת את מיקום המכשיר כדי לספק ניווט לפי מסלול מפורט" |
פרטיות – מיקום בזמן השימוש: תיאור השימוש | "האפליקציה הזו דורשת את מיקום המכשיר כדי לספק ניווט לפי מסלול מפורט" |
allowsBackgroundLocationUpdates | כן |
שליחת בקשה להרשאת מיקום ברקע
מוסיפים את המאפיינים והערכים הבאים לקובץ Info.plist:
UIBackgroundModes > Add Row > Item 0: App registers for location updates (select this value from the drop down list of suggestions)
קובץ Info.plist אמור להיראות כך בסיום.

בקשת גישה למיקום בזמן הריצה
מוסיפים את הצהרות הייבוא הבאות לקובץ ViewController.swift:
import GoogleNavigation
מוסיפים את ההצהרה הבאה למחלקה ViewController:
var locationManager: CLLocationManager!
מוסיפים שיטת ביטול ברירת מחדל ל-loadView() וקוראים ל-locationManager.requestAlwaysAuthorization():
override func loadView() {
locationManager = CLLocationManager()
locationManager.requestAlwaysAuthorization()
האפליקציה תבקש עכשיו מהמשתמש את המיקום שלו, ותאפשר לאפליקציה לגשת למיקום אם המשתמש יאשר את ההרשאה .
בקשת הרשאה להצגת התראות
מוסיפים את הקוד הבא ל-loadView() כדי לבקש מהמשתמש הרשאה להציג התראות, שנדרשת להצגת הוראות ניווט.
UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) {
granted, error in
// Handle denied authorization to display notifications.
if !granted || error != nil {
print("User rejected request to display notifications.")
}
}
מריצים את האפליקציה ובודקים שמוצגת בקשה לשתף את המיקום ולהפעיל את ההתראות.

6. הוספת ממשק משתמש לניווט
בשלב הזה מוסיפים מפה ומגדירים אותה כך שיוצג בה מיקום. לאחר מכן תוצג למשתמש תיבת דו-שיח עם התנאים וההגבלות של Navigation SDK.
הוספת תצוגת מפה לאפליקציה
מוסיפים את השורה הזו כדי להצהיר על משתנה GMSMapView ב-ViewController.
var mapView: GMSMapView!
כדי לאתחל את המפה, מוסיפים את הקוד הבא אל loadView() ב-Viewcontroller.swift:
let camera = GMSCameraPosition.camera(withLatitude: 51.483174, longitude: -0.177369, zoom: 14)
let options = GMSMapViewOptions()
options.camera = camera
options.frame = .zero
mapView = GMSMapView(options: options)
view = mapView
מריצים את האפליקציה. אמורה להופיע מפה שמרכזה בדרום-מערב לונדון.

הצגת תיבת הדו-שיח של תנאי השימוש במוצר Navigation SDK
מוסיפים את הקוד הבא ל-ViewController.swift באותה שיטת loadView() כמו הקוד הקודם. יוצגו התנאים וההגבלות למשתמשי הקצה של Navigation SDK. אם לא תאשרו את ההסכם, לא תוכלו להשתמש בניווט.
// Show the terms and conditions.
let companyName = "Navigation SDK Codelab"
GMSNavigationServices.showTermsAndConditionsDialogIfNeeded(withCompanyName: companyName) { termsAccepted in
if termsAccepted {
// Enable navigation if the user accepts the terms.
self.mapView.isNavigationEnabled = true
// Request authorization for alert notifications which deliver guidance instructions
// in the background.
} else {
// Handle the case when the user rejects the terms and conditions.
}
}
כדי לראות את תיבת הדו-שיח, בונים ומריצים את האפליקציה.

7. הוספת פונקציות listener לאירועי ניווט באמצעות מקשים
בשלב הזה נסביר איך להגדיר מאזינים לאירועים מרכזיים, כמו הגעה ליעד או שינוי מסלול של הנהג.
כדי להמתין ולתעד את האירועים האלה, בקר ה-View צריך להשתמש בפרוטוקול GMSNavigatorListener.
מוסיפים את הפרוטוקול הזה להגדרת המחלקה ב-ViewController.swift.
class ViewController: UIViewController,
GMSNavigatorListener {
עכשיו מוסיפים שורת קוד כדי להגדיר את המאזין ב-loadView():
// Add a listener for GMSNavigator.
mapView.navigator?.add(self)
לבסוף, מוסיפים שתי שיטות למחלקה כדי לטפל באירועים שמופעלים.
// Listener to handle arrival events.
func navigator(_ navigator: GMSNavigator, didArriveAt waypoint: GMSNavigationWaypoint) {
print("You have arrived at: \(waypoint.title)")
}
// Listener for route change events.
func navigatorDidChangeRoute(_ navigator: GMSNavigator) {
print("The route has changed.")
}
8. הגדרת יעד והתחלת ההנחיה
בקטע הזה נסביר איך להגדיר יעד ולהתחיל לקבל הנחיות ניווט.
יוצרים פונקציה חדשה ללוגיקת הניווט.
קודם מוסיפים פונקציה חדשה בשם startNav() ל-ViewController. הקוד הזה יכיל את הלוגיקה להגדרת יעד ולהתחלת הניווט.
// Create a route and start guidance.
@objc func startNav() {
}
יוצרים Waypoint ליעד.
לאחר מכן, יוצרים מערך של יעדים עם נקודת ציון אחת.
// Create a route and start guidance.
@objc func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(
GMSNavigationWaypoint.init(
placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
title: "Trafalgar Square")!)
}
מתקשרים אל setDestinations()ומטפלים בתשובה.
לאחר מכן, מתקשרים אל setDestinations ומטפלים בערך GMSRouteStatus שמוחזר.
אם הערך של GMSRouteStatus הוא OK, מתחילים את ההדרכה בהגדרת isGuidanceActive=true באובייקט mapView של navigator. אחרת, מדפיסים דף הצהרה שבו מצוין שהייתה שגיאה.
אם הערך GMSRouteStatus שמוחזר הוא OK, מתחילים לדמות נסיעה לאורך המסלול על ידי קריאה ל-mapView.locationSimulator.simulateLocationsAlongExistingRoute().
// Create a route and start guidance.
@objc func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(
GMSNavigationWaypoint.init(
placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
title: "Trafalgar Square")!)
mapView.navigator?.setDestinations(
destinations
) { routeStatus in
guard routeStatus == .OK else {
print("Handle route statuses that are not OK.")
return
}
//If routeStatus is OK, start guidance.
self.mapView.navigator?.isGuidanceActive = true
//start simulating driving along the route. self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
self.mapView.cameraMode = .following
}
}
טיפול בסטטוסים נפוצים של שגיאות
מומלץ לטפל בשגיאות GMSRouteStatus באופן מפורש יותר, במיוחד כשמנפים באגים בבעיות ראשוניות באפליקציה החדשה. לדוגמה, יכול להיות שתקבלו שגיאות לגבי הרשאת מיקום, מפתח API או 'לא נמצא מסלול' בתדירות גבוהה יותר בהתחלה בגלל הגדרת הניפוי שלכם, ולכן כדאי לטפל במצבי השגיאה האלה.
מוסיפים קוד שמטפל במקרים הספציפיים האלה ומדפיס הצהרה במסוף.
mapView.navigator?.setDestinations(
destinations
) { routeStatus in
guard routeStatus == .OK else {
print("Handle route statuses that are not OK.")
switch routeStatus {
case .locationUnavailable:
print("Location unavailable.") //check permissions
case .noRouteFound:
print("No route found.") //check start location and destination
case .waypointError:
print("Waypoint error") //check Place ID
default:
print("Not sure what happened")
}
return
}
הוספת לחצן להפעלת הדרכה לניווט
לבסוף, מוסיפים לחצן לממשק המשתמש ומקשרים אותו לשיטה startNav. יוצרים method בשם makeButton() עם הקוד הבא. איך מתקשרים לפונקציית makeButton() מ-loadView().
// Add a button to the view.
func makeButton() {
// A button to start navigation.
let navButton = UIButton(frame: CGRect(x: 5, y: 150, width: 200, height: 35))
navButton.backgroundColor = .blue
navButton.alpha = 0.5
navButton.setTitle("Start navigation", for: .normal)
navButton.addTarget(self, action: #selector(startNav), for: .touchUpInside)
self.mapView.addSubview(navButton)
}
יוצרים ומריצים את האפליקציה.
הערה: הפעלת הקוד ב-
startNav()
יתקשר אל
setDestinations()
שיטה שבה יש חיוב אחרי השימוש ב-1,000 יעדים ראשונים. מידע נוסף זמין במאמר בנושא שימוש וחיוב.
9. מעולה!
הגעתם ליעד!

יצרתם אפליקציה פשוטה שמספקת הנחיות מסלול מפורט ליעד באמצעות Navigation SDK של Google Maps Platform.
הגדרתם את הרשאות שניתנות לאפליקציה ואת תיבת הדו-שיח של תנאי השימוש למשתמשי קצה ב-Navigation SDK, וציינתם יעד באמצעות מזהה מקום. טיפלת במצבי הצלחה ושגיאה שונים באפליקציה.
10. עוד צעד אחד קדימה
אם אתם רוצים לפתח את האפליקציה שלכם עוד יותר, כדאי לעיין בנושאים הבאים כדי לקבל השראה.
- האזנה לאירועי ניווט נוספים מוסיפים קוד להצגת הודעה אם הזמן או המרחק שנותרו חורגים מסף מסוים.
- התאמה אישית של ממשק הניווט.
- אם אתם רוצים אתגר גדול יותר, נסו להוסיף כלי לבחירת מקום ב-Places API כדי לאפשר למשתמש להגדיר את היעד. הערה: באפליקציות ההדגמה של Navigation SDK יש הטמעה לדוגמה. מריצים את הפקודה
pod try GoogleNavigationבתיקיית הפרויקט כדי לראות את הקוד.