I have a native iOS app, and we're using react-native to embed a Facebook-style social feed. To run in debug mode I use the packager server and the following code:
NSURL *jsCodeLocation = [NSURL URLWithString:#"http://X.X.X.X:8081/index.ios.bundle?platform=ios"];
bridgeReactView = [[RCTBridge alloc] initWithBundleURL: jsCodeLocation
moduleProvider: nil
launchOptions:nil];
rootReactView = [[RCTRootView alloc] initWithBridge:bridgeReactView
moduleName:#"SocialFeed"
initialProperties:#{}];
where X.X.X.X is my local IP address. This works fine, but I can't get it to bundle the react code into the release version. From the official docs and other Stack Overflow posts I've gathered that it was originally necessary to manually bundle the code with something like
react-native bundle --entry-file="index.ios.js" --bundle-output="./ios/MyApp/main.jsbundle' --dev=false --platform='ios' --assets-dest="./ios"
and change the jsCodeLocation definition above to
*jsCodeLocation = [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
Apparently, in more recent versions of react-native, xCode will bundle the code for you automatically if you choose the release build configuration, in which case you must change the above to
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index.ios" fallbackResource:nil];
Neither of these methods work for us - in both cases jsCodeLocation gets set to nil, and I get the "No bundle URL present" error:
2017-05-08 15:06:56.738 [fatal][tid:main] No bundle URL present.
Make sure you're running a packager server or have included a .jsbundle file in your application bundle.
Incidentally, I have tried setting the following values in my Info.plist file:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
</key>
You should do the following:
Run the following command:react-native bundle --dev false --platform ios --entry-file index.ios.js --bundle-output ios/main.jsbundle --assets-dest ./ios
Add main.jsbundle and assets directory to xcode by dragging them in your project.
Note: You only have to run step 2 the first time.
Mina M's answer was so close for me but I was getting a File not found: index.ios.js in any of the project roots error when calling the command. The reason behind this was because I no longer have the separate index.js files for Android and iOS - I have 1 (Which I believe it standard practice now?).
Solution - run this in the root of your React Native project (the folder with your android, ios and node_modules folders in):
react-native bundle --dev false --platform ios --entry-file index.js --bundle-output ios/main.jsbundle --assets-dest ./ios
Then you'll have to do step 2 and drag the main.jsbundle file and assets folder that have just been created in your ios folder, into the your project root within Xcode.
In your code you stated that your bundle is in:
http://X.X.X.X:8081/index.ios.bundle?platform=ios
But if it's a local ip or not accessible to outside network rather than your development environment, bundle url may cause such issues.
Related
All of a sudden my flutter app does not install on iOS. It has been working and building for a long time, and then all of a sudden I get this error...
Unable to install /Users/me/src/myapp/client/build/ios/iphonesimulator/Runner.app on F0FDB4EA-7E61-49D5-A39F-BA1C10D0CFA4. This is sometimes caused by a malformed plist file:
ProcessException: Process exited abnormally:
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=22):
Failed to install the requested application
The bundle identifier of the application could not be determined.
Ensure that the application's Info.plist contains a value for CFBundleIdentifier.
Command: /usr/bin/arch -arm64e xcrun simctl install F0FDB4EA-7E61-49D5-A39F-BA1C10D0CFA4 /Users/me/src/myapp/client/build/ios/iphonesimulator/Runner.app
Error launching application on iPhone 13.
My info.plist definitely exists and has the bundle identifier specified as....
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
For some reason I am getting the following error when building a release version of my application via react-native.
*** Terminating app due to uncaught exception 'RCTFatalException: Unhandled JS Exception: t.typeof is not a function. (In 't.typeof("function"==typeof Symbol?Symbol.iterator:"##iterator")', 't.typeof' is undefined) (/Users/../THEAPP.app/main.jsbundle:11)', reason: 'Unhandled JS Exception: t.typeof is not a function. (In 't.typeof("function...'
This is the source of the code that has the above error that I found in my bundlejs file:
!(function(e){"use strict";var r,t=e.babelHelpers={};t.typeof="function"==typeof Symbol&&"symbol"===t.typeof("function"==typeof Symbol?Symbol.iterator:"##iterator")?
I have tried both of these methods of a release build:
Making bundle by editing the Scheme to be a Release bundle
Export a bundle myself by using the following: react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios
I get the same error for both of these. And of course, this is after I change my AppDelegate.m to the following:
//jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
jsCodeLocation = [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
I also followed someone's response from Github issues and tried the following, but got another separate issue entirely after the fact:
I did:
npm uninstall -g babel-preset-env
npm install --save #babel/preset-env
Added this to my package.json file
"babel": { "presets": ["#babel/preset-env", "react-native"] }
And created a .babelrc file in my root project with:
{ "presets": ["#babel/preset-env", "react-native"] }
Then get this on an Xcode build:
Environment
OS: macOS High Sierra 10.13.4
Node: 9.11.1
npm: 5.6.0
Watchman: 4.9.1
Xcode: Version 9.4 (9F1027a)
react: 16.3.1
react-native: 0.55.4
I solved this by completely restarting my app and using:
react-native init PROJECTNAME
I have set CFBundleShortVersionString & CFBundleVersion in App_Resources/iOS/info.plist as
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0.0</string>
using nativescript:
tns-ios: 2.1.0
tns --version: 2.1.0
here is the tns publish ios output:
ERROR ITMS-90057: "The bundle 'Payload/<XYZ>.app/Frameworks/NativeScript.framework' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString."
ERROR ITMS-90057: "The bundle 'Payload/<XYZ>.app/Frameworks/NativeScript.framework' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString."
For some reason it does not find the mentioned key. Any ideas?
Thanks
Update:
Open platforms/ios/Internal/NativeScript.framework/Info.plist in Xcode.
change bundle Version : 2.1.0
add bundle versions string, short : 2.1
This is a known bug in v2.1 of NativeScript; you actually need to modify the
/platforms/ios/Internal/NativeScript.framework/Info.plist
file with those two keys.
See: https://github.com/NativeScript/NativeScript/issues/2397
RE (don't have enough experience points to reply there):
"In my bundle command for my production build I tell it to generate a source map"
How to add sourcemap in React Native for Production?
In Xcode Version 7.3 beta 3, I went to [My Project] > Build Phases > Bundle React Native code and images
Under:
export NODE_BINARY=node
../node_modules/react-native/packager/react-native-xcode.sh
I added:
cd /Users/andresn/dev/[My Project]
react-native bundle --platform ios --entry-file index.ios.js --dev false --bundle-output ./ios/main.jsbundle --assets-dest ./ios --sourcemap-output ./sourcemap.js
Is something like this what he meant, or is there a more proper way of doing this?
I ended up using the following script in Bundle React Native code and images:
export NODE_BINARY=node
if [ "${CONFIGURATION}" = "Release" ]
then ../sourcemap.sh
else ../node_modules/react-native/scripts/react-native-xcode.sh
fi
Then in the project directory's root, I'm using the following sourcemap.sh script which generates a source map file in the ./ios directory:
#!/bin/bash
$NODE_BINARY ../node_modules/react-native/local-cli/cli.js bundle --platform ios --entry-file ./index.ios.js --dev false --bundle-output ./main.jsbundle --assets-dest ./ --sourcemap-output ./main.jsbundle.map
A generic solution based on what you've already said:
export NODE_BINARY=node
if [ "${CONFIGURATION}" = "Release" ]
then
cd "${PROJECT_DIR}/../"
react-native bundle --platform ios --entry-file index.ios.js --dev false --bundle-output ./ios/main.jsbundle --assets-dest ./ios --sourcemap-output ./ios/main.jsbundle.map
else
../node_modules/react-native/scripts/react-native-xcode.sh
fi
Be sure to add the assets and main.jsbundle.map to your iOS project then create your release build again.
When submitting my app to the app store I get this error:
Here is the relevant part from my info.plist file:
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
When I submit the app you can clearly see that there is no version 1.0.0.pre.
I use CocoaPods as well.
How do I solve this problem?
Update: Here is what I try on my project path: find . -name "*.plist" -exec grep -o -A 1 "CFBundleShortVersionString" {} \; and here is the result:
CFBundleShortVersionString
<string>1.0.6</string>
CFBundleShortVersionString
<string>1.0</string>
CFBundleShortVersionString
<string>3.3.4</string>
CFBundleShortVersionString
<string>1.5.5</string>
CFBundleShortVersionString
<string>2.0.2</string>
CFBundleShortVersionString
<string>0.7.0</string>
CFBundleShortVersionString
<string>0.0.9</string>
CFBundleShortVersionString
<string>1.2.2</string>
CFBundleShortVersionString
<string>1.6.0</string>
CFBundleShortVersionString
<string>1.7.2</string>
CFBundleShortVersionString
<string>2.0.0</string>
CFBundleShortVersionString
<string>1.3.2</string>
CFBundleShortVersionString
<string>1.4.1</string>
CFBundleShortVersionString
<string>1.0</string>
CFBundleShortVersionString
<string>0.9.1</string>
CFBundleShortVersionString
<string>0.2.3</string>
CFBundleShortVersionString
<string>1.0.0</string>
CFBundleShortVersionString
<string>3.7.3</string>
CFBundleShortVersionString
<string>0.15.0</string>
CFBundleShortVersionString
<string>1.0.0.pre</string>
CFBundleShortVersionString
<string>2.3.0</string>
CFBundleShortVersionString
<string>2.0.0</string>
CFBundleShortVersionString
<string>1.2</string>
CFBundleShortVersionString
<string>3.0.2</string>
Update 2: Doing: xcodebuild > build.log I get the following error:
2015-10-25 22:02:52.653 xcodebuild[6273:1043943] [MT] PluginLoading: Required plug-in compatibility UUID 7265231C-39B4-402C-89E1-16167C4CC990 for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/VVDocumenter-Xcode.xcplugin' not present in DVTPlugInCompatibilityUUIDs
** BUILD FAILED **
Locating Version Numbers
Since you don't see the string within your project it's likely there is a bundle, frameworks or libraries associated with your project that is responsible. From the topmost directory in your project you can use find in addition to grep to look for the culprit:
find . -name "*.plist" -exec grep -iq "CFBundleShortVersionString" {} \; \
-exec grep -Him 1 "1.0.0.pre" {} \;
This may return results that might resemble something such as:
Binary file ./FooProject/Foo.framework/Info.plist matches
./FooProject/Resources/Info.plist- <string>1.0.0.pre</string>
In the event results are returned then you'll have located the reason for the "ERROR ITMS-90096 This bundle is invalid. The value for key CFBundleVersionShortString...". If the result returned is within a Framework as shown in the first result above (eg. Binary file) or another bundle/library then you will need to change the value within it's defined project (provided that it's simply a mistake in the version number). You could also create a clean up script to replace the value at build time before code signing.
1.0.0.pre
The more important thing here though is why your app was rejected and what the 1.0.0.pre version was created specifically to do. Using a version tag that purposefully makes your app get rejected was meant to prevent you from using prerelease code in a production app — it's by design. The person(s) who created that specific pod, bundle, framework, library, are telling you:
"Don't use this prerelease code in an app that you are planning to deploy to the public".
I would suggest not just simply changing the version number of the items .plist so that your app submits successfully — instead check for a stable release version meant for production.
Multiple Info.plists
Frameworks, pods, and bundles all have their own .plist and version numbers. They are not "overriding" your main applications version number but rather simply have their own (one of which obviously not valid).
Check 1:
You may want to search for "version" in the build settings. In case of weird situations I usually use this "view":
Go to the Build Settings.
On the left hand side from "Basic All" select "All"
On the left hand side from "Combined Level" select "Level"
In the search box type "version" and press return/enter
In my MacOSX test project it looks like this:
Note that there is an entry named "version name suffix". I'm not sure, whether or not this exists in an iOS project (will test later). In any case you can look through the settings which "easily" relate to "version".
Check 2:
Alternatively you could grep the project file:
grep pre MyProject.xcodeproj/project.pbxproj
Check 3:
Open a terminal and in the project directory call this:
xcodebuild clean
xcodebuild > build.log
with cocoapods likely this:
xcodebuild -workspace PRJ.xcworkspace -scheme PRJ clean
xcodebuild -workspace PRJ.xcworkspace -scheme PRJ > build.log
In build.log search for "ProcessInfoPlistFile". In my case it looks like this: (manually wrapped - actual project name changed)
ProcessInfoPlistFile build/Release-iphoneos/PRJ.app/Info.plist PRJ/Info.plist
cd /Users/fsc/prj/PRJ
export PATH="/Applications/Xcode.app/..."
builtin-infoPlistUtility /Users/fsc/prj/PRJ/PRJ/Info.plist
-genpkginfo /Users/fsc/prj/PRJ/build/Release-iphoneos/PRJ.app/PkgInfo
-expandbuildsettings -format binary -platform iphoneos
-additionalcontentfile /Users/fsc/prj/PRJ/build/PRJ.build/Release-iphoneos/PRJ.build/Main-SBPartialInfo.plist
-additionalcontentfile /Users/fsc/prj/PRJ/build/PRJ.build/Release-iphoneos/PRJ.build/LaunchScreen-PartialInfo.plist
-additionalcontentfile /Users/fsc/prj/PRJ/build/PRJ.build/Release-iphoneos/PRJ.build/assetcatalog_generated_info.plist
-o /Users/fsc/prj/PRJ/build/Release-iphoneos/PRJ.app/Info.plist
Note the -additionalcontentfile. Please check which additional files are listed and check these.
Check 4:
Look into the IPA archive to see where the "1.0.0.pre" actually is found. For that open "Window > Organizer", select your app and press "Export...". Select "Save for iOS App Store Deployment". The result will be an .ipa file. Rename it to PRJ.ipa.zip - then you can unpack it. Look for the .plist files and check their content.
One of your 3rd party pod has the version number "1.0.0.pre". Seems the error relates to it. The error doesnt say which plist, perhaps your build has more than one. Eg the pod in question creates a bundle on its own for instance.
It is most likely a CocoaPods related problem, do not change the info.plist's in your frameworks manually, do these steps:
1) Add this script at the end of your Podfile.
post_install do |installer|
app_plist = "MyApp/Info.plist"
plist_buddy = "/usr/libexec/PlistBuddy"
version = `#{plist_buddy} -c "Print CFBundleShortVersionString" #{app_plist}`
version = `echo "#{version}" | tr -d '\n'`
puts "Updating CocoaPods frameworks' version numbers to #{version}"
installer.pods_project.targets.each do |target|
`#{plist_buddy} -c "Set CFBundleShortVersionString #{version}" "Pods/Target Support Files/#{target}/Info.plist"`
end
end
2) Update the path in app_plist variable so that it matches the path to your app's .plist file.
3) Run pod install afterwards.
This script changes all Cocoapods frameworks' version numbers to match the app's plist, which is required as of 21 Oct 2015.
Pod reinstall worked for me. you can try it once.