Skip to content

Commit

Permalink
Add RideParametersBuilder (#182)
Browse files Browse the repository at this point in the history
* Make RideParameters immutable and add builder to mutate, addressing feedback in #177

* Remove circular dependency in builder

* Un-nest RideParametersBuilder
  • Loading branch information
edjiang authored Sep 15, 2017
1 parent a331223 commit 3be952f
Show file tree
Hide file tree
Showing 17 changed files with 337 additions and 186 deletions.
133 changes: 106 additions & 27 deletions source/UberRides/Model/RideParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,17 @@ import MapKit

/// Object to represent the parameters needed to request a ride.
@objc(UBSDKRideParameters) public class RideParameters: NSObject {

/// ProductID to use for the ride
@objc public var productID: String?
@objc public let productID: String?

/// The pickup location to use for the ride
@objc public let pickupLocation: CLLocation?

/// The nickname of the pickup location of the ride
@objc public var pickupNickname: String?
@objc public let pickupNickname: String?

/// The address of the pickup location of the ride
@objc public var pickupAddress: String?
@objc public let pickupAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public let pickupPlaceID: String?
Expand All @@ -46,48 +45,70 @@ import MapKit
@objc public let dropoffLocation: CLLocation?

/// The nickname of the dropoff location for the ride
@objc public var dropoffNickname: String?
@objc public let dropoffNickname: String?

/// The adress of the dropoff location of the ride
@objc public var dropoffAddress: String?
@objc public let dropoffAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public let dropoffPlaceID: String?

/// The unique identifier of the payment method selected by a user.
@objc public var paymentMethod: String?
@objc public let paymentMethod: String?

/// The unique identifier of the surge session for a user.
@objc public var surgeConfirmationID: String?

/// The source to use for attributing the ride
@objc public var source: String?
@objc public let surgeConfirmationID: String?

/// Upfront fare quote used to request a ride
@objc public var upfrontFare: UpfrontFare?
@objc public let upfrontFare: UpfrontFare?

convenience public override init() {
self.init(pickupLocation: nil, dropoffLocation: nil, pickupPlaceID: nil, dropoffPlaceID: nil)
}
/// The source to use for attributing the ride. Used internal to the SDK.
@objc var source: String?

@objc convenience public init(pickupLocation: CLLocation?, dropoffLocation: CLLocation?) {
self.init(pickupLocation: pickupLocation, dropoffLocation: dropoffLocation, pickupPlaceID: nil, dropoffPlaceID: nil)
@objc public func builder() -> RideParametersBuilder {
let builder = RideParametersBuilder()
builder.productID = productID
builder.pickupLocation = pickupLocation
builder.pickupNickname = pickupNickname
builder.pickupAddress = pickupAddress
builder.pickupPlaceID = pickupPlaceID
builder.dropoffLocation = dropoffLocation
builder.dropoffNickname = dropoffNickname
builder.dropoffAddress = dropoffAddress
builder.dropoffPlaceID = dropoffPlaceID
builder.paymentMethod = paymentMethod
builder.surgeConfirmationID = surgeConfirmationID
builder.source = source
builder.upfrontFare = upfrontFare
return builder
}

@objc convenience public init(pickupPlaceID: String?, dropoffPlaceID: String?) {
self.init(pickupLocation: nil, dropoffLocation: nil, pickupPlaceID: pickupPlaceID, dropoffPlaceID: dropoffPlaceID)
}

private init(pickupLocation: CLLocation?,
dropoffLocation: CLLocation?,
fileprivate init(productID: String?,
pickupLocation: CLLocation?,
pickupNickname: String?,
pickupAddress: String?,
pickupPlaceID: String?,
dropoffPlaceID: String?) {
dropoffLocation: CLLocation?,
dropoffNickname: String?,
dropoffAddress: String?,
dropoffPlaceID: String?,
paymentMethod: String?,
surgeConfirmationID: String?,
source: String?,
upfrontFare: UpfrontFare?) {
self.productID = productID
self.pickupLocation = pickupLocation
self.dropoffLocation = dropoffLocation
self.pickupNickname = pickupNickname
self.pickupAddress = pickupAddress
self.pickupPlaceID = pickupPlaceID
self.dropoffLocation = dropoffLocation
self.dropoffNickname = dropoffNickname
self.dropoffAddress = dropoffAddress
self.dropoffPlaceID = dropoffPlaceID

super.init()
self.paymentMethod = paymentMethod
self.surgeConfirmationID = surgeConfirmationID
self.source = source
self.upfrontFare = upfrontFare
}

var userAgent: String {
Expand All @@ -101,3 +122,61 @@ import MapKit
return userAgentString
}
}

// Builder for RideParameters
@objc(UBSDKRideParametersBuilder) public class RideParametersBuilder: NSObject {
/// ProductID to use for the ride
@objc public var productID: String?

/// The pickup location to use for the ride
@objc public var pickupLocation: CLLocation?

/// The nickname of the pickup location of the ride
@objc public var pickupNickname: String?

/// The address of the pickup location of the ride
@objc public var pickupAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public var pickupPlaceID: String?

/// The dropoff location to use for the ride
@objc public var dropoffLocation: CLLocation?

/// The nickname of the dropoff location for the ride
@objc public var dropoffNickname: String?

/// The adress of the dropoff location of the ride
@objc public var dropoffAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public var dropoffPlaceID: String?

/// The unique identifier of the payment method selected by a user.
@objc public var paymentMethod: String?

/// The unique identifier of the surge session for a user.
@objc public var surgeConfirmationID: String?

/// Upfront fare quote used to request a ride
@objc public var upfrontFare: UpfrontFare?

/// The source to use for attributing the ride. Used internal to the SDK.
@objc var source: String?

public func build() -> RideParameters {
return RideParameters(productID: productID,
pickupLocation: pickupLocation,
pickupNickname: pickupNickname,
pickupAddress: pickupAddress,
pickupPlaceID: pickupPlaceID,
dropoffLocation: dropoffLocation,
dropoffNickname: dropoffNickname,
dropoffAddress: dropoffAddress,
dropoffPlaceID: dropoffPlaceID,
paymentMethod: paymentMethod,
surgeConfirmationID: surgeConfirmationID,
source: source,
upfrontFare: upfrontFare)
}
}
13 changes: 2 additions & 11 deletions source/UberRides/RequestDeeplink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,10 @@ import UIKit
* Builds and executes a deeplink to the native Uber app to request a ride.
*/
@objc(UBSDKRequestDeeplink) public class RequestDeeplink: BaseDeeplink {

private let parameters: RideParameters
private let clientID: String

static let sourceString = "deeplink"

@objc public init(rideParameters: RideParameters = RideParameters()) {
parameters = rideParameters
clientID = Configuration.shared.clientID

if rideParameters.source == nil {
rideParameters.source = RequestDeeplink.sourceString
}
@objc public init(rideParameters: RideParameters = RideParametersBuilder().build()) {
rideParameters.source = rideParameters.source ?? RequestDeeplink.sourceString

let queryItems = RequestURLUtil.buildRequestQueryParameters(rideParameters)
let scheme = "uber"
Expand Down
8 changes: 4 additions & 4 deletions source/UberRides/RideRequestButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import CoreLocation
*/
required public init?(coder aDecoder: NSCoder) {
requestBehavior = DeeplinkRequestingBehavior()
rideParameters = RideParameters()
rideParameters = RideParametersBuilder().build()
super.init(coder: aDecoder)
}

Expand Down Expand Up @@ -116,7 +116,7 @@ import CoreLocation
- returns: An initialized RideRequestButton
*/
@objc public convenience init(client: RidesClient) {
self.init(client: client, rideParameters: RideParameters(), requestingBehavior: DeeplinkRequestingBehavior())
self.init(client: client, rideParameters: RideParametersBuilder().build(), requestingBehavior: DeeplinkRequestingBehavior())
}

/**
Expand All @@ -142,7 +142,7 @@ import CoreLocation
- returns: An initialized RideRequestButton
*/
@objc public convenience init(requestingBehavior: RideRequesting) {
self.init(client: RidesClient(), rideParameters: RideParameters(), requestingBehavior: requestingBehavior)
self.init(client: RidesClient(), rideParameters: RideParametersBuilder().build(), requestingBehavior: requestingBehavior)
}

//Mark: UberButton
Expand All @@ -156,7 +156,7 @@ import CoreLocation
- returns: An initialized RideRequestButton
*/
@objc public convenience init() {
self.init(client: RidesClient(), rideParameters: RideParameters(), requestingBehavior: DeeplinkRequestingBehavior())
self.init(client: RidesClient(), rideParameters: RideParametersBuilder().build(), requestingBehavior: DeeplinkRequestingBehavior())
}

/**
Expand Down
10 changes: 4 additions & 6 deletions source/UberRides/RideRequestView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ import CoreLocation
- returns: An initialized RideRequestView
*/
@objc public convenience override init(frame: CGRect) {
self.init(rideParameters: RideParameters(), accessToken: TokenManager.fetchToken(), frame: frame)
self.init(rideParameters: RideParametersBuilder().build(), accessToken: TokenManager.fetchToken(), frame: frame)
}

/**
Expand All @@ -121,11 +121,11 @@ import CoreLocation
- returns: An initialized RideRequestView
*/
@objc public convenience init() {
self.init(rideParameters: RideParameters(), accessToken: TokenManager.fetchToken(), frame: CGRect.zero)
self.init(rideParameters: RideParametersBuilder().build(), accessToken: TokenManager.fetchToken(), frame: CGRect.zero)
}

required public init?(coder aDecoder: NSCoder) {
rideParameters = RideParameters()
rideParameters = RideParametersBuilder().build()
let configuration = WKWebViewConfiguration()
configuration.processPool = Configuration.shared.processPool
webView = WKWebView(frame: CGRect.zero, configuration: configuration)
Expand All @@ -152,9 +152,7 @@ import CoreLocation

let tokenString = accessToken.tokenString

if rideParameters.source == nil {
rideParameters.source = RideRequestView.sourceString
}
rideParameters.source = rideParameters.source ?? RideRequestView.sourceString

let endpoint = Components.rideRequestWidget(rideParameters: rideParameters)
guard let request = Request(session: nil, endpoint: endpoint, bearerToken: tokenString) else {
Expand Down
8 changes: 3 additions & 5 deletions source/UberRides/RideRequestViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ import MapKit

super.init(coder: aDecoder)

let defaultRideParameters = RideParameters()
let defaultRideParameters = RideParametersBuilder()
defaultRideParameters.source = RideRequestViewController.sourceString

rideRequestView.rideParameters = defaultRideParameters
rideRequestView.rideParameters = defaultRideParameters.build()
}

/**
Expand All @@ -100,9 +100,7 @@ import MapKit

super.init(nibName: nil, bundle: nil)

if rideParameters.source == nil {
rideParameters.source = RideRequestViewController.sourceString
}
rideParameters.source = rideParameters.source ?? RideRequestViewController.sourceString

rideRequestView.rideParameters = rideParameters
rideRequestView.accessToken = TokenManager.fetchToken(identifier: accessTokenIdentifier, accessGroup: keychainAccessGroup)
Expand Down
2 changes: 1 addition & 1 deletion source/UberRides/RideRequestViewRequestingBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
*/
@objc public init(presentingViewController: UIViewController, loginManager: LoginManager) {
self.presentingViewController = presentingViewController
let rideRequestViewController = RideRequestViewController(rideParameters: RideParameters(), loginManager: loginManager)
let rideRequestViewController = RideRequestViewController(rideParameters: RideParametersBuilder().build(), loginManager: loginManager)
modalRideRequestViewController = ModalRideRequestViewController(rideRequestViewController: rideRequestViewController)
}

Expand Down
38 changes: 24 additions & 14 deletions source/UberRidesTests/APIManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,17 @@ class APIManagerTests: XCTestCase {
func testRequestBuilderAllParameters() {
let pickupLocation = CLLocation(latitude: pickupLat, longitude: pickupLong)
let dropoffLocation = CLLocation(latitude: dropoffLat, longitude: dropoffLong)
let rideParameters = RideParameters(pickupLocation: pickupLocation, dropoffLocation: dropoffLocation)
rideParameters.pickupNickname = pickupNickname
rideParameters.pickupAddress = pickupAddress
rideParameters.dropoffNickname = dropoffNickname
rideParameters.dropoffAddress = dropoffAddress
rideParameters.productID = productID
rideParameters.surgeConfirmationID = surgeConfirm
rideParameters.paymentMethod = paymentMethod
let builder = RideParametersBuilder()
builder.pickupLocation = pickupLocation
builder.pickupNickname = pickupNickname
builder.pickupAddress = pickupAddress
builder.dropoffLocation = dropoffLocation
builder.dropoffNickname = dropoffNickname
builder.dropoffAddress = dropoffAddress
builder.productID = productID
builder.surgeConfirmationID = surgeConfirm
builder.paymentMethod = paymentMethod
let rideParameters = builder.build()

guard let data = RideRequestDataBuilder(rideParameters: rideParameters).build() else {
XCTAssert(false)
Expand Down Expand Up @@ -261,8 +264,10 @@ class APIManagerTests: XCTestCase {
Test the POST /v1/requests endpoint.
*/
func testPostRequest() {
let rideParameters = RideParameters(pickupPlaceID: "home", dropoffPlaceID: nil)
rideParameters.productID = productID
let builder = RideParametersBuilder()
builder.pickupPlaceID = Place.home
builder.productID = productID
let rideParameters = builder.build()
let request = buildRequestForEndpoint(Requests.make(rideParameters: rideParameters))
XCTAssertEqual(request.httpMethod, Method.post.rawValue)
if let url = request.url {
Expand Down Expand Up @@ -304,8 +309,9 @@ class APIManagerTests: XCTestCase {
Tests the POST /v1/requests/estimate endpoint.
*/
func testPostRequestEstimate() {
let rideParameters = RideParameters(pickupPlaceID: "home", dropoffPlaceID: nil)
let request = buildRequestForEndpoint(Requests.estimate(rideParameters: rideParameters))
let builder = RideParametersBuilder()
builder.pickupPlaceID = Place.home
let request = buildRequestForEndpoint(Requests.estimate(rideParameters: builder.build()))
XCTAssertEqual(request.httpMethod, "POST")
if let url = request.url {
XCTAssertEqual(url.absoluteString, ExpectedEndpoint.PostRequestEstimate)
Expand Down Expand Up @@ -381,7 +387,9 @@ class APIManagerTests: XCTestCase {
Tests the PATCH /v1/requests/curent endpoint.
*/
func testPatchCurrentRequest() {
let rideParams = RideParameters(pickupPlaceID: Place.home, dropoffPlaceID: nil)
let builder = RideParametersBuilder()
builder.pickupPlaceID = Place.home
let rideParams = builder.build()
let request = buildRequestForEndpoint(Requests.patchCurrent(rideParameters: rideParams))
XCTAssertEqual(request.httpMethod, "PATCH")
if let url = request.url {
Expand Down Expand Up @@ -420,7 +428,9 @@ class APIManagerTests: XCTestCase {
Tests the PATCH /v1/requests/{request_id} endpoint.
*/
func testPatchRequestByID() {
let rideParams = RideParameters(pickupPlaceID: Place.home, dropoffPlaceID: nil)
let builder = RideParametersBuilder()
builder.pickupPlaceID = Place.home
let rideParams = builder.build()
let request = buildRequestForEndpoint(Requests.patchRequest(requestID: requestID, rideParameters: rideParams))
XCTAssertEqual(request.httpMethod, "PATCH")
if let url = request.url {
Expand Down
Loading

0 comments on commit 3be952f

Please sign in to comment.