Skip to content

Discontinue Objective-C compatibility #2231

Closed
@1ec5

Description

@1ec5
Contributor

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

Activity

added
op-exRefactoring, Tech Debt or any other operational excellence work.
on Sep 16, 2019
added this to the v1.0.0 milestone on Sep 16, 2019
1ec5

1ec5 commented on Sep 16, 2019

@1ec5
ContributorAuthor

Work is starting in #2230.

billyking991

billyking991 commented on Oct 17, 2019

@billyking991

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

1ec5 commented on Nov 3, 2019

@1ec5
ContributorAuthor

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.

pinned this issue on Jan 21, 2020
1ec5

1ec5 commented on Jan 21, 2020

@1ec5
ContributorAuthor

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

billyking991 commented on Jan 21, 2020

@billyking991

Thank you! I appreciate the info.

modified the milestones: v1.0.0, v0.x next on Apr 14, 2020
unpinned this issue on Jul 27, 2020
pinned this issue on Jul 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    op-exRefactoring, Tech Debt or any other operational excellence work.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Participants

      @JThramer@1ec5@billyking991

      Issue actions

        Discontinue Objective-C compatibility · Issue #2231 · mapbox/mapbox-navigation-ios