When I made any changes (JS, HTML, or even app version) in the MobileFirst project, then rebuild and redeploy the app to device or simulator/emulator, nothing appears to change in the application. If I uninstall the app from the device and redeploy the app, then the changes are visible in the app. This is not related to direct update. This only happens with iOS environment.
How to resolve this?
Apparently, the Run Script is missing in my Xcode project so the buildtime.sh file was never executed. As a result, buildtime property was not updated. With the same buildtime, nothing was updated in the app.
Solution:
In Xcode, select your project and open the Build Phase tab. Click on the + icon on the top left to Add a New Build Phase. Select the new Run Script Phase and copy/paste the following to the new script:
script_file="buildtime.sh"
echo "Running a custom build phase script: $script_file"
unsecure_project_path=${PROJECT_DIR}
secure_project_path="${unsecure_project_path// /\ }"
eval ${secure_project_path}/${script_file}
scriptExitStatus=$?
echo "DONE with script: ${script_file} (exitStatus=${scriptExitStatus})\n\n"
exit "${scriptExitStatus}"
The Run Script should look like this:
Related
I have this script:
node src/runlink.js
that I'm running with npm run link but I would like to run it when building my code with Xcode.
is there any way to do that ? I tried to do it with the build phase but haven't succeed
You need to run a script in Build Phases.
On the Project Navigator (left column) select your project.
Then on the Targets select your desired target
Clic on Build Phases tab
Click on the + sign to create New Run Script Phase
Type node "${SRCROOT}/../src/runlink.js"
I added react-native-sentry to a react-native project. I followed this manual: https://docs.sentry.io/clients/react-native/
Everything worked fine on Android and ios emulator. But when I tried to archive an app in xcode I got this error.
React native symbol handling failed
The Sentry build step failed while running in the background. You can ignore this error or view details to attempt to resolve it. Ignoring it might cause your crashes not to be handled properly.
If I click 'Show Details; I get this
error: EOF while parsing a value at line 1 column 0
I followed the advice from here https://github.com/getsentry/react-native-sentry/issues/135 and edited Build Phases > Upload Debug Symbols so now there is only this line there
export SENTRY_PROPERTIES=sentry.properties
The error still persisted. So I decided to ignore it. In this case after I upload the version to Itunesconnect and install it with a TestFlight it crashes immediately on start.
If I run it on a simulator or install it directly an iphone it works fine.
It also works fine on Android.
Could you give me any advice what can be done to make it work on Apple Store too?
For me this error was signaled by Xcode because of some problems when running the build scrips.
Using:
https://github.com/getsentry/sentry-react-native
#sentry/react-native": "^1.0.9
I fixed it keeping the index.ios.js always in the root folder (before that I had it in a src folder and trying to use a custom build script to take it from src)
I set the build scripts in Xcode to be similar to the ones from sentry docs:
Build RN code and images script:
// sentry properties file located in `ios` folder
export NODE_BINARY=node
export SENTRY_PROPERTIES=sentry.properties
../node_modules/#sentry/cli/bin/sentry-cli react-native xcode \
../node_modules/react-native/scripts/react-native-xcode.sh
Upload debug symbols script:
I have this script as the last one in Build Phases
export SENTRY_PROPERTIES=sentry.properties
../node_modules/#sentry/cli/bin/sentry-cli upload-dif
"$DWARF_DSYM_FOLDER_PATH"
Note:
1) I haven't tried yet to move sentry.properties file as common for both android and iOS, placed in root folder (with import ../sentry.properties in scripts) but I think that should work too.
2) I used the terminal to test directly the release build:
react-native run-ios --configuration Release --simulator "iPhone 8"
or
react-native run-ios --configuration Release --device "Your Device Name"
In my case the reason was a space included in the name of the hard disk I use to keep the Project, Derived Data and Archives. Looks like the Sentry CLI script doesn't like spaces in the path to the project and it crashes there.
It was enough to rename the disk and update paths to Derived Data and Archives and all is well now.
Hit build and nothing gets printed in build log. What gives?
Xcode Version 8.2.1 (8C1002)
Pre-action takes place before the build, so output doesn't go to the build log, it goes to stdErr. You can copy the output to a file:
exec > ${PROJECT_DIR}/prebuild.log 2>&1
echo "hello world"
To get the environment variables to work, you also need to set "Provide build settings from" to the appropriate target.
That should write hello world to a file named "prebuild.log" in your project folder.
for XCode versions < 13.2
If you want these activities to end up in the build log, consider adding a run script to your target's build phase instead.
for XCode versions >= 13.2
The XCode build log now includes a Run pre-actions section. If you don't redirect to a file, those messages will end up as the last item in a 'Run custom shell script' in this section - access via the XCode Report Navigator.
To add to the answer, https://stackoverflow.com/a/42497746/1058199, it's important to not clutter up the project.pbxproj (where build scripts go) or your scheme file (where these scripts go) as much as possible.
With this in mind, I create a Build-Scripts folder in the project root where I put the app build scripts and pre-action scripts. This folder is dragged into the root of the project as a folder so that any script I add to it is automatically added to project.
Assuming that your pre-action script is called That_pre-action_script.sh, this is what I put in Pre-actions script based on the approved answer.
say "Pre build scripts running."
exec > "${PROJECT_DIR}/prebuild.log" 2>&1
echo "Starting build scheme Pre-actions"
"${PROJECT_DIR}/Build-Phases/That_pre-action_script.sh"
As a test, make sure to echo some message from your script so you can see it in the prebuild.log file.
Hope this helps.
And don't forget to chmod u+x your script in the terminal so that it will run.
The important part is if you can't make sure if your build script is running or not. This is where the say command us useful so that you know it's actually being issued before a build.
It's a good idea to put quotes around the path to the script in case there are any space characters (or otherwise) in the path to your project.
When I build my project with Xcode 8, it saves the final build in ~/Library/Developer/Xcode/DerivedData/MyProject-[add-lots-of-random-chars-here]/Build/Products/Release-iphoneos. Is there any way to make Xcode copy the app bundle to a user-specified path after building it? e.g. how can I make Xcode copy the built app bundle to /MyBuilds after building it?
I know that I can change the path for storing derived data in my project's settings in Xcode but doing so will of course make Xcode store all data (including intermediate stuff like object code etc) in this location which I don't want. I really only want Xcode to copy the final, ready-for-distribution app bundle to a user-specified location without any intermediate files used in the build process.
How can I do that?
The solution using a script in "Build Phases" does not work properly since Xcode is not finished building the app when running the script. Here is a solution with a script that runs after all build tasks are finished:
Go to "Edit Scheme"
Click on the triangle next to "Build"
Select "Post-action"
Press the + button and select "New Run Script Option"
Select your app name in "Provide build settings from"
Add the following shell script:
Script:
PRODUCT="${BUILT_PRODUCTS_DIR}/${TARGET_NAME}.app"
cp -R "${PRODUCT}" ~/Desktop
Add a shell script to your build phases to copy the product:
Script:
PRODUCT="${BUILT_PRODUCTS_DIR}/${TARGET_NAME}.app"
cp -R "${PRODUCT}" ~/Desktop
Certainly replace ~/Desktop with a target directory of your choice.
I'm probably missing something simple here. I am trying to auto increment my build number in XCode 4.4 only when archiving my application (in preparation for a TestFlight deployment). I have a working shell script that runs on the target and successfully updates the info.plist file for each build. My build configuration for archiving is name 'Ad-Hoc'.
Here is the script:
if [ $CONFIGURATION == Ad-Hoc ]; then
echo "Ad-Hoc build. Bumping build#..."
plist=${PROJECT_DIR}/${INFOPLIST_FILE}
buildnum=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${plist}")
if [[ "${buildnum}" == "" ]]; then
echo "No build number in $plist"
exit 2
fi
buildnum=$(expr $buildnum + 1)
/usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnum" "${plist}"
echo "Bumped build number to $buildnum"
else
echo $CONFIGURATION " build - Not bumping build number."
fi
This script updates the plist file appropriately and is reflected in XCode each time I archive. The problem is that the .ipa file that comes out of the archive process is still showing the previous build number. I have tried the following solutions with no success:
Clean before build
Clean build folder before build
Move Run Script phase to directly after the Target Dependencies step in Build Phases
Adding the script as a Run Script action in my scheme as a pre-action
No matter what I do, when I look at the build log, I see that the info.plist file is being processed as one of the very first steps. It is always prior to my script running and updating the build number, which is, I assume, why the build number is never current in the .ipa file.
Is there a way to force the Run Script phase to run before the info.plist file is processed?
in Xcode 4.4.1 I create new target and add to this target build phase "Run custom script", which update main target Plist. And also, you should add this target to dependencies for main target
The reason that this happens is that by the time your "Run Script" gets run, the XCode build process has already processed the project's plist file to extract the bundle version number, etc.
You can see this (probably in more detail that you want) by going to the Log Navigator in XCode (View/Navigators/Show Log Navigator), and selecting an "Archive" build.
A detailed list of build actions should appear in your main window, and one of the things near the top should be one called Process <projectname>-Info.plist. If you expand this using the icon at the right hand side, you can see the actual build command that was run.
The way that I got around this was to update both the original plist file, and also the processed one. By doing this, you get your updated build version in the current build rather than the next one.
Here's the script that I use to do this (this is Ruby, so you would need to put "/usr/bin/ruby" in the interpreter box to use this, but the concept works the same with a shell script or any other scripting language):
def incrementBundleVersion(file)
oldVersion = `/usr/libexec/Plistbuddy -c "print :CFBundleVersion" #{file}`.strip
components = oldVersion.split('.')
newBuild = components.pop.to_i + 1
version = components.push(newBuild).join('.')
print "Updating version: #{oldVersion} -> #{version} : #{file}\n"
system("/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion #{version}\" #{file}")
end
incrementBundleVersion("#{ENV['PROJECT_DIR']}/#{ENV['INFOPLIST_FILE']}")
incrementBundleVersion("#{ENV['CODESIGNING_FOLDER_PATH']}/Info.plist")
Note that the processed file #{ENV['CODESIGNING_FOLDER_PATH']}/Info.plist is a binary plist file, so you won't be able to process it with simple text tools - using plistbuddy is the easiest way to handle this, and it automatically works with both text and binary plist files.
Mark (et al), I believe I've run into the same problem you are facing, and i will try to describe it in one sentence and then explain:
I think /usr/libexec/PlistBuddy, when run from inside Xcode, works on cached versions of the Info.plist data, and thus what gets finally written for execution on device or simulator is not always what you want.
I had tried writing post Copy Resource Bundle "Run Scripts" in order to change this info in a way that wouldn't cause it to change within my local git repo, only to discover that, whereas the information would work properly when the PlistBuddy commands were executed in a terminal.app window beside Xcode, if not done, the cached values would get written.
I finally resigned myself to running the version-info generation scripts prior to the Copy Bundle Resources phase and just auto-committing the changes in another Run Script, using the same tags for the git message and for the git tag that get auto-created. for the Settings.bundle/Root.plist file, rather than commit this every time, i preferred to just run a finalization script that would perform a 'git checkout -- ${PROJECT}/Resources/Settings.bundle/Root.plist' (which is where mine exists, but may not be where everyone puts their own system settings resource file).
between the checking for changes, running parts of it at install and parts of it every time, and having the finalization scripts at the end, there are 6 scripts for some targets and 7 for another …
… but the important thing to me is that it's finally properly automated … and gets around whatever PlistBuddy is doing to my plist files when processed inside of Xcode.