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

Transition to Swift #253

Open
yvbeek opened this issue Jun 24, 2020 · 10 comments
Open

Transition to Swift #253

yvbeek opened this issue Jun 24, 2020 · 10 comments
Labels
🗣 Discussion This label identifies an ongoing discussion on a subject

Comments

@yvbeek
Copy link

yvbeek commented Jun 24, 2020

Introduction

When development on React-Native started, Objective-C was the primary language for all iOS apps. On June 2, 2014, a little under a year before the first public release of React-Native, Apple's new programming language Swift was introduced to the world.

The first few versions of Swift were not ready for production apps. New releases often introduced code breaking changes and I think we all have "fond" memories of the Xcode SourceKit crashes and other stability issues.

Fast forward to March 2019, Swift 5 was introduced with ABI stability. Many developers have now adopted the language and Apple is pushing the language forward with a new Swift-only UI framework called SwiftUI. During WWDC 2020 we learn that parts of MacOS Big Sur (for example the new control center) are implemented with SwiftUI.

Clearly Objective-C is moving into the background and the path forward is Swift. My proposal for React-Native would be to start moving into the same direction.

Details

When you create a new React-Native project, you are greeted by an Objective-C project. With some work you can convert the AppDelegate and other classes to Swift and you'll have to figure out how to get the Podfile properly configured for Swift <=> Objective-C interoperability.

This isn't a great experience for new developers starting with React-Native, nor for developers that already have a native app written in Swift and that want to transition to a multi-platform React-Native app.

When it comes to device support, the first iOS version able to run Swift apps was iOS 7. The minimum requirement for React-Native nowadays is iOS 10, therefor Swift support is not a problem.

But why Swift? I think there could be a lot to gain from the safety features that are built right into the Swift language. Code written in Swift is often shorter and uses a modern syntax that reduces code complexity.

Discussion points

  • What are the specific Objective-C features that React-Native is using (things like macros)?
  • What are up- and downsides of slowly transitioning the codebase to Swift?
  • What would be the best way to move towards a Swift codebase (new files in Swift, patch some code with extensions)?
  • How can we make React-Native more accessible to Swift developers?
  • How can we make it easier to create React-Native community packages in Swift?

(we could start a similar proposal for Android for Kotlin)

@yvbeek
Copy link
Author

yvbeek commented Jun 24, 2020

Linking to What don't you like about React-Native => Swift not being the default language for iOS
The comment is from June 2019 and at the time of writing has 212 upvotes

@kelset kelset added the 🗣 Discussion This label identifies an ongoing discussion on a subject label Jun 25, 2020
@kelset
Copy link
Member

kelset commented Jun 25, 2020

👋
So, a couple things:

  1. I feel that this is basically a duplicate of Make ejected iOS app a Swift app, not Objective-C #82 so maybe post this instead on that conversation? They are both on this topic.

  2. The FB team actually replied to the comment you are linking, here: Reply from Facebook about "What do you dislike about React Native?" #104

In particular, I'll quote here the response:

At the moment we are using Objective-C and Java for our codebases at Facebook and we cannot add either Swift or Kotlin to our apps. Since Facebook runs React Native from master, we cannot at the moment rewrite React Native to use either Swift or Kotlin. With our work on Fabric we are actually moving more code from Objective-C and Java to C++ and members of the community have expressed their interest in building alternative app templates that will use Swift and Kotlin instead of Objective-C and Java. There is no timeline for this work.

I haven't heard anything on this topic anywhere so my assumption is that the situation hasn't changed. Because of the two above reasons I think this issue should be closed.

@mrousavy
Copy link
Member

mrousavy commented Aug 25, 2020

For the record, in many cases Objective-C is still "faster" than Swift.

EDIT: I capped. 🧢 In many cases Swift is faster than Objective-C.

@yvbeek
Copy link
Author

yvbeek commented Aug 25, 2020

For the record, in many cases Objective-C is still "faster" than Swift.

With Swift 5+ there are plenty of scenarios where Swift is now faster than Objective-C. With every new Swift release this will improve in favor of Swift. For performance critical code a lot of companies still use C(++).

Note that in my post I'm proposing a slow transition to Swift. If there are a few specific scenarios where it still makes more sense to use Objective-C, then use Objective-C for that. The use of Swift doesn't cancel out the use of Objective-C.

I just find it very odd that when you create a new React-Native project that it creates the AppDelegate etc. in Objective-C instead of Swift. I think it would also improve the quality of the community components if it is easier to set those up with Swift and Kotlin.

@mrousavy
Copy link
Member

mrousavy commented Aug 25, 2020

That's definitely true. I had a pretty hard time creating my native modules, since there is little to no documentation for this, especially not for Swift. Also Swift doesn't support Macros, which requires us to have Objective-C headers and Bridges in every native module. Probably the biggest problem is that Swift doesn't easily interop with C++, which is where React Native is heading with the Re-Architecture.

tbh I'm not really up to date with the current performance differences between Objective-C and Swift 5, I've just always thought Objective-C had less overhead and was a better choice if speed really matters a lot.

@yvbeek
Copy link
Author

yvbeek commented Aug 25, 2020

But I had a pretty hard time creating those native modules, since there is little to no documentation for this, especially not for Swift. Also Swift doesn't support Macros, which requires us to have Objective-C headers and Bridges in every native module.

Yes, that's one of my main concerns and why I decided to write this proposal. Right now it is kinda difficult to get started with Swift and Kotlin on React-Native. I think that it will hurt React-Native's adoption at some point.

This project has helped me to set up a few RN libraries:
https://github.com/react-native-community/bob

tbh I'm not really up to date with the current performance differences between Objective-C and Swift 5, I've just always thought Objective-C had less overhead and was a better choice if speed really matters a lot.

Swift 5 is performing a lot better than Swift 3. The performance differences are getting smaller with every release. It is unfortunate that Swift sometimes performs worse than Objective-C because of bridging in order to be compatible with Objective-C (examples: String <=> NSString, Array <=> NSArray).

In the end there's no reason why a static language like Swift shouldn't outperform a dynamic language like Objective-C. You can never apply the same level of compiler optimization to a dynamic language.

@mrousavy
Copy link
Member

I believe the biggest blocker here is that Swift does not smoothly interop with C++ (which is the direction React Native is moving with the re-architecture), while Objective-C does. (Objective-C++, .mm) See:

@tom-sherman
Copy link

I think there are two different discussion points in this issue:

  1. Transitioning the React Native source code to Swift
  2. Making Swift-first React Native apps easy to create and maintain

I'd like to add mine and my team's 2c around point number 2:

Ideally we'd like to transition our React Native app to pure Swift. In our case this essentially means converting AppDelegate to Swift (and other stuff the OP mentions).

This is fine for us to do but it presents a challenge in staying up to date with new React Native versions - we'll need to translate the diff produced by https://github.com/react-native-community/rn-diff-purge to Swift on every release.

I believe teams would prefer to have their AppDelegate written in Swift and right now the fact that there doesn't exist a Swift template for react native is blocking them or causing duplicated work across the react native ecosystem.

My proposal is:

Convert the react native official template to be Swift-first and release this in a new react native version.

Alternative, maintain two official templates: one swift-first and one ObjectiveC-first. This may be required anyway to initially introduce the swift version to the community while gradually phasing out the ObjectiveC version.

@ergenekonyigit
Copy link

Apple announced C++ Interoperability in Swift 5.9 at WWDC 2023. Should we reconsider the transition to Swift?

@TheRogue76
Copy link

Apple announced C++ Interoperability in Swift 5.9 at WWDC 2023. Should we reconsider the transition to Swift?

I think we should at least start considering turning the templates over (Like the work done on the Kotlin side of things). Admittedly Swift 5.9 does require Xcode 15, which some users might not be using just yet, but Apple will enforce it's use from April 2024. so it's not that big of a blocker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗣 Discussion This label identifies an ongoing discussion on a subject
Projects
None yet
Development

No branches or pull requests

6 participants