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

General outline #3

Merged
merged 5 commits into from
Nov 18, 2016
Merged

General outline #3

merged 5 commits into from
Nov 18, 2016

Conversation

bsudekum
Copy link
Contributor

@bsudekum bsudekum commented Nov 16, 2016

@1ec5 okay this is a general working outline. Some notes on how the API will work:

  • Developers will subscribe to notifications:
  • alert level changes
  • progress changes
  • user reroutes
  • As a first iteration, we will not expose a voice controller
  • Because of this, there will be no translations

todo:

  • expose distance options
  • allow developer to specify location manager with options
  • Tests

/cc @pveugen

@@ -0,0 +1,155 @@
//
// MBNavigation.swift
Copy link
Contributor

Choose a reason for hiding this comment

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

Rename this file to MBNavigationController.swift for consistency. (You can drop MB from the file names if you want. The file names don't actually matter.)

// MapboxNavigation
//
// Created by Bobby Sudekum on 11/16/16.
// Copyright © 2016 Mapbox. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

Normally we don't include header blocks in our public code. If you do, make sure to change "All rights reserved" to something more appropriate when we decide on a license.

import CoreLocation
import MapboxDirections

open class NavigationController: NSObject {
Copy link
Contributor

Choose a reason for hiding this comment

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

Every public symbol will eventually need a documentation comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Every public class or enum needs an @objc(…) attribute that prefixes the class name with MB. Otherwise we'll pollute the class namespace in Objective-C.


locationManager.delegate = self
if CLLocationManager.authorizationStatus() == .notDetermined {
locationManager.requestWhenInUseAuthorization()
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the user has to manually press Accept in this case, the location manager calls a delegate method asynchronously when permission is given. Implement that method; otherwise, this library will do nothing in the case where the user hasn't already given permissions by the time NavigationController is initialized.

}

guard userIsOnRoute(location) else {
NotificationCenter.default.post(name: NavigationControllerNotification.rerouted, object: self, userInfo: [NavigationControllerNotification.rerouted : "rerouted"])
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the point of this "rerouted" key in the user info dictionary? It doesn't provide any additional information, so remove it.

import Foundation
import CoreLocation

public let NavigationControllerProgressDidChangeNotificationProgressKey = "progress"
Copy link
Contributor

Choose a reason for hiding this comment

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

These keys should be of type NavigationControllerNotificationUserInfoKey, which would be a new typedef of String.

public let NavigationControllerMaximumAllowedDegreeOffsetForTurnCompletion: Double = 30

// Alert distances
public let NavigationControllerMediumAlertNumberOfSeconds: Double = 70
Copy link
Contributor

Choose a reason for hiding this comment

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

These constants should be of type TimeInterval and "NumberOfSeconds" should become "Interval".

class ViewController: UIViewController, MGLMapViewDelegate, AVSpeechSynthesizerDelegate {

var destination: CLLocationCoordinate2D?
var directions = Directions(accessToken: "pk.eyJ1IjoiYm9iYnlzdWQiLCJhIjoiTi16MElIUSJ9.Clrqck--7WmHeqqvtFdYig")
Copy link
Contributor

Choose a reason for hiding this comment

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

Replace this string literal with a placeholder token. See the example project in MapboxDirections.swift for an example.

options.routeShapeResolution = .full

_ = directions.calculate(options) { [weak self] (waypoints, routes, error) in
if let route = routes?.first {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be a guard statement.

}

func getRoute() {
let options = RouteOptions(coordinates: [mapView.userLocation!.coordinate, destination!])
Copy link
Contributor

Choose a reason for hiding this comment

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

Use the automobileAvoidingTraffic profile identifier.

@1ec5
Copy link
Contributor

1ec5 commented Nov 17, 2016

In order to distribute this framework via CocoaPods, you'll need to add a podspec to the root of the repository. See MapboxDirections.swift for an example. Note that this podspec will directly require MapboxDirections but not Polyline (which would be a transitive dependency).

@bsudekum
Copy link
Contributor Author

Good first step here, going to merge this and begin documentation.

@bsudekum bsudekum merged commit 8abc6ca into master Nov 18, 2016
@bsudekum bsudekum deleted the newnewnew branch November 18, 2016 00:31
S2Ler added a commit that referenced this pull request May 24, 2021
The method is part of the public SDK API, and there are no guarantees
that it will be called in a thread-safe manner. The fact current
implementation isn't thread-safe was proofed by running a test with
Thread Sanitizer (TSan) enabled (see the log at the end).

- UnimplementedLogging.logUnimplemented reimplemented so that it is safe
to use from multiple threads.
- Adds a test to verify that the new implementation is safe.
- Adds a test to catch performance regressions in implementation.

Below is a log from TSan when run for old implementation:
```
WARNING: ThreadSanitizer: Swift access race (pid=14419)
  Modifying access of Swift variable at 0x00010a65a7a0 by thread T2:
    #0 UnimplementedLogging.logUnimplemented(protocolType:level:function:) <null>:12416464 (MapboxCoreNavigationTests:arm64+0x3a7464)
    #1 func1() in UnimplementedClass #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:9 (MapboxCoreNavigationTests:arm64+0xb26f4)
    #2 closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:24 (MapboxCoreNavigationTests:arm64+0xb1e9c)
    #3 partial apply for closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() <compiler-generated> (MapboxCoreNavigationTests:arm64+0xb1f34)
    #4 partial apply for thunk for @callee_guaranteed (@unowned Int) -> () <null>:12416464 (libswiftDispatch.dylib:arm64+0x5030)
    #5 _dispatch_client_callout2 <null>:12416464 (libdispatch.dylib:arm64+0x3d80)

  Previous read of size 8 at 0x00010a65a7a0 by thread T4:
    #0 UnimplementedLogging.logUnimplemented(protocolType:level:function:) <null>:12416464 (MapboxCoreNavigationTests:arm64+0x3a6f9c)
    #1 func1() in UnimplementedClass #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:9 (MapboxCoreNavigationTests:arm64+0xb26f4)
    #2 closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:24 (MapboxCoreNavigationTests:arm64+0xb1e9c)
    #3 partial apply for closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() <compiler-generated> (MapboxCoreNavigationTests:arm64+0xb1f34)
    #4 partial apply for thunk for @callee_guaranteed (@unowned Int) -> () <null>:12416464 (libswiftDispatch.dylib:arm64+0x5030)
    #5 _dispatch_client_callout2 <null>:12416464 (libdispatch.dylib:arm64+0x3d80)

  Location is global 'warned' at 0x00010a65a7a0 (MapboxCoreNavigationTests+0x000000e3a7a0)

  Thread T2 (tid=3981887, running) is a GCD worker thread

  Thread T4 (tid=3981890, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (MapboxCoreNavigationTests:arm64+0x3a7464) in UnimplementedLogging.logUnimplemented(protocolType:level:function:)+0x770
```
S2Ler added a commit that referenced this pull request May 28, 2021
The method is part of the public SDK API, and there are no guarantees
that it will be called in a thread-safe manner. The fact current
implementation isn't thread-safe was proofed by running a test with
Thread Sanitizer (TSan) enabled (see the log at the end).

- UnimplementedLogging.logUnimplemented reimplemented so that it is safe
to use from multiple threads.
- Adds a test to verify that the new implementation is safe.
- Adds a test to catch performance regressions in implementation.

Below is a log from TSan when run for old implementation:
```
WARNING: ThreadSanitizer: Swift access race (pid=14419)
  Modifying access of Swift variable at 0x00010a65a7a0 by thread T2:
    #0 UnimplementedLogging.logUnimplemented(protocolType:level:function:) <null>:12416464 (MapboxCoreNavigationTests:arm64+0x3a7464)
    #1 func1() in UnimplementedClass #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:9 (MapboxCoreNavigationTests:arm64+0xb26f4)
    #2 closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:24 (MapboxCoreNavigationTests:arm64+0xb1e9c)
    #3 partial apply for closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() <compiler-generated> (MapboxCoreNavigationTests:arm64+0xb1f34)
    #4 partial apply for thunk for @callee_guaranteed (@unowned Int) -> () <null>:12416464 (libswiftDispatch.dylib:arm64+0x5030)
    #5 _dispatch_client_callout2 <null>:12416464 (libdispatch.dylib:arm64+0x3d80)

  Previous read of size 8 at 0x00010a65a7a0 by thread T4:
    #0 UnimplementedLogging.logUnimplemented(protocolType:level:function:) <null>:12416464 (MapboxCoreNavigationTests:arm64+0x3a6f9c)
    #1 func1() in UnimplementedClass #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:9 (MapboxCoreNavigationTests:arm64+0xb26f4)
    #2 closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:24 (MapboxCoreNavigationTests:arm64+0xb1e9c)
    #3 partial apply for closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() <compiler-generated> (MapboxCoreNavigationTests:arm64+0xb1f34)
    #4 partial apply for thunk for @callee_guaranteed (@unowned Int) -> () <null>:12416464 (libswiftDispatch.dylib:arm64+0x5030)
    #5 _dispatch_client_callout2 <null>:12416464 (libdispatch.dylib:arm64+0x3d80)

  Location is global 'warned' at 0x00010a65a7a0 (MapboxCoreNavigationTests+0x000000e3a7a0)

  Thread T2 (tid=3981887, running) is a GCD worker thread

  Thread T4 (tid=3981890, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (MapboxCoreNavigationTests:arm64+0x3a7464) in UnimplementedLogging.logUnimplemented(protocolType:level:function:)+0x770
```
S2Ler added a commit that referenced this pull request May 28, 2021
The method is part of the public SDK API, and there are no guarantees
that it will be called in a thread-safe manner. The fact current
implementation isn't thread-safe was proofed by running a test with
Thread Sanitizer (TSan) enabled (see the log at the end).

- UnimplementedLogging.logUnimplemented reimplemented so that it is safe
to use from multiple threads.
- Adds a test to verify that the new implementation is safe.
- Adds a test to catch performance regressions in implementation.

Below is a log from TSan when run for old implementation:
```
WARNING: ThreadSanitizer: Swift access race (pid=14419)
  Modifying access of Swift variable at 0x00010a65a7a0 by thread T2:
    #0 UnimplementedLogging.logUnimplemented(protocolType:level:function:) <null>:12416464 (MapboxCoreNavigationTests:arm64+0x3a7464)
    #1 func1() in UnimplementedClass #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:9 (MapboxCoreNavigationTests:arm64+0xb26f4)
    #2 closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:24 (MapboxCoreNavigationTests:arm64+0xb1e9c)
    #3 partial apply for closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() <compiler-generated> (MapboxCoreNavigationTests:arm64+0xb1f34)
    #4 partial apply for thunk for @callee_guaranteed (@unowned Int) -> () <null>:12416464 (libswiftDispatch.dylib:arm64+0x5030)
    #5 _dispatch_client_callout2 <null>:12416464 (libdispatch.dylib:arm64+0x3d80)

  Previous read of size 8 at 0x00010a65a7a0 by thread T4:
    #0 UnimplementedLogging.logUnimplemented(protocolType:level:function:) <null>:12416464 (MapboxCoreNavigationTests:arm64+0x3a6f9c)
    #1 func1() in UnimplementedClass #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:9 (MapboxCoreNavigationTests:arm64+0xb26f4)
    #2 closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() UnimplementedLoggingTests.swift:24 (MapboxCoreNavigationTests:arm64+0xb1e9c)
    #3 partial apply for closure #1 in UnimplementedLoggingTests.testUnimplementedLoggingMultithreaded() <compiler-generated> (MapboxCoreNavigationTests:arm64+0xb1f34)
    #4 partial apply for thunk for @callee_guaranteed (@unowned Int) -> () <null>:12416464 (libswiftDispatch.dylib:arm64+0x5030)
    #5 _dispatch_client_callout2 <null>:12416464 (libdispatch.dylib:arm64+0x3d80)

  Location is global 'warned' at 0x00010a65a7a0 (MapboxCoreNavigationTests+0x000000e3a7a0)

  Thread T2 (tid=3981887, running) is a GCD worker thread

  Thread T4 (tid=3981890, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (MapboxCoreNavigationTests:arm64+0x3a7464) in UnimplementedLogging.logUnimplemented(protocolType:level:function:)+0x770
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants