Import React Native dependency to existing iOS app manually - ios

It seems like just about every tutorial and blog post out there has you integrating RN into an existing app using CocoaPods. Adding CocoaPods support isn't a possibility for our existing iOS app - we are relying on Carthage for dependency management already which doesn't seem to be supported by RN.
So, I went through the process of adding the dependencies manually by attempting to recreate the iOS app that is produced when using the RN CLI (react-native init):
-Add the React.xcodeproj from node_modules/react-native to my Libraries folder, and also add the other Libraries from node_modules/react-native/Libraries, such as RCTActionSheet.xcodeproj. Then, I added all of those to the 'Link Binary With Libraries' section in Build Phases.
-Updated 'Other Linker Flags' to -ObjC -Ic++.
...My app build is still failing with "RCTRootView.h file not found".
Does anyone have experience with just adding RN manually to an existing iOS project, that might be able to provide a definitive list of steps for adding it manually to an existing project?

In addition to the other steps, I also needed to update the HeaderSearchPaths setting to point to the React folder in node_modules: http://i.imgur.com/jK0IMZN.jpg

Related

How can I properly share the Amplify framework with my Main App and my App Extension for an iOS app?

I have an iOS app using AWS amplify for the backend. I am using Xcode 13 and SwiftUI.
I previously added the Amplify framework using Cocoapods however I was unable to get the framework to work with the extension.
So I recently switched to Swift Package Manager. I added the package to my main project. Then I went to my Share Extension and in General - Frameworks and Libraries and manually added the libraries.
After doing this the app builds and runs and both the main app and extension work fine and are able to use the libraries.
The problem is that I cannot archive and upload the app to the App Store. I get the following error:
CFBundleIdentifier Collision. There is more than one bundle with the
CFBundleIdentifier value 'com.amazonaws.AWSAuthCore' under the iOS
application 'MyAPP.app'. With error code
STATE_ERROR.VALIDATION_ERROR...
I went on many forums and spent many hours trying to fix this but to no avail. The suggestions are to click 'do not embed' for the libraries but that option is not available for me.
I wonder if there is anyway to resolve this?
Below are my General and Build Phases for the Share Extension:
Just remove explicit Amplify dependency from extension, ie. next section should be empty
Make sure (it should be automatically, but anyway)
Link Frameworks Automatically parameter (in Build Settings) is true
Runpath Search Path parameter is related to main bundle
So as targets from SPM are built in same location as product and extension and automatic framework linking is enabled the imported modules in extension will available and linked automatically and due to run paths are set the frameworks will be found in run-time as well.
Note: of course in main app target all should be included
Tested with Xcode 13.1 / iOS 15.1

Can't submit iOS app to iTunes connect when using a SPM package

When I try to submit an iOS app that includes an SPM package which uses the new binary target the submission fails with the following two errors:
Invalid Swift Support. The file MyApp.app/Frameworks/libHello.a doesn’t have the correct file type for this location. Ensure you’re using the correct file, rebuild your app using the current public (GM) version of Xcode, and resubmit it.
Invalid Bundle Structure - The binary file 'MyApp.app/Frameworks/libHello.a' is not permitted. Your app can’t contain standalone executables or libraries, other than a valid CFBundleExecutable of supported bundles. Refer to the Bundle Programming Guide at https://developer.apple.com/go/?id=bundle-structure for information on the iOS app bundle structure.
I believe it's to do with SPM as when I manually drag the Hello.xcframework package to the project it allows me to submit successfully.
Trying to do other things like changing Xcode build settings, customising the package.swift and using lipo to make sure the architecture slices are valid doesn't lead to anyway.
I looked at the embed framework in Build phases, it's not been included only in the link framework phase. One thing I noticed is when I archived the app the static library libHello.a was in the app's framework folder, which is weird since it shouldn't be there as they are integrated with the app binary. When I delete that file I can continue the app submission without any issues. But I don't think this workaround would be ideal long term.
I've created a simple static library with one class and method to keep thing simple. I then use Xcode archive the resulting static library in an XCFramework using xcodebuild -create-xcframework. See Github Repo: https://github.com/shams-ahmed/Hello
Steps to reproduce:
Create a new Xcode project
Add the Hello SPM package using the SPM interface with URL: https://github.com/shams-ahmed/Hello
Archive the project
Validate the App
You can deselect all the options
Fails with the above error message
What do I need to do to get SPM working with a static library? This is now meant to be supported with Xcode 12 and Swift 5.3
Info:
Xcode 12.0
Swift 5.3
Using a new Xcode project
P.S must use a static library
Looks like it's not possible with static libraries (.a files) because .binaryTarget with a xcframework is associated with dynamic frameworks and XCode just copy a platform depended entity from the xcframework to Frameworks folder of your .app instead of linking to your application's binary.
XCode build log:
PBXCp .../Hello.xcframework/ios-x86_64-simulator/libHello.a .../Test.app/Frameworks/libHello.a
There are two solutions:
Compile library sources as dynamic frameworks and make the xcframework from them.
If you have .a files only you can make dynamic frameworks wrappers which link static libraries and provides API access to them and then make the xcframework.

