Uber Rides iOS SDK
这个 Swift 库 允许您在 iOS 应用程序中集成 Uber Rides API。
要求
- iOS 8.0+
- Xcode 10.0+
- Swift 4.2+
安装 Uber Rides SDK
要安装 Uber Rides SDK,您可以使用 CocoaPods,Carthage 或将您手动添加到项目中
pod 'UberRides', '~> 0.13'
Carthage
github "uber/rides-ios-sdk" ~> 0.13
入门指南
SDK 配置
要开始使用 Uber API 联系,您需要在 Uber 开发者站点 上注册应用程序并获得您的应用程序凭据。
然后,使用 Uber SDK 的相关信息配置您的 Xcode。找到您的应用程序的 Info.plist 文件。右键单击此文件并选择 打开方式 > 源代码
添加以下代码片段,将方括号内的占位符替换为从开发者仪表板获取的应用程序信息。(注意:不要包含方括号)
<key>UberClientID</key>
<string>[ClientID]</string>
<key>UberServerToken</key>
<string>[Server Token]</string>
<key>UberDisplayName</key>
<string>[App Name]</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>uber</string>
<string>uberauth</string>
</array>
注意:当您的用户尚未与 Uber 进行身份验证时,您的 服务器令牌
用于 价格 和 时间 估计。我们建议只有在您需要在用户登录之前获取估计值时才将其添加到您的 Info.plist
中。
行程请求按钮
RideRequestButton
是显示 Uber 产品价格和时间的简单方式,可以自定义以执行各种操作。按钮接受 RideParameters
,可以描述产品 ID、接车地点和下车地点。默认情况下,按钮不显示任何信息。
要显示时间估计,设置产品 ID 和接车地点。要显示价格估计,您还需要设置下车地点。
将库导入到您的项目中,并像添加任何其他 UIView 一样将行程请求按钮添加到您的视图中
// Swift
import UberRides
let button = RideRequestButton()
view.addSubview(button)
// Objective-C
@import UberRides;
UBSDKRideRequestButton *button = [[UBSDKRideRequestButton alloc] init];
[view addSubview:button];
这将创建一个具有默认行为的请求按钮,拣选针设置为用户的当前位置。当用户切换到 Uber 应用程序时,他们将需要选择产品并输入其他信息。
使用 RideParameters 添加参数
该SDK为定义你的行程请求提供了一个简单的对象。 RideParameters
对象允许你指定上车地点、下车地点、产品ID等信息。使用RideParametersBuilder
对象创建RideParameters
非常简单。
// Swift
import UberRides
import CoreLocation
let builder = RideParametersBuilder()
let pickupLocation = CLLocation(latitude: 37.787654, longitude: -122.402760)
let dropoffLocation = CLLocation(latitude: 37.775200, longitude: -122.417587)
builder.pickupLocation = pickupLocation
builder.dropoffLocation = dropoffLocation
builder.dropoffNickname = "Somewhere"
builder.dropoffAddress = "123 Fake St."
let rideParameters = builder.build()
let button = RideRequestButton(rideParameters: rideParameters)
// Objective-C
@import UberRides;
@import CoreLocation;
UBSDKRideParametersBuilder *builder = [[UBSDKRideParametersBuilder alloc] init];
CLLocation *pickupLocation = [[CLLocation alloc] initWithLatitude:37.787654 longitude:-122.402760];
CLLocation *dropoffLocation = [[CLLocation alloc] initWithLatitude:37.775200 longitude:-122.417587];
[builder setPickupLocation:pickupLocation];
[builder setDropoffLocation:dropoffLocation];
[builder setDropoffAddress:@"123 Fake St."];
[builder setDropoffNickname:@"Somewhere"];
UBSDKRideParameters *rideParameters = [builder build];
UBSDKRideRequestButton *button = [[UBSDKRideRequestButton alloc] initWithRideParameters:rideParameters];
我们建议传递额外的参数,以使您的用户体验更加无缝。例如,可以使用下车地点参数自动将用户的目的地信息传递给司机。设置所有必要的参数后,点击按钮将无缝提示行程请求确认界面。
注意:如果您使用的是 Deeplink 到 Uber 应用程序的RideRequestButton
并且需要指定一个下车地点,您必须提供该位置的昵称或格式化地址。否则,将不会显示标记。
您还可以使用RideRequestButtonDelegate
来在按钮刷新期间接收成功和失败事件的通知。
行程请求Deeplink
如果您不想使用Uber提供的按钮,也可以像上面那样手动发起类似的deeplink
// Swift
import UberRides
import CoreLocation
let builder = RideParametersBuilder()
// ...
let rideParameters = builder.build()
let deeplink = RequestDeeplink(rideParameters: rideParameters)
deeplink.execute()
// Objective-C
@import UberRides;
@import CoreLocation;
UBSDKRideParametersBuilder *builder = [[UBSDKRideParametersBuilder alloc] init];
// ...
UBSDKRideParameters *rideParameters = [builder build];
UBSDKRequestDeeplink *deeplink = [[UBSDKRequestDeeplink alloc] initWithRideParameters:rideParameters];
[deeplink executeWithCompletion:nil];
使用行程请求deeplink,您可以指定那些没有安装Uber应用的用户的可选方案。有了可选方案,他们会重定向到Uber的移动网页版本或App Store。要这样做,只需添加fallbackType
参数
// Swift
let deeplink = RequestDeeplink(rideParameters: rideParameters, fallbackType: .mobileWeb) // Or .appStore
// Objective-C
UBSDKRequestDeeplink *requestDeeplink = [[UBSDKRequestDeeplink alloc] initWithRideParameters:rideParameters
fallbackType:UBSDKDeeplinkFallbackTypeMobileWeb];
使用Uber登录
要使用SDK的其他任何功能,您需要让终端用户授权您的应用程序使用Uber API。
设置
首先,打开Uber开发者仪表板。转到授权选项卡,然后在应用程序签名下输入您的iOS应用程序的包标识。
我们还需要为您的应用程序注册一个重定向URL,以确保Uber在用户登录后将用户发送到正确的应用程序。创建以下格式的URL,并保存您的应用程序:YourApplicationBundleID://oauth/consumer
。
在您的Xcode项目中,您还需要将您的URL方案以及回调URL注册到Uber SDK中。将其复制到您的Info.plist
中,替换相关值
注意:如果以下键已在您的
Info.plist
文件中存在,您将不得不向它们添加值而不是复制键。
<key>UberCallbackURIs</key>
<array>
<dict>
<key>UberCallbackURIType</key>
<string>General</string>
<key>URIString</key>
<string>[Your Bundle ID Here]://oauth/consumer</string>
</dict>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>[Your Bundle ID Here]</string>
</array>
</dict>
</array>
您还需要修改您的应用程序的应用程序代理,以调用RidesAppDelegate
来处理URL。
// Swift
// Add the following calls to your AppDelegate
import UberCore
@available(iOS 9, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let handledUberURL = UberAppDelegate.shared.application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplicationOpenURLOptionsKey.annotation] as Any)
return handledUberURL
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let handledUberURL = UberAppDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
return handledUberURL
}
// Objective-C
// Add the following calls to your AppDelegate
@import UberCore;
// iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
BOOL handledURL = [[UBSDKAppDelegate shared] application:app open:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
return handledURL;
}
// iOS 8
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
BOOL handledURL = [[UBSDKAppDelegate shared] application:application open:url sourceApplication:sourceApplication annotation:annotation];
return handledURL;
}
登录按钮
登录按钮
是授权用户的一种简单方式。您需要向Uber请求一定的作用域或权限来初始化按钮。更多关于作用域信息。当用户点击按钮时,将执行登录操作。
您可以可选地设置一个LoginButtonDelegate
以接收登录/登出成功的通知。
// Swift
import UberCore
let scopes: [UberScope] = [.profile, .places, .request]
let loginManager = LoginManager(loginType: .native)
let loginButton = LoginButton(frame: CGRect.zero, scopes: scopes, loginManager: loginManager)
loginButton.presentingViewController = self
loginButton.delegate = self
view.addSubview(loginButton)
// Mark: LoginButtonDelegate
func loginButton(_ button: LoginButton, didLogoutWithSuccess success: Bool) {
// success is true if logout succeeded, false otherwise
}
func loginButton(_ button: LoginButton, didCompleteLoginWithToken accessToken: AccessToken?, error: NSError?) {
if let _ = accessToken {
// AccessToken Saved
} else if let error = error {
// An error occured
}
}
// Objective-C
@import UberCore;
NSArray<UBSDKScope *> *scopes = @[UBSDKScope.profile, UBSDKScope.places, UBSDKScope.request];
UBSDKLoginManager *loginManager = [[UBSDKLoginManager alloc] initWithLoginType:UBSDKLoginTypeNative];
UBSDKLoginButton *loginButton = [[UBSDKLoginButton alloc] initWithFrame:CGRectZero scopes:scopes loginManager:loginManager];
loginButton.presentingViewController = self;
[loginButton sizeToFit];
loginButton.delegate = self;
[self.view addSubview:loginButton];
#pragma mark - UBSDKLoginButtonDelegate
- (void)loginButton:(UBSDKLoginButton *)button didLogoutWithSuccess:(BOOL)success {
// success is true if logout succeeded, false otherwise
}
- (void)loginButton:(UBSDKLoginButton *)button didCompleteLoginWithToken:(UBSDKAccessToken *)accessToken error:(NSError *)error {
if (accessToken) {
// UBSDKAccessToken saved
} else if (error) {
// An error occured
}
}
自定义集成
如果想在应用程序中提供更定制化的体验,有几个类需要熟悉。阅读下面的内容,您将很快能开始请求行程!
Uber行程API端点
SDK暴露了Uber开发者文档中所有可用的端点。某些端点可以通过服务器令牌进行验证,但对于大多数端点,您将需要一个 bearer 令牌。可以通过隐式授权、授权代码授权或单点登录(SSO)检索 bearer 令牌。要授权特权作用域,必须使用授权代码授权或 SSO。
请参阅CocoaDocs中的完整API文档
RidesClient
是您访问Uber行程API中所有端点的来源。只需您的服务器令牌,您就可以获取Uber产品的列表以及价格和时间预估。
// Swift example
let ridesClient = RidesClient()
let pickupLocation = CLLocation(latitude: 37.787654, longitude: -122.402760)
ridesClient.fetchProducts(pickupLocation: pickupLocation, completion:{ products, response in
if let error = response.error {
// Handle error
return
}
for product in products {
// Use product
}
})
// Objective-C example
UBSDKRidesClient *ridesClient = [[UBSDKRidesClient alloc] init];
CLLocation *pickupLocation = [[CLLocation alloc] initWithLatitude: 37.787654 longitude: -122.402760];
[ridesClient fetchProductsWithPickupLocation: pickupLocation completion:^(NSArray<UBSDKProduct *> * _Nullable products, UBSDKResponse *response) {
if (response.error) {
// Handle error
return;
}
for (UBSDKProduct *product in products) {
// Use product
}
}];
原生/SOO授权
要访问更多有关端点,您需要让最终用户授权您的应用程序访问他们的Uber数据。
最简单的授权形式是使用.native
登录类型。它允许您请求特权作用域,并且如果您的用户已经登录Uber应用程序,则无需用户输入用户名和密码。它要求用户在设备上已经安装了原生的Uber应用。
本地身份验证可以通过Uber乘车出行主应用程序或Uber Eats应用程序进行。您还可以从一个应用程序回退到另一个应用程序,例如,如果用户在其设备上未安装UberEats应用程序,您可以通过Uber乘车出行主应用程序进行身份验证。
// Swift
let loginManager = LoginManager(loginType: .native, productFlowPriority: [UberAuthenticationProductFlow(.eats), UberAuthenticationProductFlow(.rides)])
// Objective-C
UBSDKUberAuthenticationProductFlow *eatsProduct = [[UBSDKUberAuthenticationProductFlow alloc] init:UberProductTypeEats];
UBSDKUberAuthenticationProductFlow *ridesProduct = [[UBSDKUberAuthenticationProductFlow alloc] init:UberProductTypeRides];
UBSDKLoginManager *loginManager = [[UBSDKLoginManager alloc] initWithLoginType:loginType productFlowPriority:@[ eatsProduct, ridesProduct ]];
LoginManager
默认使用主Uber乘车出行应用程序进行本地登录,因此您可以直接实例化一个LoginManager
并使用请求的作用域调用login()
方法。
// Swift
let loginManager = LoginManager()
loginManager.login(requestedScopes:[.request], presentingViewController: self, completion: { accessToken, error in
// Completion block. If accessToken is non-nil, you’re good to go
// Otherwise, error.code corresponds to the RidesAuthenticationErrorType that occured
})
// Objective-C
UBSDKLoginManager *loginManager = [[UBSDKLoginManager alloc] init];
[loginManager loginWithRequestedScopes:@[ UBSDKScope.request ] presentingViewController: self completion: ^(UBSDKAccessToken * _Nullable accessToken, NSError * _Nullable error) {
// Completion block. If accessToken is non-nil, you're good to go
// Otherwise, error.code corresponds to the RidesAuthenticationErrorType that occured
}];
注意:presentingViewController
参数是可选的,但如果提供了,将尝试智能地回退到另一种登录方法。否则,将重定向用户到App商店下载Uber应用程序。
认证方法 | 令牌类型 | 允许的作用域 |
---|---|---|
无 | 服务器 | 无(可以访问产品和预估) |
隐式授权 | Bearer | 通用 |
授权码授予 | Bearer | 特权通用 |
SSO | Bearer | 特权通用 |
自定义授权/令牌管理器
如果您的应用程序允许用户通过您的自定义逻辑进行授权,您需要手动创建一个AccessToken
并将其保存到密钥链中,使用TokenManager
。
// Swift
let accessTokenString = "access_token_string"
let token = AccessToken(tokenString: accessTokenString)
if TokenManager.save(accessToken: token) {
// Success
} else {
// Unable to save
}
// Objective-C
NSString *accessTokenString = @"access_token_string";
UBSDKAccessToken *token = [[UBSDKAccessToken alloc] initWithTokenString: accessTokenString];
if ([UBSDKTokenManager saveWithAccessToken: token]) {
// Success
} else {
// Unable to save
}
TokenManager
还可以用来获取和删除AccessToken
。
// Swift
TokenManger.fetchToken()
TokenManager.deleteToken()
// Objective-C
[UBSDKTokenManager fetchToken];
[UBSDKTokenManager deleteToken];
获取帮助
Uber开发者会积极监控StackOverflow上的Uber标签。如果您需要安装或使用库的帮助,可以在那里提问。确保用uber-api和ios标签您的问题!
关于我们API的完整文档,请访问我们的开发者网站。
贡献
我们
注意:所有贡献者都必须在我们可以合并您更改之前填写Uber贡献者许可协议。
请将任何pull请求针对develop
分支打开。
许可
Uber Rides iOS SDK 以 MIT 许可协议发布。请参阅 LICENSE 文件以了解更多详细信息。