From 6b50f70f56943243a1ed570c0202b5095e0f002f Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 18:18:23 +0100
Subject: [PATCH 01/13] chore: initial commit for RFC
---
proposals/0000-adding-support-for-swift.md | 58 ++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 proposals/0000-adding-support-for-swift.md
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
new file mode 100644
index 00000000..02c7f8ed
--- /dev/null
+++ b/proposals/0000-adding-support-for-swift.md
@@ -0,0 +1,58 @@
+---
+title: Title goes here
+author:
+- Jane Doe
+date: today
+---
+
+# RFC0000: Title goes here
+
+## Summary
+
+Brief explanation of the change.
+
+## Basic example
+
+If the proposal involves a new or changed API, include a basic code example. Omit this section if it's not applicable.
+
+## Motivation
+
+Why are we doing this? What use cases does it support? What is the expected outcome?
+
+Please focus on explaining the motivation so that if this RFC is not accepted, the motivation could be used to develop alternative solutions. In other words, enumerate the constraints you are trying to solve without coupling them too closely to the solution you have in mind.
+
+## Detailed design
+
+This is the bulk of the RFC. Explain the design in enough detail for somebody familiar with React Native to understand, and for somebody familiar with the implementation to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. Any new terminology should be defined here.
+
+## Drawbacks
+
+Why should we _not_ do this? Please consider:
+
+- implementation cost, both in term of code size and complexity
+- whether the proposed feature can be implemented in user space
+- the impact on teaching people React Native
+- integration of this feature with other existing and planned features
+- cost of migrating existing React Native applications (is it a breaking change?)
+
+There are tradeoffs to choosing any path. Attempt to identify them here.
+
+## Alternatives
+
+What other designs have been considered? Why did you select your approach?
+
+## Adoption strategy
+
+If we implement this proposal, how will existing React Native developers adopt it? Is this a breaking change? Can we write a codemod? Should we coordinate with other projects or libraries?
+
+## How we teach this
+
+What names and terminology work best for these concepts and why? How is this idea best presented? As a continuation of existing React patterns?
+
+Would the acceptance of this proposal mean the React Native documentation must be re-organized or altered? Does it change how React Native is taught to new developers at any level?
+
+How should this feature be taught to existing React Native developers?
+
+## Unresolved questions
+
+Optional, but suggested for first drafts. What parts of the design are still TBD?
From ba724f9c468891187cfa924e6c44e9fa4a8d2448 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 18:53:41 +0100
Subject: [PATCH 02/13] feat: add header, summary and motivation
---
proposals/0000-adding-support-for-swift.md | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 02c7f8ed..36e3b36c 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -1,25 +1,23 @@
---
-title: Title goes here
+title: Adding support for Swift / Moving away from Obj-C on Apple platforms
author:
-- Jane Doe
-date: today
+- Parsa Nasirimehr
+date: 2023-12-14
---
-# RFC0000: Title goes here
+# RFC0000: Adding support for Swift / Moving away from Obj-C on Apple platforms
## Summary
-Brief explanation of the change.
-
-## Basic example
-
-If the proposal involves a new or changed API, include a basic code example. Omit this section if it's not applicable.
+React Native's base code on Apple's platfroms has been written in a mix of Obj-C, Obj-C++ and C++. This proposal discuses what path we might have to migrate the codebase to using just C++ and Swift, Apple's current standard language for developing apps on their platforms, and what areas we need to be to mindful of (including tooling, various architectures that would need to be supported, documentation updates and the impact on third party libraries)
## Motivation
-Why are we doing this? What use cases does it support? What is the expected outcome?
+The motivation for this change is threefold:
+- As of Swift 5.9, Swift is now capable of direct interop with C++, Which was one of the primary reasons Obj-C and Obj-C++ were still required within the repository. While the development [is still ongoing](https://www.swift.org/documentation/cxx-interop/status/) and there are [constraints that still exist](https://github.com/apple/swift/issues/66159), Apple's end goal is to reach the needed API parity to work seemlesssly between Swift and C++
+- Obj-C is relatively hard to write and maintain for, and it is reflected by the [community](https://github.com/react-native-community/discussions-and-proposals/issues/104). Having a modern language that is more readable, more performant(in some cases) and [safer from certain class of errors](https://developer.apple.com/swift/#safety) means that users and library maintainers alike can produce better quality code and take advantage of the underlying platforms easier if they need it
+- As Swift evolves and becomes more feature rich, there is a possibility that Apple will begin to remove support for Obj-C in it's toolchain. The documentation for the various APIs that Apple provides may also be moved to simply having Swift as the supported language.
-Please focus on explaining the motivation so that if this RFC is not accepted, the motivation could be used to develop alternative solutions. In other words, enumerate the constraints you are trying to solve without coupling them too closely to the solution you have in mind.
## Detailed design
From a297a0cb5c538e8e6f134da4f959ebac57ba5625 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 19:48:02 +0100
Subject: [PATCH 03/13] feat: add Detailed design section
---
proposals/0000-adding-support-for-swift.md | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 36e3b36c..4ef59c26 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -21,6 +21,54 @@ The motivation for this change is threefold:
## Detailed design
+### TODO: I am unaware of a lot of the internals of RN, so if anyone more aware than me can contribute, it is appreciated
+
+The general idea is that the code we have for Apple platforms should be consistent of three primary parts:
+- The Swift API layer that is in charge of the platform specific operations that can not be shared across other platforms (the View Delegate, the Scene Delegate, anything that has to do with Apple specific frameworks like UIKit)
+- The Shared C++ code that is platform agnostic and used by all React Native target platforms (Yoga, Hermes, the event handlers, the bridge (if applicable), etc)
+- The optional intermidery C++ code, with Swift specific annotations for certain APIs that help Swift interact with C++ in a more efficient and correct manner (To learn more, please refer to [Swift's documentation of interop with C++](https://www.swift.org/documentation/cxx-interop/#exposing-swift-apis-to-c) under "Customizing How C++ Maps to Swift")
+
+The third step is marked as optional. The idea is that the Swift compiler makes certain assumptions when interacting directly with the C++ modules that may not necessarily be correct (C++ types being imported as value types by default, for instance). But we can override those behaviours by explicitly marking certain sections with the annotations provided to us by (Marking things to be imported as reference types, Mapping getters and setters, etc)
+
+Much like our current setup with Obj-C, The Apple platform section of any new project template created will simply expose the Swift files for developers to extend and add functionalities to. The React Native APIs can be simply imported via a swift import and consumed by the Swift parts, giving us control over our API surface and hiding away any specific pieces that will not be needed on a day to day basis. Example:
+
+```swift
+import React
+
+@main
+class AppDelegate: RCTAppDelegate {
+ override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ self.moduleName = "HelloWorld"
+ // You can add your custom initial props in the dictionary below.
+ // They will be passed down to the ViewController used by React Native.
+ self.initialProps = [:]
+
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+
+ override func sourceURL(for bridge: RCTBridge!) -> URL! {
+ return self.getBundleURL()
+ }
+
+ func getBundleURL() -> URL {
+ #if DEBUG
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+ #else
+ return Bundle.main.url(forResource: "main", withExtension: "jsbundle")!
+ #endif
+ }
+
+ /// Native bits of functionality that users may extend and add on their own
+}
+```
+
+
+
+
+
+
+
+
This is the bulk of the RFC. Explain the design in enough detail for somebody familiar with React Native to understand, and for somebody familiar with the implementation to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. Any new terminology should be defined here.
## Drawbacks
From 9d79ee2f5cb3470f579c0ace2f8d6484410f3b6b Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 21:04:06 +0100
Subject: [PATCH 04/13] feat: add draw backs, alternatives and adoption
strategy
---
proposals/0000-adding-support-for-swift.md | 49 ++++++++++++----------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 4ef59c26..05a62d18 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -21,14 +21,14 @@ The motivation for this change is threefold:
## Detailed design
-### TODO: I am unaware of a lot of the internals of RN, so if anyone more aware than me can contribute, it is appreciated
+### TODO: I am unaware of a lot of the internals of RN, so if anyone more aware than me can contribute, it is appreciated.
-The general idea is that the code we have for Apple platforms should be consistent of three primary parts:
+The general idea is that the code we have for Apple platforms should be consistent of three primary parts by the end of this migration:
- The Swift API layer that is in charge of the platform specific operations that can not be shared across other platforms (the View Delegate, the Scene Delegate, anything that has to do with Apple specific frameworks like UIKit)
- The Shared C++ code that is platform agnostic and used by all React Native target platforms (Yoga, Hermes, the event handlers, the bridge (if applicable), etc)
- The optional intermidery C++ code, with Swift specific annotations for certain APIs that help Swift interact with C++ in a more efficient and correct manner (To learn more, please refer to [Swift's documentation of interop with C++](https://www.swift.org/documentation/cxx-interop/#exposing-swift-apis-to-c) under "Customizing How C++ Maps to Swift")
-The third step is marked as optional. The idea is that the Swift compiler makes certain assumptions when interacting directly with the C++ modules that may not necessarily be correct (C++ types being imported as value types by default, for instance). But we can override those behaviours by explicitly marking certain sections with the annotations provided to us by (Marking things to be imported as reference types, Mapping getters and setters, etc)
+The third step is marked as optional. The idea is that the Swift compiler makes certain assumptions when interacting directly with the C++ modules that may not necessarily be correct (C++ types being imported as value types by default, for instance). But we can override those behaviours by explicitly marking certain sections with the annotations provided to us by `` (Marking things to be imported as reference types, Mapping getters and setters, etc)
Much like our current setup with Obj-C, The Apple platform section of any new project template created will simply expose the Swift files for developers to extend and add functionalities to. The React Native APIs can be simply imported via a swift import and consumed by the Swift parts, giving us control over our API surface and hiding away any specific pieces that will not be needed on a day to day basis. Example:
@@ -62,34 +62,37 @@ class AppDelegate: RCTAppDelegate {
}
```
-
-
-
-
-
-
-
-This is the bulk of the RFC. Explain the design in enough detail for somebody familiar with React Native to understand, and for somebody familiar with the implementation to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. Any new terminology should be defined here.
-
## Drawbacks
-Why should we _not_ do this? Please consider:
-
-- implementation cost, both in term of code size and complexity
-- whether the proposed feature can be implemented in user space
-- the impact on teaching people React Native
-- integration of this feature with other existing and planned features
-- cost of migrating existing React Native applications (is it a breaking change?)
-
-There are tradeoffs to choosing any path. Attempt to identify them here.
+The biggest drawback can be boiled down to certain key elements:
+- It is a massive undertaking, that will likely take years to fully complete
+- The Swift API is not yet fully compatible with everything we will need on the C++ side of things
+- Libraries will need to update their documentation and probably some changes to their imports as well (ideally, the API should not change, unless it is related to the Platform specific side of things and the Swift implementation simplifies the existing API for them to consume) and as [previously established](https://github.com/react-native-community/discussions-and-proposals/issues/671) not all libraries adapt and maintainers may not update
+- Users will need to upgrade their templates and the libraries they use to Switch over
## Alternatives
-What other designs have been considered? Why did you select your approach?
+### Leaving things as is
+The overhead of this option is much much lower in the short term, and while it creates a bad user experience for the smaller subsection of the user base that want to be able to do more (and library maintainers who would probably benefit from this new found access), the cost is undeniably lower. The problem is that eventually, Apple either push for this change directly, or will make it very hard to continue, so unless we take initiative now, We will be forced to it down the road, and in the mean time React Native will have to resort to more and more custom solutions to deal with any APIs that might become unavailable
## Adoption strategy
-If we implement this proposal, how will existing React Native developers adopt it? Is this a breaking change? Can we write a codemod? Should we coordinate with other projects or libraries?
+The core idea is to still be able to deliver feature and changes that users and library maintainers have been asking for while doing the migration. One strategy that comes to mind for achieving this result is as follows:
+- (If needed) Isolating the OSS bits that are user facing from the internals as much as possible (Like AppDelegate and the tests)
+- (If needed) Updating Cocopods infra
+- (If needed) Communicating with third party libraries to adjust
+- (If needed) Rolling out a new version
+- Migrating the OSS parts from Obj-C -> Swift
+- Updating CLI to support the new files and structures
+- Updating React Native Helper to support people trying to migrate their templates from Obj-C to Swift
+- Updating the docs
+- Communicating with library maintainers if help is needed updating their documentation to support the setup for both Swift and Obj-C for older users
+- Rolling out a new version
+- Moving as much shared logic as possible to C++ and away from Obj-C, separating them as distinctly as possible while adding new features and capabilities and continuing to roll out new versions (**Users should not be affected, and ideally the Library maintainers should not be affected either**)
+- Beginning the transition from Obj-C to Swift from the tests in the internals (**No effect on users or library maintainers**)
+- Moving the rest of the modules one at a time from Obj-C to Swift (**Library maintainers may need to update, if they wish to take advantage of the newer APIs or if we break change an APIs signiture, but ideally it should only be in the direction of making it easier to maintain libraries and better APIs**)
+- Updating Cocopods infra
+- ? (Please add any more steps that come to mind, at the end or anywhere else in the list)
## How we teach this
From 508dd0094b0e953067bfdaaa0b7cd4b498ccde5d Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 21:38:18 +0100
Subject: [PATCH 05/13] feat: write the how we teach and unresolved sections
---
proposals/0000-adding-support-for-swift.md | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 05a62d18..de7ebdc3 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -21,7 +21,7 @@ The motivation for this change is threefold:
## Detailed design
-### TODO: I am unaware of a lot of the internals of RN, so if anyone more aware than me can contribute, it is appreciated.
+### HELP WANTED: I am unaware of a lot of the internals of RN, so if anyone more aware than me can contribute, it is appreciated.
The general idea is that the code we have for Apple platforms should be consistent of three primary parts by the end of this migration:
- The Swift API layer that is in charge of the platform specific operations that can not be shared across other platforms (the View Delegate, the Scene Delegate, anything that has to do with Apple specific frameworks like UIKit)
@@ -73,7 +73,7 @@ The biggest drawback can be boiled down to certain key elements:
## Alternatives
### Leaving things as is
-The overhead of this option is much much lower in the short term, and while it creates a bad user experience for the smaller subsection of the user base that want to be able to do more (and library maintainers who would probably benefit from this new found access), the cost is undeniably lower. The problem is that eventually, Apple either push for this change directly, or will make it very hard to continue, so unless we take initiative now, We will be forced to it down the road, and in the mean time React Native will have to resort to more and more custom solutions to deal with any APIs that might become unavailable
+The overhead of this option is much much lower in the short term, and while it creates a bad user experience for the smaller subsection of the user base that want to be able to do more (and library maintainers who would probably benefit from this new found access), the cost is undeniably lower. The problem is that eventually, Apple will either push for this change directly, or will make it very hard to continue, so unless we take initiative now, We will be forced to it down the road, and in the mean time React Native will have to resort to more and more custom solutions to deal with any APIs that might become unavailable
## Adoption strategy
@@ -96,12 +96,16 @@ The core idea is to still be able to deliver feature and changes that users and
## How we teach this
-What names and terminology work best for these concepts and why? How is this idea best presented? As a continuation of existing React patterns?
+This should be a pretty welcome step for the user base (and even the maintainers, if done correctly and without too many breaking changes). The docs for creating Native module will need to be updated to add support for Swift, and we can simply mention the change in React Native EU or similar conferences.
-Would the acceptance of this proposal mean the React Native documentation must be re-organized or altered? Does it change how React Native is taught to new developers at any level?
+The idea is to make it very un-noticable to the vast majority of the user base who simply want to use the React side for creating their mobile applications, and the part of the community that is capable of creating native modules should simply feel like it is just another native Apple app that they can extend using whatever it is that they need (perhaps adding a watchOS target support for their app, or using CoreML or AppClips or making a SwiftUI based widget)
-How should this feature be taught to existing React Native developers?
+It should be presented as React Native keeping up with changes and lowering the barrier of entry for all devs and that we are simply making part of the work that is duplicated across platforms easy to reuse, using the same tools that our industry is using and without sacrificing the experience.
## Unresolved questions
-Optional, but suggested for first drafts. What parts of the design are still TBD?
+- What other parts of the infra need to be changed for this transition to work?
+- How will this affect other targets such as React Native MacOS, React Native visionOS, etc?
+- Is our current separation of internals from the OSS template enough that we can simply change the template directly without any of the first four steps needed? (I managed to get a [test repo](https://github.com/TheRogue76/React-Native-Template-With-Swift) to work as a proof of concept with these changes, but i am not sure if that means that the app will work for all situations (new arch, bridgless, etc). I also submitted [a PR](https://github.com/facebook/react-native/pull/41896) to test out the current tests we had and those passed, but that might not be enough). And what about Expo? Will it continue to function if this change is done to the base template, or would it interfere with any of the work done on their side
+- Can we create a separation between the base template of the app and rest of the internals in a way that would allow us to switch over the template without breaking the everything in the process?
+
From 9821a99b93a1de95c02f13942ae2d1490f980a8f Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 21:42:40 +0100
Subject: [PATCH 06/13] chore: fixing typos
---
proposals/0000-adding-support-for-swift.md | 28 +++++++++++-----------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index de7ebdc3..e9fc3ec0 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -9,12 +9,12 @@ date: 2023-12-14
## Summary
-React Native's base code on Apple's platfroms has been written in a mix of Obj-C, Obj-C++ and C++. This proposal discuses what path we might have to migrate the codebase to using just C++ and Swift, Apple's current standard language for developing apps on their platforms, and what areas we need to be to mindful of (including tooling, various architectures that would need to be supported, documentation updates and the impact on third party libraries)
+React Native's base code on Apple's platforms has been written in a mix of Obj-C, Obj-C++ and C++. This proposal discuses what path we might have to migrate the codebase to using just C++ and Swift, Apple's current standard language for developing apps on their platforms, and what areas we need to be mindful of (including tooling, various architectures that would need to be supported, documentation updates and the impact on third party libraries)
## Motivation
The motivation for this change is threefold:
-- As of Swift 5.9, Swift is now capable of direct interop with C++, Which was one of the primary reasons Obj-C and Obj-C++ were still required within the repository. While the development [is still ongoing](https://www.swift.org/documentation/cxx-interop/status/) and there are [constraints that still exist](https://github.com/apple/swift/issues/66159), Apple's end goal is to reach the needed API parity to work seemlesssly between Swift and C++
+- As of Swift 5.9, Swift is now capable of direct interop with C++, Which was one of the primary reasons Obj-C and Obj-C++ were still required within the repository. While the development [is still ongoing](https://www.swift.org/documentation/cxx-interop/status/) and there are [constraints that still exist](https://github.com/apple/swift/issues/66159), Apple's end goal is to reach the needed API parity to work seamlessly between Swift and C++
- Obj-C is relatively hard to write and maintain for, and it is reflected by the [community](https://github.com/react-native-community/discussions-and-proposals/issues/104). Having a modern language that is more readable, more performant(in some cases) and [safer from certain class of errors](https://developer.apple.com/swift/#safety) means that users and library maintainers alike can produce better quality code and take advantage of the underlying platforms easier if they need it
- As Swift evolves and becomes more feature rich, there is a possibility that Apple will begin to remove support for Obj-C in it's toolchain. The documentation for the various APIs that Apple provides may also be moved to simply having Swift as the supported language.
@@ -25,12 +25,12 @@ The motivation for this change is threefold:
The general idea is that the code we have for Apple platforms should be consistent of three primary parts by the end of this migration:
- The Swift API layer that is in charge of the platform specific operations that can not be shared across other platforms (the View Delegate, the Scene Delegate, anything that has to do with Apple specific frameworks like UIKit)
-- The Shared C++ code that is platform agnostic and used by all React Native target platforms (Yoga, Hermes, the event handlers, the bridge (if applicable), etc)
-- The optional intermidery C++ code, with Swift specific annotations for certain APIs that help Swift interact with C++ in a more efficient and correct manner (To learn more, please refer to [Swift's documentation of interop with C++](https://www.swift.org/documentation/cxx-interop/#exposing-swift-apis-to-c) under "Customizing How C++ Maps to Swift")
+- The Shared C++ code that is platform-agnostic and used by all React Native target platforms (Yoga, Hermes, the event handlers, the bridge (if applicable), etc.)
+- The optional intermediary C++ code, with Swift specific annotations for certain APIs that help Swift interact with C++ in a more efficient and correct manner (To learn more, please refer to [Swift's documentation of interop with C++](https://www.swift.org/documentation/cxx-interop/#exposing-swift-apis-to-c) under "Customizing How C++ Maps to Swift")
-The third step is marked as optional. The idea is that the Swift compiler makes certain assumptions when interacting directly with the C++ modules that may not necessarily be correct (C++ types being imported as value types by default, for instance). But we can override those behaviours by explicitly marking certain sections with the annotations provided to us by `` (Marking things to be imported as reference types, Mapping getters and setters, etc)
+The third step is marked as optional. The idea is that the Swift compiler makes certain assumptions when interacting directly with the C++ modules that may not necessarily be correct (C++ types being imported as value types by default, for instance). But we can override those behaviours by explicitly marking certain sections with the annotations provided to us by `` (Marking things to be imported as reference types, Mapping getters and setters, etc.)
-Much like our current setup with Obj-C, The Apple platform section of any new project template created will simply expose the Swift files for developers to extend and add functionalities to. The React Native APIs can be simply imported via a swift import and consumed by the Swift parts, giving us control over our API surface and hiding away any specific pieces that will not be needed on a day to day basis. Example:
+Much like our current setup with Obj-C, The Apple platform section of any new project template created will simply expose the Swift files for developers to extend and add functionalities to. The React Native APIs can be simply imported via a swift import and consumed by the Swift parts, giving us control over our API surface and hiding away any specific pieces that will not be needed on a day-to-day basis. Example:
```swift
import React
@@ -73,13 +73,13 @@ The biggest drawback can be boiled down to certain key elements:
## Alternatives
### Leaving things as is
-The overhead of this option is much much lower in the short term, and while it creates a bad user experience for the smaller subsection of the user base that want to be able to do more (and library maintainers who would probably benefit from this new found access), the cost is undeniably lower. The problem is that eventually, Apple will either push for this change directly, or will make it very hard to continue, so unless we take initiative now, We will be forced to it down the road, and in the mean time React Native will have to resort to more and more custom solutions to deal with any APIs that might become unavailable
+The overhead of this option is much lower in the short term, and while it creates a bad user experience for the smaller subsection of the user base that want to be able to do more (and library maintainers who would probably benefit from this new-found access), the cost is undeniably lower. The problem is that eventually, Apple will either push for this change directly, or will make it very hard to continue, so unless we take initiative now, We will be forced to it down the road, and in the meantime React Native will have to resort to more and more custom solutions to deal with any APIs that might become unavailable
## Adoption strategy
The core idea is to still be able to deliver feature and changes that users and library maintainers have been asking for while doing the migration. One strategy that comes to mind for achieving this result is as follows:
- (If needed) Isolating the OSS bits that are user facing from the internals as much as possible (Like AppDelegate and the tests)
-- (If needed) Updating Cocopods infra
+- (If needed) Updating CocoaPods infra
- (If needed) Communicating with third party libraries to adjust
- (If needed) Rolling out a new version
- Migrating the OSS parts from Obj-C -> Swift
@@ -90,22 +90,22 @@ The core idea is to still be able to deliver feature and changes that users and
- Rolling out a new version
- Moving as much shared logic as possible to C++ and away from Obj-C, separating them as distinctly as possible while adding new features and capabilities and continuing to roll out new versions (**Users should not be affected, and ideally the Library maintainers should not be affected either**)
- Beginning the transition from Obj-C to Swift from the tests in the internals (**No effect on users or library maintainers**)
-- Moving the rest of the modules one at a time from Obj-C to Swift (**Library maintainers may need to update, if they wish to take advantage of the newer APIs or if we break change an APIs signiture, but ideally it should only be in the direction of making it easier to maintain libraries and better APIs**)
-- Updating Cocopods infra
+- Moving the rest of the modules one at a time from Obj-C to Swift (**Library maintainers may need to update, if they wish to take advantage of the newer APIs or if we break change an APIs signature, but ideally it should only be in the direction of making it easier to maintain libraries and better APIs**)
+- Updating CocoaPods infra
- ? (Please add any more steps that come to mind, at the end or anywhere else in the list)
## How we teach this
This should be a pretty welcome step for the user base (and even the maintainers, if done correctly and without too many breaking changes). The docs for creating Native module will need to be updated to add support for Swift, and we can simply mention the change in React Native EU or similar conferences.
-The idea is to make it very un-noticable to the vast majority of the user base who simply want to use the React side for creating their mobile applications, and the part of the community that is capable of creating native modules should simply feel like it is just another native Apple app that they can extend using whatever it is that they need (perhaps adding a watchOS target support for their app, or using CoreML or AppClips or making a SwiftUI based widget)
+The idea is to make it very un-noticeable to the vast majority of the user base who simply want to use the React side for creating their mobile applications, and the part of the community that is capable of creating native modules should simply feel like it is just another native Apple app that they can extend using whatever it is that they need (perhaps adding a watchOS target support for their app, or using CoreML or AppClips or making a SwiftUI based widget)
It should be presented as React Native keeping up with changes and lowering the barrier of entry for all devs and that we are simply making part of the work that is duplicated across platforms easy to reuse, using the same tools that our industry is using and without sacrificing the experience.
## Unresolved questions
- What other parts of the infra need to be changed for this transition to work?
-- How will this affect other targets such as React Native MacOS, React Native visionOS, etc?
-- Is our current separation of internals from the OSS template enough that we can simply change the template directly without any of the first four steps needed? (I managed to get a [test repo](https://github.com/TheRogue76/React-Native-Template-With-Swift) to work as a proof of concept with these changes, but i am not sure if that means that the app will work for all situations (new arch, bridgless, etc). I also submitted [a PR](https://github.com/facebook/react-native/pull/41896) to test out the current tests we had and those passed, but that might not be enough). And what about Expo? Will it continue to function if this change is done to the base template, or would it interfere with any of the work done on their side
-- Can we create a separation between the base template of the app and rest of the internals in a way that would allow us to switch over the template without breaking the everything in the process?
+- How will this affect other targets such as React Native macOS, React Native visionOS, etc.?
+- Is our current separation of internals from the OSS template enough that we can simply change the template directly without any of the first four steps needed? (I managed to get a [test repo](https://github.com/TheRogue76/React-Native-Template-With-Swift) to work as a proof of concept with these changes, but I am not sure if that means that the app will work for all situations (new arch, bridge-less, etc.). I also submitted [a PR](https://github.com/facebook/react-native/pull/41896) to test out the current tests we had and those passed, but that might not be enough). And what about Expo? Will it continue to function if this change is done to the base template, or would it interfere with any of the work done on their side
+- Can we create a separation between the base template of the app and rest of the internals in a way that would allow us to switch over the template without breaking everything in the process?
From d9ba022a3eb2212e6a55f8d51825b5599a30204a Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Thu, 14 Dec 2023 21:58:12 +0100
Subject: [PATCH 07/13] chore: fixing typo
---
proposals/0000-adding-support-for-swift.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index e9fc3ec0..92a89cfe 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -9,7 +9,7 @@ date: 2023-12-14
## Summary
-React Native's base code on Apple's platforms has been written in a mix of Obj-C, Obj-C++ and C++. This proposal discuses what path we might have to migrate the codebase to using just C++ and Swift, Apple's current standard language for developing apps on their platforms, and what areas we need to be mindful of (including tooling, various architectures that would need to be supported, documentation updates and the impact on third party libraries)
+React Native's codebase on Apple's platforms has been written in a mix of Obj-C, Obj-C++ and C++. This proposal discuses what path we might have to migrate the codebase to using just C++ and Swift, Apple's current standard language for developing apps on their platforms, and what areas we need to be mindful of (including tooling, various architectures that would need to be supported, documentation updates and the impact on third party libraries)
## Motivation
From 21e7c3f63aa0213a214744a31b12d5b0b681cef1 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Tue, 19 Dec 2023 16:49:31 +0100
Subject: [PATCH 08/13] chore: mention swift only frameworks being added
---
proposals/0000-adding-support-for-swift.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 92a89cfe..4381917d 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -16,7 +16,7 @@ React Native's codebase on Apple's platforms has been written in a mix of Obj-C,
The motivation for this change is threefold:
- As of Swift 5.9, Swift is now capable of direct interop with C++, Which was one of the primary reasons Obj-C and Obj-C++ were still required within the repository. While the development [is still ongoing](https://www.swift.org/documentation/cxx-interop/status/) and there are [constraints that still exist](https://github.com/apple/swift/issues/66159), Apple's end goal is to reach the needed API parity to work seamlessly between Swift and C++
- Obj-C is relatively hard to write and maintain for, and it is reflected by the [community](https://github.com/react-native-community/discussions-and-proposals/issues/104). Having a modern language that is more readable, more performant(in some cases) and [safer from certain class of errors](https://developer.apple.com/swift/#safety) means that users and library maintainers alike can produce better quality code and take advantage of the underlying platforms easier if they need it
-- As Swift evolves and becomes more feature rich, there is a possibility that Apple will begin to remove support for Obj-C in it's toolchain. The documentation for the various APIs that Apple provides may also be moved to simply having Swift as the supported language.
+- As Swift evolves and becomes more feature rich, there is a possibility that Apple will begin to remove support for Obj-C in it's toolchain, or release new frameworks that are Swift only (We have already begun seeing this trend with frameworks like Swift Data). The documentation for the various APIs that Apple provides may also be moved to simply having Swift as the supported language.
## Detailed design
From d5c39aea9f2196cbdcbf3f2a44d22d2baf149491 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Tue, 19 Dec 2023 18:14:15 +0100
Subject: [PATCH 09/13] feat: add another alternative that we can consider
---
proposals/0000-adding-support-for-swift.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 4381917d..08cbaba9 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -75,6 +75,20 @@ The biggest drawback can be boiled down to certain key elements:
### Leaving things as is
The overhead of this option is much lower in the short term, and while it creates a bad user experience for the smaller subsection of the user base that want to be able to do more (and library maintainers who would probably benefit from this new-found access), the cost is undeniably lower. The problem is that eventually, Apple will either push for this change directly, or will make it very hard to continue, so unless we take initiative now, We will be forced to it down the road, and in the meantime React Native will have to resort to more and more custom solutions to deal with any APIs that might become unavailable
+### Creating a wrapper Objective-C(++) around C++ pure code
+Another approach could be to create wrappers around our C++ code base using Objective-C and Objective-C++ and only exposing APIs that are Swift compatible through this wrapper.
+
+To make this work, we will need to clearly define which APIs fall under that category, which might require quite a bit of work.
+
+This approach has several pros which should be taken into consideration:
+ - Avoid a rewrite of some internals
+ - Allow contributors to start using Swift only, making the process much easier for everyone involved
+ - Allow us to work around the current Swift <-> C++ interop limitations and unblock the work
+ - Take a much shorter amount of time to do
+
+ It also has one con that we would need to consider as well:
+ - It does not address the issue of Apple removing support for Objective-C in the toolchain (Though perhaps, given how long it might take for Apple to make this change, this might end up not being too big of a problem)
+
## Adoption strategy
The core idea is to still be able to deliver feature and changes that users and library maintainers have been asking for while doing the migration. One strategy that comes to mind for achieving this result is as follows:
From 6a0543926e0f59ec507fe97e4cd97834aaa7efde Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Tue, 19 Dec 2023 18:18:45 +0100
Subject: [PATCH 10/13] chore: remove answered question
---
proposals/0000-adding-support-for-swift.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 08cbaba9..fba7ca81 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -120,6 +120,4 @@ It should be presented as React Native keeping up with changes and lowering the
- What other parts of the infra need to be changed for this transition to work?
- How will this affect other targets such as React Native macOS, React Native visionOS, etc.?
-- Is our current separation of internals from the OSS template enough that we can simply change the template directly without any of the first four steps needed? (I managed to get a [test repo](https://github.com/TheRogue76/React-Native-Template-With-Swift) to work as a proof of concept with these changes, but I am not sure if that means that the app will work for all situations (new arch, bridge-less, etc.). I also submitted [a PR](https://github.com/facebook/react-native/pull/41896) to test out the current tests we had and those passed, but that might not be enough). And what about Expo? Will it continue to function if this change is done to the base template, or would it interfere with any of the work done on their side
-- Can we create a separation between the base template of the app and rest of the internals in a way that would allow us to switch over the template without breaking everything in the process?
From 8ecb9db79244b93ded0bebf0276d33f6115cc460 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Tue, 19 Dec 2023 18:31:44 +0100
Subject: [PATCH 11/13] chore: add question regarding API compatibility to
---
proposals/0000-adding-support-for-swift.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index fba7ca81..37800e79 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -120,4 +120,5 @@ It should be presented as React Native keeping up with changes and lowering the
- What other parts of the infra need to be changed for this transition to work?
- How will this affect other targets such as React Native macOS, React Native visionOS, etc.?
+- Are bits like Native/TurboModule APIs or Native/Fabric Components APIs or Codegen (for the New Arch) compatible with Swift? If not, what work needs to be done to make these APIs compatible? (And in the case of Codegen, would it be possible to generate Swift types directly as well, even if its partial)? If they can not be made compatible, what can be done?
From 228b56dbbd63f16a1da25d2122fabd32207c2e91 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Fri, 29 Dec 2023 12:19:34 +0100
Subject: [PATCH 12/13] chore: mention needing to expose the modules as clang
modules and how there might be breaking change in it
---
proposals/0000-adding-support-for-swift.md | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index 37800e79..c397c6f4 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -92,10 +92,12 @@ This approach has several pros which should be taken into consideration:
## Adoption strategy
The core idea is to still be able to deliver feature and changes that users and library maintainers have been asking for while doing the migration. One strategy that comes to mind for achieving this result is as follows:
-- (If needed) Isolating the OSS bits that are user facing from the internals as much as possible (Like AppDelegate and the tests)
-- (If needed) Updating CocoaPods infra
-- (If needed) Communicating with third party libraries to adjust
-- (If needed) Rolling out a new version
+- Isolating the OSS bits that are user facing from the internals as much as possible (Like AppDelegate and the tests)
+- Updating CocoaPods infra
+- Communicating with third party libraries to adjust
+- Rolling out a new version
+- Configuring the exposed modules as Clang modules so they can be consumed by Swift
+- (If configuring the modules ends up requiring some breaking change (like needing to put the public headers in an include folder)) Deal with breaking change for the libraries and setting up migration guides
- Migrating the OSS parts from Obj-C -> Swift
- Updating CLI to support the new files and structures
- Updating React Native Helper to support people trying to migrate their templates from Obj-C to Swift
From 2016329e28f1f18e08b455fd44ba61a1f822c562 Mon Sep 17 00:00:00 2001
From: Parsa Nasirimehr
Date: Sat, 18 May 2024 10:35:40 +0200
Subject: [PATCH 13/13] chore: remove unneeded header, let people point out
issues as they see it
---
proposals/0000-adding-support-for-swift.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/proposals/0000-adding-support-for-swift.md b/proposals/0000-adding-support-for-swift.md
index c397c6f4..e073d400 100644
--- a/proposals/0000-adding-support-for-swift.md
+++ b/proposals/0000-adding-support-for-swift.md
@@ -21,8 +21,6 @@ The motivation for this change is threefold:
## Detailed design
-### HELP WANTED: I am unaware of a lot of the internals of RN, so if anyone more aware than me can contribute, it is appreciated.
-
The general idea is that the code we have for Apple platforms should be consistent of three primary parts by the end of this migration:
- The Swift API layer that is in charge of the platform specific operations that can not be shared across other platforms (the View Delegate, the Scene Delegate, anything that has to do with Apple specific frameworks like UIKit)
- The Shared C++ code that is platform-agnostic and used by all React Native target platforms (Yoga, Hermes, the event handlers, the bridge (if applicable), etc.)