Getting error: ld: framework not found Fabric for architecture armv7 in App

I have build a iOS framework eg: abc.framework. Now in abc.framework I have added FirebaseDatabase and FirebaseMessaging. The abc.framework compiles and builds properly. However when I add the abc.framework and abc.bundle in my iOS project eg: xyz.project then it is giving error "framework not found Fabric for architecture armv7". I have not added Fabric in abc.framework and not in my xyz.project. However when I remove the Firebase from the abc.framework then the error disappears from xyz.project and the project compiles and run without errors.
If anyone has encountered the same issue then please let me know how should I solve the issue. I have to integrate Firebase in abc.framework and that framework will be added in xyz.project
Nested frameworks are not allowed in IOS , it's only allowed in MacOSX , to create a frameWork it must be of a pure code , fabric is in Firebase , also framework must support all architecture armv7,64 and soon on this configured when you build it, I encountered the same situation posted in Apple forums and find that
If CocoaPods is an option for you, the recent CocoaPods 1.4.0 release has added the static framework podspec option, which enables the definition of static frameworks that allow depending upon other static frameworks like Fabric.

Linking only embedded framework with other dynamic framework fails when build & run on device

tl;dr
Linking your embedded framework with other framework and don't link other framework with your app cause required code signature missing when Build & Run on device.
description:
Setup:
My setup is pretty simple (Swift 2.3 & Xcode Xcode 8.0; Build version 8S162m):
Using Carthage (0.17.2) I have build Other.framework with xcodebuild 8.0 and TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 carthage build --platform iOS
MyApp has embeded My.framework.
The app and the framework projects are under one Xcode workspace.
I hade linked Other.framework to My.framework ONLY (that means, MyApp is not linked to Other.framework at all). The point here is that, MyApp does not need to use Other.framework API.
Problem:
Everything seems to work fine, until I Build & Run the app on the device. The app launched and than the process is aborted with the following Xcode error:
dyld: Library not loaded: #rpath/Other.framework/Other
Referenced from: /private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/My
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/Frameworks/Other.framework/Other: required code signature missing for '/private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/Frameworks/Other.framework/Other'
I have checked the signature of Other.framework and it looked OK to me. Moreover,
Solution (workaround)
Link MyApp with Other.framework. Horrible... This feels broken.
Linking the very same binary Other.framework to MyApp and solving the issue this way, points out, the Other.framework is built OK and able to be re-signed correctly. Possibly, nothing to do with Carthage.
NOTE:
There is a similar problem iOS 8+ framework with nested embedded framework, however, mine has slightly other reason.
The issue has nothing to dow with nested frameworks. It is entirely about codesignature validation. dyld is reporting that Other.framework is missing a codesignature. You need to sign the framework. This should be done for you by Xcode, so I'm curious how Other.framework is getting built.
You can probably work around this yourself by just signing it.
codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign - /path/to/Other.framework
or to just deeply resign your app:
codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign - /path/to/My.app
I fixed my exact problem by following this guidance
You don't need to link your 'Other.framework' to your MyApp. Just add run script to sign the whatever embed framework that required code signature missing
Discussing this issue on the Carthage github page, it's become clear that the workaround mentioned in the question, is actually an expected behaviour:
Carthage doesn't support nested frameworks.
Nesting frameworks doesn't let you reuse those frameworks. For instance, if A.framework and B.framework both depend on Other.framework, then neither of them can nest Other.framework—otherwise you might end up with 2 different versions, and the correct one might not be chosen at runtime.
The correct way to do this is to list it as a dependency, but link it into the app target.
Full discussion: Linking only embedded framework with other dynamic framework fails when build & run on device: "required code signature missing"
This was unclear from the README, so I raised another issue, requesting to update the documentation:
Update to README: Linking dynamic frameworks to embedded frameworks requires as well linking them to the app target #1427
This is resolved and closed in the scope of the PR:
#1427 README upd: link dependencies from embedded frameworks to the app target

