حزمة Driver SDK هي مكتبة تدمجها في تطبيق برنامج التشغيل. من المهم مسئولاً عن تحديث Fleet Engine بموقع السائق وطريقه والمسافة المتبقية والوقت المقدر للوصول. وهي تتكامل أيضًا مع حزمة SDK للتنقل، والتي توفّر إرشادات التنقّل باتّجاهات مفصّلة للسائق.
الحد الأدنى لمتطلبات النظام
المتطلبات الأساسية
يفترض هذا الدليل أن تطبيقك ينفذ حزمة SDK للتنقل وأنّ Fleet Engine إعداد الواجهة الخلفية وإتاحتها. ومع ذلك، يوفر مثال التعليمة البرمجية نموذج لكيفية إعداد حزمة SDK للتنقل.
يجب أيضًا تفعيل حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" لنظام التشغيل iOS في مشروع Google Cloud والحصول على مفتاح واجهة برمجة تطبيقات.
تنمية محلية
بالنسبة للتنمية المحلية، يكفي تسجيل الدخول باستخدام Cloud SDK:
gcloud
gcloud auth login
يجب أن يكون عنوان البريد الإلكتروني المستخدَم لتسجيل الدخول عضوًا في مجموعة Workspace.
الأتمتة (إنشاء الأنظمة أو الدمج المستمر)
إعداد مضيفي التشغيل الآلي وفقًا لما يلي: أفضل الممارسات:
في حال إجراء العملية داخل بيئة Google Cloud، استخدِم آلي بيانات الاعتماد.
بخلاف ذلك، يمكنك تخزين ملف مفتاح حساب الخدمة في موقع آمن على نظام ملفات المضيف وتعيين GOOGLE_APPLICATION_CREDENTIALS متغير البيئة بشكل مناسب.
يجب أن يكون البريد الإلكتروني لحساب الخدمة المرتبط ببيانات الاعتماد عضوًا في Workspace Goup.
إعدادات المشروع
مدير حزم Swift
يمكن تثبيت Driver SDK من خلال مدير حزم Swift لإضافة حزمة تطوير البرامج (SDK)، تأكَّد من أنّ لديك إزالة أي تبعيات حالية لحزمة تطوير البرامج (SDK) لبرنامج التشغيل.
لإضافة حزمة تطوير البرامج (SDK) إلى مشروع جديد أو حالي، اتّبِع الخطوات التالية:
-
افتح Xcode
project
أوworkspace
، ثم انتقِل إلى File >. أضِف تبعيات الحزمة. - أدخِل https://github.com/googlemaps/ios-driver-sdk كعنوان URL واضغط على Enter. لسحب الحزمة، والنقر فوق "Add Package" (إضافة حزمة).
-
لتثبيت قاعدة
version
محدّدة، اضبط حقل قاعدة التبعية على أحد الخيارات المستندة إلى الإصدار. وبالنسبة للمشروعات الجديدة، نوصي بتحديد أحدث إصدار باستخدام "الإصدار الدقيق" الخيار. بعد اكتمال عملية النقل، انقر على "إضافة حزمة". -
من نافذة اختيار منتجات الحزمة، تأكَّد من إضافة
GoogleRidesharingDriver
إلى هدفmain
المحدد. بعد اكتمال عملية النقل، انقر على "إضافة حزمة". -
للتحقّق من عملية التثبيت، انتقِل إلى جزء
General
في استهدافك. من المفترَض أن تظهر الحِزَم المثبَّتة في أُطر العمل والمكتبات والمحتوى المضمَّن. يمكنك أيضًا عرض قسم "تبعيات الحزمة" قسم "مستكشف المشروع" للتحقق من الحزمة وإصدارها.
لتعديل package
لمشروع حالي، اتّبِع الخطوات التالية:
في حال الترقية من إصدار أقدم من 9.0.0، يجب إزالة التبعيات التالية:
GoogleMapsBase
وGoogleMapsCore
وGoogleMapsM4B
بعد الترقية. لا تقم بإزالة تبعيةGoogleMaps
لمزيد من المعلومات، يُرجى الاطّلاع على ملاحظات الإصدار 9.0.0:من إعدادات ضبط مشروع Xcode، ابحث عن Frameworks وLibraries والمحتوى المضمَّن استخدِم علامة الطرح(-) لإزالة إطار العمل التالي:
GoogleMapsBase
(للترقيات من الإصدارات السابقة على 9.0.0 فقط)GoogleMapsCore
(للترقيات من الإصدارات السابقة على 9.0.0 فقط)GoogleMapsM4B
(للترقيات من الإصدارات السابقة على 9.0.0 فقط)
- من Xcode، انتقل إلى "File >" (ملف >) الحزم > التحديث إلى أحدث إصدارات الحزمة".
- للتحقّق من عملية التثبيت، انتقِل إلى قسم تبعيات الحزمة في Project Navigator (أداة التنقّل في المشروع) للتحقق من الحزمة وإصدارها.
لإزالة العناصر الاعتمادية الحالية لـ Driver SDK التي تمت إضافتها باستخدام
CocoaPods
، يُرجى اتّباع الخطوات التالية:
- أغلِق مساحة عمل Xcode. افتح المحطة الطرفية ونفِّذ الأمر التالي:
sudo gem install cocoapods-deintegrate cocoapods-clean pod deintegrate pod cache clean --all
-
إزالة
Podfile
وPodfile.resolved
و Xcodeworkspace
إذا كنت لا تستخدمهم لأي غرض آخر غير CocoaPods.
لإزالة تثبيت Driver SDK الحالي، يدويًا، اتبع الخطوات التالية:
من إعدادات ضبط مشروع Xcode، ابحث عن Frameworks، المكتبات والمحتوى المضمَّن استخدِم علامة الطرح
(-)
لإزالتها إطار العمل التالي:GoogleRidesharingDriver.xcframework
من دليل المستوى الأعلى لمشروع Xcode، أزِل حزمة
GoogleRidesharingDriver
.
CocoaPods
لضبط حزمة تطوير البرامج (SDK) لبرنامج التشغيل باستخدام CocoaPods، ستحتاج إلى العناصر التالية:
- أداة CocoaPods: لتثبيت هذه الأداة، افتح المحطة الطرفية وشغِّل الأمر التالي.
sudo gem install cocoapods
إنشاء ملف Podfile لـ Driver SDK واستخدامه لتثبيت واجهة برمجة التطبيقات ملحقاته: قم بإنشاء ملف يسمى Podfile في دليل المشروع الخاص بك. يحدد هذا الملف تبعيات مشروعك. قم بتحرير Podfile وإضافة وتبعياتك. فيما يلي مثال يتضمن التبعيات:
source "https://github.com/CocoaPods/Specs.git" target 'YOUR_APPLICATION_TARGET_NAME_HERE' do pod 'GoogleRidesharingDriver' end
في ما يلي مثال يتضمن الإصدارات الأولية والتجريبية لمجموعة حزمة تطوير البرامج (SDK) لبرنامج التشغيل كعناصر تابعة:
source "https://cpdc-eap.googlesource.com/ridesharing-driver-sdk.git" source "https://github.com/CocoaPods/Specs.git" target 'YOUR_APPLICATION_TARGET_NAME_HERE' do pod 'GoogleRidesharingDriver' end
احفظ ملف Podfile. افتح نافذة طرفية وانتقِل إلى الدليل الذي يحتوي على ملف Podfile:
cd <path-to-project>
شغِّل الأمر pod install. سيؤدي هذا إلى تثبيت واجهات برمجة التطبيقات المحددة في Podfile، إلى جانب أي تبعيات قد تكون موجودة.
pod install
أغلِق Xcode، ثم افتح ملف xcworkspace لمشروعك (بالنقر مرّتين). لتشغيل Xcode. ومن الآن فصاعدًا، يجب عليك استخدام .xcworkspace لفتح المشروع.
يُرجى الاطّلاع على مقالة بدء استخدام CocoaPods. لمزيد من المعلومات التفاصيل.
التثبيت اليدوي
XCFramework عبارة عن حزمة ثنائية تستخدمها لتثبيت SDK لبرنامج التشغيل. يمكنك استخدام هذه الحزمة على عدة حِزم بما في ذلك الأجهزة التي تستخدم نظام Apple السيليكون. يوضح هذا الدليل كيفية أضف XCFramework يدويًا الذي يحتوي على حزمة تطوير البرامج (SDK) لبرنامج التشغيل إلى مشروعك وإعداد إصدارك الإعدادات في Xcode.
تنزيل البرنامج الثنائي لحزمة SDK والموارد:
يمكنك استخراج الملفات للوصول إلى XCFramework والموارد.
ابدأ Xcode وافتح مشروعًا حاليًا أو أنشئ مشروعًا جديدًا مشروعك. إذا كنت مستخدمًا جديدًا لنظام التشغيل iOS، أنشئ مشروعًا جديدًا واختَر نظام التشغيل iOS. نموذج التطبيق.
إنشاء مجموعة أطر عمل ضمن مجموعة المشروعات إذا لم تكن هناك مجموعة بالفعل.
لتثبيت Driver SDK، اسحب ملف واحد (
GoogleRidesharingDriver.xcframework
) إلى مشروعك ضمن أُطر العمل والمكتبات والمحتوى المضمَّن: عندما يُطلب منك ذلك، اختَر انسخ العناصر إذا لزم الأمر.اسحب "
GoogleRidesharingDriver.bundle
" الذي تم تنزيله إلى المستوى الأعلى. دليل مشروع Xcode الخاص بك. اختَر "Copy items if needed
" عندما يُطلب منك ذلك.اختَر مشروعك من Project Navigator، ثم اختَر هدف التطبيق.
افتح علامة التبويب "مراحل الإنشاء"، وفي "Link Binary with Libraries" (رابط ثنائي مع المكتبات)، أضف أُطر العمل والمكتبات التالية إذا لم تكن موجودة بالفعل:
Accelerate.framework
AudioToolbox.framework
AVFoundation.framework
CoreData.framework
CoreGraphics.framework
CoreLocation.framework
CoreTelephony.framework
CoreText.framework
GLKit.framework
ImageIO.framework
libc++.tbd
libxml2.tbd
libz.tbd
LocalAuthentication.framework
OpenGLES.framework
QuartzCore.framework
SystemConfiguration.framework
UIKit.framework
WebKit.framework
اختر مشروعك بدلاً من هدف محدد، وافتح زر إنشاء الإعدادات في القسم علامات الروابط الأخرى، أضِف
-ObjC
عندما تصحيح الأخطاء والإصدار. إذا لم تكن هذه الإعدادات مرئية، فغيّر في شريط "إعدادات الإصدار" من أساسي إلى الكل.
فحص ملف بيان الخصوصية في Apple
تشترط Apple تفاصيل خصوصية التطبيقات للتطبيقات المتوفّرة على App Store. يُرجى الانتقال إلى صفحة تفاصيل خصوصية Apple App Store للاطّلاع على آخر الأخبار والمعلومات.
يتم تضمين ملف بيان الخصوصية من Apple في حزمة الموارد لحزمة تطوير البرامج (SDK). للتأكّد من تضمين "ملف بيان الخصوصية" وفحص محتواه، عليك إنشاء أرشيف لتطبيقك وإنشاء تقرير خصوصية من الأرشيف.
تنفيذ التفويض والمصادقة
عندما ينشئ تطبيق Driver التحديثات ويرسلها إلى خلفية Fleet Engine،
يجب أن تتضمن الطلبات رموز دخول صالحة. لمنح الإذن
بمصادقة هذه الطلبات، فإن "حزمة تطوير البرامج (SDK) لبرنامج التشغيل" تستدعي الكائن الذي يتوافق مع
GMTDAuthorization
والبروتوكول. الكائن مسؤول عن توفير رمز الدخول المطلوب.
بصفتك مطوّر التطبيق، أنت تختار كيفية إنشاء الرموز المميّزة. عملية التنفيذ القدرة على إجراء ما يلي:
- استرجاع رمز دخول، ربما بتنسيق JSON، من خادم HTTPS.
- تحليل الرمز المميّز وتخزينه مؤقتًا
- أعِد تحميل الرمز المميّز عند انتهاء صلاحيته.
للحصول على تفاصيل الرموز المميّزة التي يتوقعها خادم Fleet Engine، يُرجى الاطّلاع على إنشاء رمز JSON المميّز للويب (JWT) للتفويض:
رقم تعريف مقدّم الخدمة هو نفسه رقم تعريف مشروع Google Cloud. يُرجى الاطّلاع على دليل المستخدم لواجهة برمجة التطبيقات Fleet Engine Deliveries API. لمزيد من المعلومات.
يقدم المثال التالي موفّرًا لرمز الدخول:
#import "SampleAccessTokenProvider.h"
#import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
// SampleAccessTokenProvider.h
@interface SampleAccessTokenProvider : NSObject<GMTDAuthorization>
@end
static NSString *const PROVIDER_URL = @"INSERT_YOUR_TOKEN_PROVIDER_URL";
// SampleAccessTokenProvider.m
@implementation SampleAccessTokenProvider{
// The cached vehicle token.
NSString *_cachedVehicleToken;
// Keep track of the vehicle ID the cached token is for.
NSString *_lastKnownVehicleID;
// Keep track of when tokens expire for caching.
NSTimeInterval _tokenExpiration;
}
- (void)fetchTokenWithContext:(nullable GMTDAuthorizationContext *)authorizationContext
completion:(nonnull GMTDAuthTokenFetchCompletionHandler)completion {
if (!completion) {
NSAssert(NO, @"%s encountered an unexpected nil completion.", __PRETTY_FUNCTION__);
return;
}
// Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
NSString *vehicleID = authorizationContext.vehicleID;
if (!vehicleID) {
NSAssert(NO, @"Vehicle ID is missing from authorizationContext.");
return;
}
// Clear cached vehicle token if vehicle ID has changed.
if (![_lastKnownVehicleID isEqual:vehicleID]) {
_tokenExpiration = 0.0;
_cachedVehicleToken = nil;
}
_lastKnownVehicleID = vehicleID;
// Clear cached vehicle token if it has expired.
if ([[NSDate date] timeIntervalSince1970] > _tokenExpiration) {
_cachedVehicleToken = nil;
}
// If appropriate, use the cached token.
if (_cachedVehicleToken) {
completion(_cachedVehicleToken, nil);
return;
}
// Otherwise, try to fetch a new token from your server.
NSURL *requestURL = [NSURL URLWithString:PROVIDER_URL];
NSMutableURLRequest *request =
[[NSMutableURLRequest alloc] initWithURL:requestURL];
request.HTTPMethod = @"GET";
// Replace the following key values with the appropriate keys based on your
// server's expected response.
NSString *vehicleTokenKey = @"VEHICLE_TOKEN_KEY";
NSString *tokenExpirationKey = @"TOKEN_EXPIRATION";
__weak typeof(self) weakSelf = self;
void (^handler)(NSData *_Nullable data, NSURLResponse *_Nullable response,
NSError *_Nullable error) =
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
typeof(self) strongSelf = weakSelf;
if (error) {
completion(nil, error);
return;
}
NSError *JSONError;
NSMutableDictionary *JSONResponse =
[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&JSONError];
if (JSONError) {
completion(nil, JSONError);
return;
} else {
// Sample code only. No validation logic.
id expirationData = JSONResponse[tokenExpirationKey];
if ([expirationData isKindOfClass:[NSNumber class]]) {
NSTimeInterval expirationTime = ((NSNumber *)expirationData).doubleValue;
strongSelf->_tokenExpiration = [[NSDate date] timeIntervalSince1970] + expirationTime;
}
strongSelf->_cachedVehicleToken = JSONResponse[vehicleTokenKey];
completion(JSONResponse[vehicleTokenKey], nil);
}
};
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *mainQueueURLSession =
[NSURLSession sessionWithConfiguration:config delegate:nil
delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [mainQueueURLSession dataTaskWithRequest:request completionHandler:handler];
[task resume];
}
@end
إنشاء مثيل DeliveryDriverAPI
للحصول على مثيل GMTDDeliveryVehicleReporter
، عليك أولاً إنشاء
مثيل واحد (GMTDDeliveryDriverAPI
) يستخدم معرِّف الموفّر
معرف المركبةID، وdriverContext، وaccessTokenProvider. معرِّف الموفِّر هو نفسه
معرّف مشروع Google Cloud ويمكنك الوصول إلى GMTDDeliveryVehicleReporter
.
من واجهة برمجة تطبيقات برنامج التشغيل مباشرةً.
ينشئ المثال التالي مثيل GMTDDeliveryDriverAPI
:
#import “SampleViewController.h”
#import “SampleAccessTokenProvider.h”
#import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
@implementation SampleViewController {
GMSMapView *_mapView;
}
- (void)viewDidLoad {
NSString *vehicleID = @"INSERT_CREATED_VEHICLE_ID";
SampleAccessTokenProvider *accessTokenProvider =
[[SampleAccessTokenProvider alloc] init];
GMTDDriverContext *driverContext =
[[GMTDDriverContext alloc] initWithAccessTokenProvider:accessTokenProvider
providerID:PROVIDER_ID
vehicleID:vehicleID
navigator:_mapView.navigator];
GMTDDeliveryDriverAPI *deliveryDriverAPI = [[GMTDDeliveryDriverAPI alloc] initWithDriverContext:driverContext];
}
الاستماع بشكل اختياري إلى أحداث AutomotiveReporter
تُحدِّث "GMTDDeliveryVehicleReporter
" المركبة بشكل دوري في حال
locationTrackingEnabled
هي نعم. للاستجابة لهذه التحديثات الدورية، سيتم
يمكن للعنصر الاشتراك في أحداث GMTDDeliveryVehicleReporter
من خلال التوافق مع
بروتوكول GMTDVehicleReporterListener
.
يمكنك التعامل مع الأحداث التالية:
vehicleReporter:didSucceedVehicleUpdate
تُبلغ تطبيق Driver بأنّ خدمات الخلفية قد تلقّت بنجاح وتحديث موقع المركبة والحالة.
vehicleReporter:didFailVehicleUpdate:withError
تُبلِغ المستمِع بتعذُّر تحديث المركبة. طالما أن الموقع تفعيل التتبُّع، وسيستمر
GMTDDeliveryVehicleReporter
في إرسال أحدث البيانات في خلفية Fleet Engine.
يتعامل المثال التالي مع هذه الأحداث:
SampleViewController.h
@interface SampleViewController : UIViewController<GMTDVehicleReporterListener>
@end
SampleViewController.m
#import “SampleViewController.h”
#import “SampleAccessTokenProvider.h”
#import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
@implementation SampleViewController {
GMSMapView *_mapView;
}
- (void)viewDidLoad {
// ASSUMES YOU IMPLEMENTED HAVE THE SAMPLE CODE UP TO THIS STEP.
[ridesharingDriverAPI.vehicleReporter addListener:self];
}
- (void)vehicleReporter:(GMTDDeliveryVehicleReporter *)vehicleReporter didSucceedVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate {
// Handle update succeeded.
}
- (void)vehicleReporter:(GMTDDeliveryVehicleReporter *)vehicleReporter didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate withError:(NSError *)error {
// Handle update failed.
}
@end
تفعيل تتبع الموقع الجغرافي
لتفعيل ميزة تتبُّع الموقع الجغرافي، يمكن لتطبيقك ضبط locationTrackingEnabled
على YES
.
في GMTDDeliveryVehicleReporter
. بعد ذلك، سيكون GMTDDeliveryVehicleReporter
=
إرسال تحديثات الموقع تلقائيًا. عندما تكون "GMSNavigator
" في وضع التنقّل
وضع (عند تحديد وجهة من خلال setDestinations
)
تم ضبط locationTrackingEnabled
على YES
، وسيتضمن GMTDDeliveryVehicleReporter
إرسال تحديثات المسار والوقت المقدر للوصول تلقائيًا أيضًا.
سيكون المسار الذي تم ضبطه أثناء هذه التحديثات هو المسار نفسه الذي يسلكه السائق.
الانتقال إليه أثناء جلسة التنقل. وبالتالي، لكي تعمل ميزة تتبُّع الشحن
بشكل صحيح، يجب أن تتطابق النقطة الوسيطة المحددة من خلال -setDestinations:callback:
مع
البيانات المحددة في خلفية Fleet Engine.
يوضّح المثال التالي ميزة تتبُّع الموقع الجغرافي:
SampleViewController.m
#import “SampleViewController.h”
#import “SampleAccessTokenProvider.h”
#import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
@implementation SampleViewController {
GMSMapView *_mapView;
}
- (void)viewDidLoad {
// ASSUMES YOU IMPLEMENTED HAVE THE SAMPLE CODE UP TO THIS STEP.
deliveryDriverAPI.vehicleReporter.locationTrackingEnabled = YES;
}
@end
بشكل افتراضي، يبلغ الفاصل الزمني لإعداد التقارير 10 ثوانٍ، ولكن يمكن
مع locationUpdateInterval
. الحدّ الأدنى للفاصل الزمني المتوافق مع التحديثات
5 ثوانٍ. يبلغ الحدّ الأقصى للفاصل الزمني المسموح به للتحديث 60 ثانية. أكثر تكرارًا
إلى إبطاء الطلبات والأخطاء.
إيقاف تحديثات الموقع الجغرافي
يمكن لتطبيقك إيقاف تحديثات الموقع الجغرافي لمركبة. على سبيل المثال، عندما
تنتهي وردية عمل السائق، يمكن لتطبيقك ضبط locationTrackingEnabled
على NO
.
_vehicleReporter.locationTrackingEnabled = NO
التعامل مع أخطاء update_mask
عندما يرسل "GMTDDeliveryVehicleReporter
" معلومات جديدة عن المركبة، update_mask
عندما يكون القناع فارغًا، وعادةً ما يحدث ذلك في أول
التحديث بعد بدء التشغيل. يوضح المثال التالي كيفية التعامل مع هذا الخطأ:
Swift
import GoogleRidesharingDriver
class VehicleReporterListener: NSObject, GMTDVehicleReporterListener {
func vehicleReporter(
_ vehicleReporter: GMTDVehicleReporter,
didFail vehicleUpdate: GMTDVehicleUpdate,
withError error: Error
) {
let fullError = error as NSError
if let innerError = fullError.userInfo[NSUnderlyingErrorKey] as? NSError {
let innerFullError = innerError as NSError
if innerFullError.localizedDescription.contains("update_mask cannot be empty") {
emptyMaskUpdates += 1
return
}
}
failedUpdates += 1
}
override init() {
emptyMaskUpdates = 0
failedUpdates = 0
}
}
Objective-C
#import "VehicleReporterListener.h"
#import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
@implementation VehicleReporterListener {
NSInteger emptyMaskUpdates = 0;
NSInteger failedUpdates = 0;
}
- (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter
didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate
withError:(NSError *)error {
for (NSError *underlyingError in error.underlyingErrors) {
if ([underlyingError.localizedDescription containsString:@"update_mask cannot be empty"]) {
emptyMaskUpdates += 1;
return;
}
}
failedUpdates += 1
}
@end