Skip to content

Commit

Permalink
Make models optional (#213)
Browse files Browse the repository at this point in the history
* Make models optional. Update sample apps and CHANGELOG

* add more color to changelog

* Add empty string for when no detail text
  • Loading branch information
edjiang committed Feb 5, 2018
1 parent b39d907 commit 66d16aa
Show file tree
Hide file tree
Showing 25 changed files with 532 additions and 244 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,12 @@
# Change Log

## [0.9.0] TBD

### Changes

* All model properties are now Optionals.
* In Objective-C, `Double`, `Int`, and `Bool` are represented by NSNumber `boolValue`, `intValue`, and `doubleValue`. The `UBSDKDistanceUnavailable`, `UBSDKEstimateUnavailable`, and `UBSDKBearingUnavailable` constants are now removed.

## [0.8.1] 2018-01-31

### Fixes
Expand Down
Expand Up @@ -130,10 +130,11 @@ class AuthorizationCodeGrantExampleViewController: AuthorizationBaseViewControll
ridesClient.requestRide(parameters: builder.build(), completion: { ride, response in
DispatchQueue.main.async(execute: {
self.checkError(response)
if let ride = ride {
if let ride = ride,
let requestID = ride.requestID {
self.statusLabel.text = "Processing"

self.updateRideStatus(ride.requestID, index: 0)
self.updateRideStatus(requestID, index: 0)
} else {
self.requestButton.isEnabled = true
}
Expand Down
Expand Up @@ -210,18 +210,21 @@ extension ImplicitGrantExampleViewController: UITableViewDataSource {
return cell
case HistorySection:
let trip = history[indexPath.row]
let startCity = trip.startCity.name
let startTime = trip.startTime
let endTime = trip.endTime
let startCity = trip.startCity?.name ?? ""

let cell = tableView.dequeueReusableCell(withIdentifier: HistoryCell) ??
UITableViewCell(style: .default, reuseIdentifier: HistoryCell)
cell.textLabel?.text = startCity

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
cell.detailTextLabel?.text = "\(dateFormatter.string(from: startTime)) to \(dateFormatter.string(from: endTime))"
if let startTime = trip.startTime,
let endTime = trip.endTime {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
cell.detailTextLabel?.text = "\(dateFormatter.string(from: startTime)) to \(dateFormatter.string(from: endTime))"
} else {
cell.detailTextLabel?.text = ""
}

return cell
default:
Expand Down
4 changes: 0 additions & 4 deletions source/UberCore/UBSDKConstants.h
Expand Up @@ -22,8 +22,4 @@
#ifndef UBSDKConstants_h
#define UBSDKConstants_h

FOUNDATION_EXPORT double UBSDKDistanceUnavailable;
FOUNDATION_EXPORT NSInteger UBSDKEstimateUnavailable;
FOUNDATION_EXPORT NSInteger UBSDKBearingUnavailable;

#endif /* UBSDKConstants_h */
4 changes: 0 additions & 4 deletions source/UberCore/UBSDKConstants.m
Expand Up @@ -20,7 +20,3 @@
// THE SOFTWARE.

#import <Foundation/Foundation.h>

double UBSDKDistanceUnavailable = -INFINITY;
NSInteger UBSDKEstimateUnavailable = NSIntegerMin;
NSInteger UBSDKBearingUnavailable = NSIntegerMin;
34 changes: 27 additions & 7 deletions source/UberRides/Model/DistanceEstimate.swift
Expand Up @@ -24,19 +24,39 @@

// MARK: DistanceEstimate

import UberCore

/**
* Estimate information on an Uber trip.
*/
@objc(UBSDKDistanceEstimate) public class DistanceEstimate: NSObject, Codable {

/// Expected activity distance.
@objc public private(set) var distance: Double
@nonobjc public private(set) var distance: Double?

/// Expected activity distance.
@objc(distance) public var objc_distance: NSNumber? {
if let distance = distance {
return NSNumber(value: distance)
} else {
return nil
}
}

/// The unit of distance (mile or km).
@objc public private(set) var distanceUnit: String

@objc public private(set) var distanceUnit: String?

/// Expected activity duration (in seconds).
@nonobjc public private(set) var duration: Int?

/// Expected activity duration (in seconds).
@objc public private(set) var duration: Int
@objc(duration) public var objc_duration: NSNumber? {
if let duration = duration {
return NSNumber(value: duration)
} else {
return nil
}
}

enum CodingKeys: String, CodingKey {
case distance = "distance_estimate"
Expand All @@ -46,8 +66,8 @@

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
distance = try container.decode(Double.self, forKey: .distance)
distanceUnit = try container.decode(String.self, forKey: .distanceUnit)
duration = try container.decode(Int.self, forKey: .duration)
distance = try container.decodeIfPresent(Double.self, forKey: .distance)
distanceUnit = try container.decodeIfPresent(String.self, forKey: .distanceUnit)
duration = try container.decodeIfPresent(Int.self, forKey: .duration)
}
}
25 changes: 17 additions & 8 deletions source/UberRides/Model/Driver.swift
Expand Up @@ -30,19 +30,28 @@
@objc(UBSDKDriver) public class Driver: NSObject, Codable {

/// The first name of the driver.
@objc public private(set) var name: String
@objc public private(set) var name: String?

/// The URL to the photo of the driver.
@objc public private(set) var pictureURL: URL
@objc public private(set) var pictureURL: URL?

/// The formatted phone number for calling the driver.
@objc public private(set) var phoneNumber: String
@objc public private(set) var phoneNumber: String?

/// The formatted phone number for sending a SMS to the driver.
@objc public private(set) var smsNumber: String?

/// The driver's star rating out of 5 stars.
@objc public private(set) var rating: Double
@nonobjc public private(set) var rating: Double?

/// The driver's star rating out of 5 stars.
@objc(rating) public var objc_rating: NSNumber? {
if let rating = rating {
return NSNumber(value: rating)
} else {
return nil
}
}

enum CodingKeys: String, CodingKey {
case name = "name"
Expand All @@ -54,10 +63,10 @@

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
pictureURL = try container.decode(URL.self, forKey: .pictureURL)
phoneNumber = try container.decode(String.self, forKey: .phoneNumber)
name = try container.decodeIfPresent(String.self, forKey: .name)
pictureURL = try container.decodeIfPresent(URL.self, forKey: .pictureURL)
phoneNumber = try container.decodeIfPresent(String.self, forKey: .phoneNumber)
smsNumber = try container.decodeIfPresent(String.self, forKey: .smsNumber)
rating = try container.decode(Double.self, forKey: .rating)
rating = try container.decodeIfPresent(Double.self, forKey: .rating)
}
}
8 changes: 4 additions & 4 deletions source/UberRides/Model/PaymentMethod.swift
Expand Up @@ -44,10 +44,10 @@ struct PaymentMethods: Codable {
@objc public private(set) var paymentDescription: String?

/// Unique identifier of the payment method.
@objc public private(set) var methodID: String
@objc public private(set) var methodID: String?

/// The type of the payment method. See https://developer.uber.com/docs/v1-payment-methods.
@objc public private(set) var type: String
@objc public private(set) var type: String?

enum CodingKeys: String, CodingKey {
case paymentDescription = "description"
Expand All @@ -58,7 +58,7 @@ struct PaymentMethods: Codable {
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
paymentDescription = try container.decodeIfPresent(String.self, forKey: .paymentDescription)
methodID = try container.decode(String.self, forKey: .methodID)
type = try container.decode(String.self, forKey: .type)
methodID = try container.decodeIfPresent(String.self, forKey: .methodID)
type = try container.decodeIfPresent(String.self, forKey: .type)
}
}
4 changes: 2 additions & 2 deletions source/UberRides/Model/Place.swift
Expand Up @@ -34,10 +34,10 @@
@objc public static let work = "work"

/// Fully qualified address of the location.
@objc public private(set) var address: String
@objc public private(set) var address: String?

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
address = try container.decode(String.self, forKey: .address)
address = try container.decodeIfPresent(String.self, forKey: .address)
}
}
71 changes: 48 additions & 23 deletions source/UberRides/Model/PriceEstimate.swift
Expand Up @@ -50,52 +50,77 @@ struct PriceEstimates: Codable {
/// Expected activity distance (in miles).
@nonobjc public private(set) var distance: Double?

/// Expected activity distance (in miles). -1 if not present.
@objc(distance) public var objc_distance: Double {
return distance ?? UBSDKDistanceUnavailable
/// Expected activity distance (in miles).
@objc(distance) public var objc_distance: NSNumber? {
if let distance = distance {
return NSNumber(value: distance)
} else {
return nil
}
}

/// Expected activity duration (in seconds).
@nonobjc public private(set) var duration: Int?

/// Expected activity duration (in seconds). UBSDKEstimateUnavailable if not present.
@objc(duration) public var objc_duration: Int {
return duration ?? UBSDKEstimateUnavailable
/// Expected activity duration (in seconds).
@objc(duration) public var objc_duration: NSNumber? {
if let duration = duration {
return NSNumber(value: duration)
} else {
return nil
}
}

/// A formatted string representing the estimate in local currency. Could be range, single number, or "Metered" for TAXI.
@objc public private(set) var estimate: String?

/// Upper bound of the estimated price.
@nonobjc public private(set) var highEstimate: Int?

/// Upper bound of the estimated price. UBSDKEstimateUnavailable if not present.
@objc(highEstimate) public var objc_highEstimate: Int {
return highEstimate ?? UBSDKEstimateUnavailable
/// Upper bound of the estimated price.
@objc(highEstimate) public var objc_highEstimate: NSNumber? {
if let highEstimate = highEstimate {
return NSNumber(value: highEstimate)
} else {
return nil
}
}

/// Lower bound of the estimated price.
@nonobjc public private(set) var lowEstimate: Int?

/// Lower bound of the estimated price. UBSDKEstimateUnavailable if not present.
@objc(lowEstimate) public var objc_lowEstimate: Int {
return lowEstimate ?? UBSDKEstimateUnavailable
/// Lower bound of the estimated price.
@objc(lowEstimate) public var objc_lowEstimate: NSNumber? {
if let lowEstimate = lowEstimate {
return NSNumber(value: lowEstimate)
} else {
return nil
}
}

/// Display name of product. Ex: "UberBLACK".
@objc public private(set) var name: String?

/// Unique identifier representing a specific product for a given latitude & longitude.
@objc public private(set) var productID: String?

/// The unique identifier of the surge session for a user. Nil for no surge.
@objc public private(set) var surgeConfirmationID: String?

/// The URL a user must visit to accept surge pricing.
@objc public private(set) var surgeConfirmationURL: URL?

/// Expected surge multiplier (active if surge is greater than 1).
@objc public private(set) var surgeMultiplier: Double
@nonobjc public private(set) var surgeMultiplier: Double?

/// Expected surge multiplier (active if surge is greater than 1).
@objc(surgeMultiplier) public var objc_surgeMultiplier: NSNumber? {
if let surgeMultiplier = surgeMultiplier {
return NSNumber(value: surgeMultiplier)
} else {
return nil
}
}

enum CodingKeys: String, CodingKey {
case currencyCode = "currency_code"
Expand Down Expand Up @@ -123,6 +148,6 @@ struct PriceEstimates: Codable {
productID = try container.decodeIfPresent(String.self, forKey: .productID)
surgeConfirmationID = try container.decodeIfPresent(String.self, forKey: .surgeConfirmationID)
surgeConfirmationURL = try container.decodeIfPresent(URL.self, forKey: .surgeConfirmationURL)
surgeMultiplier = try container.decodeIfPresent(Double.self, forKey: .surgeMultiplier) ?? 1.0
surgeMultiplier = try container.decodeIfPresent(Double.self, forKey: .surgeMultiplier)
}
}

0 comments on commit 66d16aa

Please sign in to comment.