Error with Google Play Game Service on iOS

I am getting this error:
ERROR: GPGSAppController.mm GIDSignIn.h File not found error
I am using Google Play Game Service plugin for Unity for leaderboard and Achievements, and every thing is working fine in android but when I build to IOS and try to run my project to an iOS device I keep getting this error and I couldn't find a solution to it for hours now.
I tried to deleted everything related to Google Play service (After creating a back up of course) and the app installed and worked ok, except it was a bit laggy but that is a another issue. So I'm sure the problem comes from Google Play Service, but I have no clue how to fix it. Again I'm new to Xcode and iOS development in general and even Mac.
I also get this message after building the project in Unity:
TO FINISH CONFIGURING THE EXPORTED XCODE PROJECT
Add these frameworks:
AddressBook.framework
AssetsLibrary.framework
CoreData.framework
CoreTelephony.framework
CoreText.framework
Security.framework
libc++.dylib
libz.dylib
Add the following bundles and frameworks from the Google Plus
and the Google Play Games C++ SDKs. These can be downloaded from
https://developers.google.com/games/services.
GoogleOpenSource.framework
GoogleSignId.bundle
GoogleSignId.framework
gpg.bundle
gpg.framework
Note: Make sure the bundles are copied to application. This can be
verified under Build Phases/Copy Bundle Resources.
Add the '-ObjC' linker flag. To do this, select the top-level project
object, select the 'Unity-iPhone' build target, then go to the
Build Settings tab. Search for Other Linker Flags and add
the '-ObjC' flag to that list.
** Note: To run in the simulator, use Unity 4.6.8 or greater.
ios_instructions on plugin repository
But I have no idea how to do any thing above as am not familiar with iOS development. Any help is appreciated.
#aimozs answer was right for indicating where to add required files, a few google search gave me the answers;
From instructions (didn't work for me, scroll down)
AddressBook.framework
AssetsLibrary.framework
CoreData.framework
CoreTelephony.framework
CoreText.framework
Security.framework
libc++.dylib
libz.dylib
These can all be located directly when linking frameworks. (In my case, libc++.dylib and libz.dylib were already linked, and I couldn't find them somehow, but regenerating your xcode project should add these two again.
GoogleOpenSource.framework
I've found it here:
https://developers.google.com/+/mobile/ios/getting-started#step_1_creating_the_console_name_project
GoogleSignId.bundle
GoogleSignId.framework
Found them in:
https://developers.google.com/identity/sign-in/ios/sdk/
(I grabbed latest version Google Sign-In SDK 3.0.0)
gpg.bundle
gpg.framework
I found them here:
https://developers.google.com/games/services/downloads/sdks
(Grabbed Play Games C++ SDK Version 2.1)
Also, the following part of the message seemed important:
Make sure the bundles are copied to application
I tried to copy bundle files to root of the project, but I still get the same error.
Solution: CocoaPods and the podfile!
I saw the PodFile in xcode project directory!.
Here you go; make sure you followed these steps:
https://github.com/playgameservices/play-games-plugin-for-unity#ios-setup
Then see https://cocoapods.org/
sudo gem install cocoapods
pod repo update
pod install
open Unity-iPhone.xcworkspace
Way better than manually copying files everywhere! ;)
Note: I also had to disable bitecode because I was having a linker error concerning GoogleOpenSource:
You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE)
It doesn't seem to be compiled with bitcode enabled, solution in here: how to ENABLE_BITCODE in xcode 7?
Build, enjoy and focus on making awesome games!
Linked questions
There's also a small discussion here:
http://forum.unity3d.com/threads/googleplus-googleplus-h-file-not-found-gpgsappcontroller-mm-xcode.294398/
A similar issue on UnityAnswers:
http://answers.unity3d.com/questions/1098655/gpgsappcontrollermm-gidsigninh-file-not-found-erro.html
Im going through that aswell, and for #1 it has to be done in xcode, here's a screenshot of how to add those libs
And that is for #3
Hope that helps :) and I'll get back to you about #2 when I've found out about it ;)

Resources