Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to Alamofire. Fixes #29 [skip ci] #30

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class ViewController: UIViewController {
let request = MBDirectionsRequest(sourceCoordinate: mb, destinationCoordinate: wh)
request.version = .Four

directions = MBDirections(request: request, accessToken: MapboxAccessToken)
directions = MBDirections(accessToken: MapboxAccessToken)

directions!.calculateDirectionsWithCompletionHandler { (response, error) in
directions!.calculateDirectionsWithCompletionHandler(request) { (response, error) in
if let route = response?.routes.first {
print("Route summary:")
let steps = route.legs.first!.steps
Expand Down
2 changes: 1 addition & 1 deletion MapboxDirections.swift.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Pod::Spec.new do |s|
s.module_name = "MapboxDirections"

# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
s.dependency "NBNRequestKit"
s.dependency "Alamofire", "~> 3.0"
s.dependency "Polyline", "~> 3.0"

end
16 changes: 12 additions & 4 deletions MapboxDirections.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
8543D22E59F4F058585E18B9 /* Pods_MapboxDirectionsTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B856631C2DD5B041A03A48 /* Pods_MapboxDirectionsTests.framework */; };
910EA7231CB5734F00858D31 /* driving_dc_polyline.json in Resources */ = {isa = PBXBuildFile; fileRef = 910EA7221CB5734F00858D31 /* driving_dc_polyline.json */; };
9151CBAA1CB5A36C006CF17B /* Polyline.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 910EA7241CB5917000858D31 /* Polyline.framework */; };
9151CBAC1CB5C295006CF17B /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9151CBAB1CB5C295006CF17B /* Alamofire.framework */; };
BB44F9743C24BD97DFD53E9F /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 779CA65749150F5A75B46628 /* Pods.framework */; };
DA2133B21CAEEE3200AA2594 /* RequestKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA2133B11CAEEE3200AA2594 /* RequestKit.framework */; };
DA2133B31CAEEFE100AA2594 /* MapboxDirections.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA6C9D881CAE442B00094FBC /* MapboxDirections.framework */; };
DA2E03E91CB0E0B000D1269A /* MBDirectionsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E03E81CB0E0B000D1269A /* MBDirectionsResponse.swift */; };
DA2E03EB1CB0E13D00D1269A /* MBDirectionsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2E03EA1CB0E13D00D1269A /* MBDirectionsRequest.swift */; };
Expand Down Expand Up @@ -59,10 +59,10 @@
78F47212D6DC575EFAC36509 /* Pods-MapboxDirectionsTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MapboxDirectionsTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MapboxDirectionsTests/Pods-MapboxDirectionsTests.release.xcconfig"; sourceTree = "<group>"; };
910EA7221CB5734F00858D31 /* driving_dc_polyline.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = driving_dc_polyline.json; sourceTree = "<group>"; };
910EA7241CB5917000858D31 /* Polyline.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Polyline.framework; path = "../../Library/Developer/Xcode/DerivedData/MapboxDirections-cxcrsxhcoorbtxaohfcuxrgxzrsg/Build/Products/Debug-iphonesimulator/Polyline.framework"; sourceTree = "<group>"; };
9151CBAB1CB5C295006CF17B /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = "Pods/../build/Debug-iphoneos/Alamofire.framework"; sourceTree = "<group>"; };
A338BDE4A863FFF749998470 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
B2FF88ACFEC9E7E276EF93DA /* Pods-MapboxDirectionsTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MapboxDirectionsTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MapboxDirectionsTests/Pods-MapboxDirectionsTests.debug.xcconfig"; sourceTree = "<group>"; };
D4657820F4366F9DB1C432FB /* Pods-Unit Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Unit Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Unit Tests/Pods-Unit Tests.debug.xcconfig"; sourceTree = "<group>"; };
DA2133B11CAEEE3200AA2594 /* RequestKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RequestKit.framework; path = "Pods/../build/Debug-iphoneos/RequestKit.framework"; sourceTree = "<group>"; };
DA2E03E81CB0E0B000D1269A /* MBDirectionsResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MBDirectionsResponse.swift; sourceTree = "<group>"; };
DA2E03EA1CB0E13D00D1269A /* MBDirectionsRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MBDirectionsRequest.swift; sourceTree = "<group>"; };
DA6C9D881CAE442B00094FBC /* MapboxDirections.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MapboxDirections.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -90,8 +90,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9151CBAC1CB5C295006CF17B /* Alamofire.framework in Frameworks */,
9151CBAA1CB5A36C006CF17B /* Polyline.framework in Frameworks */,
DA2133B21CAEEE3200AA2594 /* RequestKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -119,8 +119,8 @@
4025371970E36C6D8BF67116 /* Frameworks */ = {
isa = PBXGroup;
children = (
9151CBAB1CB5C295006CF17B /* Alamofire.framework */,
910EA7241CB5917000858D31 /* Polyline.framework */,
DA2133B11CAEEE3200AA2594 /* RequestKit.framework */,
371BFE7855E3EA8B44CA2B5F /* Pods_Unit_Tests.framework */,
779CA65749150F5A75B46628 /* Pods.framework */,
72B856631C2DD5B041A03A48 /* Pods_MapboxDirectionsTests.framework */,
Expand Down Expand Up @@ -531,6 +531,10 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/build/Debug-iphoneos",
);
INFOPLIST_FILE = MapboxDirections/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
Expand All @@ -551,6 +555,10 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/build/Debug-iphoneos",
);
INFOPLIST_FILE = MapboxDirections/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
Expand Down
81 changes: 29 additions & 52 deletions MapboxDirections/MBDirections.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Alamofire
import CoreLocation

public typealias MBDirectionsHandler = (MBDirectionsResponse?, NSError?) -> Void
Expand All @@ -13,16 +14,18 @@ public enum MBDirectionsErrorCode: UInt {
case InvalidInput = 422
}

/**
A named coordinate commonly used to represent a waypoint
along a route
*/
public class MBPoint {

public let name: String?
public let coordinate: CLLocationCoordinate2D

internal init(name: String?, coordinate: CLLocationCoordinate2D) {
self.name = name
self.coordinate = coordinate
}

}

extension CLLocationCoordinate2D {
Expand All @@ -34,44 +37,32 @@ extension CLLocationCoordinate2D {

public class MBDirections: NSObject {

private let request: MBDirectionsRequest
private let configuration: MBDirectionsConfiguration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep this property for compatibility with MapKit. It's how client code knows that the object is already waiting for a request. Perhaps not the most elegant approach, but we should be deliberate about the places we diverge from MapKit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per voice, given the async'ness of requests this bit of compatibility with MapKit isn't worthwhile: our directions SDK doesn't have any good reason will permit concurrent requests and any kind of serialization would happen on the app level.

private var task: NSURLSessionDataTask?
public var calculating: Bool {
return task?.state == .Running
}

private var errorForSimultaneousRequests: NSError {
let userInfo = [
NSLocalizedFailureReasonErrorKey: "Cannot calculate directions on an MBDirections object that is already calculating.",
]
return NSError(domain: MBDirectionsErrorDomain, code: -1, userInfo: userInfo)
}

public init(request: MBDirectionsRequest, accessToken: String) {
self.request = request
public init(accessToken: String) {
Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders = ["User-Agent": "MapboxDirections.swift/0.4.0"]
configuration = MBDirectionsConfiguration(accessToken)
super.init()
}

public func calculateDirectionsWithCompletionHandler(completionHandler: MBDirectionsHandler) {
guard !calculating else {
completionHandler(nil, errorForSimultaneousRequests)
return
}
/**
Run a Directions API request against the web service, returning
the request and calling a completion handler on success or failure
*/
public func calculateDirectionsWithCompletionHandler(request: MBDirectionsRequest, completionHandler: MBDirectionsHandler) -> Request? {

var profileIdentifier = request.profileIdentifier
let version = request.version
let router: MBDirectionsRouter
switch version {
case .Four:
profileIdentifier = profileIdentifier.stringByReplacingOccurrencesOfString("/", withString: ".")
router = MBDirectionsRouter.V4(configuration, profileIdentifier, waypointsForDirections, request.requestsAlternateRoutes, nil, .Polyline, nil)
router = MBDirectionsRouter.V4(configuration, profileIdentifier, waypointsForDirections(request), request.requestsAlternateRoutes, nil, .Polyline, nil)
case .Five:
router = MBDirectionsRouter.V5(configuration, profileIdentifier, waypointsForDirections, request.requestsAlternateRoutes, .Polyline, .Full, true, nil)
router = MBDirectionsRouter.V5(configuration, profileIdentifier, waypointsForDirections(request), request.requestsAlternateRoutes, .Polyline, .Full, true, nil)
}

task = taskWithRouter(router, completionHandler: { (source, waypoints, destination, routes, error) in
return taskWithRouter(router, request: request, completionHandler: { (source, waypoints, destination, routes, request, error) in
let response = MBDirectionsResponse(source: source, waypoints: Array(waypoints), destination: destination, routes: routes.map {
MBRoute(source: source, waypoints: Array(waypoints), destination: destination, json: $0, profileIdentifier: profileIdentifier, version: version)
})
Expand All @@ -81,22 +72,18 @@ public class MBDirections: NSObject {
})
}

public func calculateETAWithCompletionHandler(completionHandler: MBETAHandler) {
guard !calculating else {
completionHandler(nil, errorForSimultaneousRequests)
return
}
public func calculateETAWithCompletionHandler(request: MBDirectionsRequest, completionHandler: MBETAHandler) -> Request? {

let router: MBDirectionsRouter
switch request.version {
case .Four:
let profileIdentifier = request.profileIdentifier.stringByReplacingOccurrencesOfString("/", withString: ".")
router = MBDirectionsRouter.V4(configuration, profileIdentifier, waypointsForDirections, false, nil, .None, false)
router = MBDirectionsRouter.V4(configuration, profileIdentifier, waypointsForDirections(request), false, nil, .None, false)
case .Five:
router = MBDirectionsRouter.V5(configuration, request.profileIdentifier, waypointsForDirections, false, .GeoJSON, .None, false, nil)
router = MBDirectionsRouter.V5(configuration, request.profileIdentifier, waypointsForDirections(request), false, .GeoJSON, .None, false, nil)
}

task = taskWithRouter(router, completionHandler: { (source, waypoints, destination, routes, error) in
return taskWithRouter(router, request: request, completionHandler: { (source, waypoints, destination, routes, request, error) in
let expectedTravelTime = routes.flatMap {
$0["duration"] as? NSTimeInterval
}.minElement()
Expand All @@ -111,7 +98,7 @@ public class MBDirections: NSObject {
})
}

private var waypointsForDirections: [MBDirectionsWaypoint] {
private func waypointsForDirections(request: MBDirectionsRequest) -> [MBDirectionsWaypoint] {
var sourceHeading: MBDirectionsWaypoint.Heading? = nil
if let heading = request.sourceHeading {
sourceHeading = MBDirectionsWaypoint.Heading(heading: heading, headingAccuracy: 90)
Expand All @@ -122,16 +109,13 @@ public class MBDirections: NSObject {
[MBDirectionsWaypoint(coordinate: request.destinationCoordinate, accuracy: nil, heading: nil)]].flatMap{ $0 }
}

private func taskWithRouter(router: MBDirectionsRouter, completionHandler completion: (MBPoint, [MBPoint], MBPoint, [JSON], NSError?) -> Void, errorHandler: (NSError?) -> Void) -> NSURLSessionDataTask? {
return router.loadJSON(JSON.self) { [weak self] (json, error) in
guard let dataTaskSelf = self where dataTaskSelf.task?.state == .Completed else {
return
}
private func taskWithRouter(router: MBDirectionsRouter, request: MBDirectionsRequest, completionHandler completion: (MBPoint, [MBPoint], MBPoint, [JSON], MBDirectionsRequest, NSError?) -> Void, errorHandler: (NSError?) -> Void) -> Request? {
let httpRequest = Alamofire.request(router).responseJSON { response in
let error = response.result.error
let json = response.result.value

guard error == nil && json != nil else {
dispatch_sync(dispatch_get_main_queue()) {
errorHandler(error as? NSError)
}
errorHandler(error)
return
}

Expand All @@ -153,9 +137,7 @@ public class MBDirections: NSObject {
NSLocalizedFailureReasonErrorKey: errorMessage!,
]
let apiError = NSError(domain: MBDirectionsErrorDomain, code: 200, userInfo: userInfo)
dispatch_sync(dispatch_get_main_queue()) {
errorHandler(apiError)
}
errorHandler(apiError)
return
}

Expand Down Expand Up @@ -195,14 +177,9 @@ public class MBDirections: NSObject {
var waypoints = points.suffixFrom(1)
waypoints = waypoints.prefixUpTo(waypoints.count)

dispatch_sync(dispatch_get_main_queue()) {
completion(source, Array(waypoints), destination, routes, error as? NSError)
}
completion(source, Array(waypoints), destination, routes, request, error)
}

return httpRequest
}

public func cancel() {
self.task?.cancel()
}

}
9 changes: 6 additions & 3 deletions MapboxDirections/MBDirectionsConfiguration.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import Foundation
import RequestKit

internal struct MBDirectionsConfiguration: Configuration {
internal struct MBDirectionsConfiguration {
internal var apiEndpoint: String = "https://api.mapbox.com"
internal var accessToken: String?

/**
Create a new configuration object.
- Parameter accessToken: a Mapbox access token is required to use the Mapbox Geocoding API
*/
internal init(_ accessToken: String) {
self.accessToken = accessToken
}
}
}
6 changes: 0 additions & 6 deletions MapboxDirections/MBDirectionsRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class MBDirectionsRequest {
case Automobile = "mapbox/driving"
case Walking = "mapbox/walking"
case Cycling = "mapbox/cycling"
// case Any = ""
}

public let sourceCoordinate: CLLocationCoordinate2D
Expand All @@ -29,11 +28,6 @@ public class MBDirectionsRequest {
}
}
public var profileIdentifier: String = MBDirectionsTransportType.Automobile.rawValue
// var departureDate: NSDate!
// var arrivalDate: NSDate!

// class func isDirectionsRequestURL
// func initWithContentsOfURL

public init(sourceCoordinate: CLLocationCoordinate2D, waypointCoordinates: [CLLocationCoordinate2D] = [], destinationCoordinate: CLLocationCoordinate2D, sourceHeading: CLLocationDirection? = nil) {
self.sourceCoordinate = sourceCoordinate
Expand Down
13 changes: 4 additions & 9 deletions MapboxDirections/MBDirectionsResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ public class MBDirectionsResponse: MBResponse {
}

public class MBRoute {
// var polyline: MKPolyline! { get }
public let legs: [MBRouteLeg]
// public let name: String
// var advisoryNotices: [AnyObject]! { get }
public let distance: CLLocationDistance
public let expectedTravelTime: NSTimeInterval
public var transportType: MBDirectionsRequest.MBDirectionsTransportType {
Expand Down Expand Up @@ -66,17 +63,14 @@ public class MBRoute {
}

public class MBRouteLeg {
// var polyline: MKPolyline! { get }
public let steps: [MBRouteStep]
public let name: String
// var advisoryNotices: [AnyObject]! { get }
public let distance: CLLocationDistance
public let expectedTravelTime: NSTimeInterval
public var transportType: MBDirectionsRequest.MBDirectionsTransportType {
return MBDirectionsRequest.MBDirectionsTransportType(rawValue: profileIdentifier) ?? .Automobile
}
public let profileIdentifier: String

public let source: MBPoint
public let destination: MBPoint

Expand All @@ -94,6 +88,9 @@ public class MBRouteLeg {
}

public class MBRouteStep {
/**
A maneuver is an action that is required along a route
*/
public enum ManeuverType: String {
case Turn = "turn"
case PassNameChange = "new name"
Expand Down Expand Up @@ -149,9 +146,7 @@ public class MBRouteStep {
}
}

// var polyline: MKPolyline! { get }
public let instructions: String
// var notice: String! { get }
public let distance: CLLocationDistance
public let transportType: MBDirectionsRequest.MBDirectionsTransportType
public let profileIdentifier: String
Expand Down Expand Up @@ -227,4 +222,4 @@ public class MBETAResponse: MBResponse {
self.destination = destination
self.expectedTravelTime = expectedTravelTime
}
}
}
Loading