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

Discontinue Objective-C compatibility #2231

Closed
1ec5 opened this issue Sep 16, 2019 · 5 comments · Fixed by #2230
Closed

Discontinue Objective-C compatibility #2231

1ec5 opened this issue Sep 16, 2019 · 5 comments · Fixed by #2230
Labels
op-ex Refactoring, Tech Debt or any other operational excellence work.
Milestone

Comments

@1ec5
Copy link
Contributor

1ec5 commented Sep 16, 2019

We’re discontinuing support for applications written purely in Objective-C to use the iOS navigation SDK. The same change will take place in MapboxDirections.swift: mapbox/mapbox-directions-swift#381. Applications written in Objective-C will need to implement compatibility shims in Swift to continue to interoperate with this library.

Since #3, we’ve half-heartedly supported Objective-C by ensuring bridgeability of key APIs, but there are many gaps in coverage, and the public API in Objective-C feels like a translation from another language. A renewed focus on Swift will eliminate a major source of technical debt. We’ll be able to write more idiomatic, less error-prone Swift code without compromising the developer experience in both languages.

Hybrid application frameworks (such as React Native) are implemented in Objective-C. Discontinuing Objective-C support makes it more difficult – but not infeasible – for a developer to write a hybrid wrapper around the SDK. For instance, a React Native wrapper such as react-native-maps-navigation would need an additional compatibility shim written in Swift to translate the navigation SDK’s API to a more basic API that can bridge to Objective-C. Regardless, we do not officially support hybrid application frameworks.

Discontinuing Objective-C support will have the following immediate impacts on the codebase:

  • @objc attributes and MB class prefixes will disappear, except in some edge cases that require Objective-C method dispatch (for key-value observation).
  • Methods whose sole purpose is to bridge to Objective-C will disappear.
  • Enumeration declarations will move from Objective-C headers to Swift files.
  • References to Objective-C compatibility will be removed from readmes and jazzy guides.

We’ll hopefully be able to take advantage of some Swift language features in the process:

  • Convert value classes to structures or enumerations with associated types.
  • Convert abstract classes to protocols with default implementations.
  • Move global variables and global constants under structures and classes.
  • Replace magic default values with optionals.
  • Replace NSCoding with Codable.

/cc @mapbox/navigation-ios

@1ec5 1ec5 added op-ex Refactoring, Tech Debt or any other operational excellence work. Objective-C labels Sep 16, 2019
@1ec5 1ec5 added this to the v1.0.0 milestone Sep 16, 2019
@1ec5
Copy link
Contributor Author

1ec5 commented Sep 16, 2019

Work is starting in #2230.

@billyking991
Copy link

Do we know the last compatible SDK version with ObjC? I've got 37 installed, but 38 doesn't want to install properly using CocoaPods. I'm working on a complete rewrite with Swift, but I want to keep the ObjC project going while I'm working. What will the final ObjC compatible version be?

@1ec5
Copy link
Contributor Author

1ec5 commented Nov 3, 2019

v0.38.0 is still compatible with Objective-C. If you’re having difficulty installing it via CocoaPods, make sure your minimum deployment target is equal to or greater than this library’s minimum deployment target, which is iOS 10.0 following #2206.

We don’t currently have another release scheduled before we land #2230, which drops Objective-C support.

@1ec5 1ec5 pinned this issue Jan 21, 2020
@1ec5
Copy link
Contributor Author

1ec5 commented Jan 21, 2020

Hybrid application frameworks (such as React Native) are implemented in Objective-C. Discontinuing Objective-C support makes it more difficult – but not infeasible – for a developer to write a hybrid wrapper around the SDK. For instance, a React Native wrapper would need an additional compatibility shim written in Swift to translate the navigation SDK’s API to a more basic API that can bridge to Objective-C. Regardless, we do not officially support hybrid application frameworks.

If your application is written in Objective-C, the changes in v1.0.0-alpha.1 don’t mean you have to rewrite your application in Swift, though you’re certainly free to do so. But you would at a minimum need to write a compatibility shim around the parts of the navigation SDK’s public API that your application uses. For example, here’s a compatibility shim that allows an application to present a NavigationViewController navigating between a specific origin and destination:

@objcMembers class NavigationViewControllerProxy: NSObject {
    var origin: CLLocationCoordinate2D
    var destination: CLLocationCoordinate2D
    
    init(origin: CLLocationCoordinate2D, destination: CLLocationCoordinate2D) {
        self.origin = origin
        self.destination = destination
        super.init()
    }
    
    func present(from parentViewController: UIViewController, animated: Bool) {
        // Configure and present NavigationViewController like you would in Swift.
        let options = NavigationRouteOptions(coordinates: [origin, destination])
        Directions.shared.calculate(options) { (waypoints, routes, error) in
            guard let route = routes?.first else { return }
            let navigationViewController = NavigationViewController(for: route)
            navigationViewController.modalPresentationStyle = .fullScreen
            parentViewController.present(navigationViewController, animated: true, completion: nil)
        }
    }
}

You can adjust and expand upon this code snippet to suit your application’s needs. For example, you can modify NavigationViewControllerProxy.present(from:animated:) to set additional Directions API options or specify a NavigationOptions or additional Style subclasses. This proxy object could also conform to NavigationViewControllerDelegate, in case you need to respond to any location-related events coming out of the navigation service. This is not unlike how SwiftUI applications would interact with NavigationViewController.

@billyking991
Copy link

Thank you! I appreciate the info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
op-ex Refactoring, Tech Debt or any other operational excellence work.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants