How do you debug an issue with a release mode build in iOS? - ios

I am working on an iOS app and I have noticed a bug that is only reproducible when the app is built in release mode. The only way I have found to run a release mode app that I have built is by building an archive, signing it with my debug profile, and doing an ad-hoc deployment to my device. Using this method however I can't attach with a debugger, and I'm not even sure if I could attach it if it would work well after the release build had run the optimizer on the code.
Does anyone know of a good way to debug an issue that is only reproducible when an app is build in release mode?

Normally Debug builds have optimisation disabled (-O0) to make debugging easier, whereas Release builds have optimisation enabled (-O3 or -Os), which makes the code run much faster, but also makes debugging harder (but not impossible). You can just go into the build settings in Xcode in the Debug configuration and temporarily turn up the optimisation level - this will keep all the other debug goodies (symbols etc) but hopefully also flush out the Release mode bug. (Don't forget to reset the optimisation level to -O0 in the Debug configuration when you're done!)

Go to "Project" command in an Xcode application menu and chose "Edit Scheme"(Shortcut: ⌘< )
Select "Run Project name" in left pane
In right pane, under "Info" tab change "Build Configuration" to "Release"

You can not run an app in release mode while have having debugging turned on. That is not intended.
When running an app in release mode you have to find a different way to observe the behaviour of your app (e.g. using alerts).
Additionally you will have to trust the distribution profile on your device. Xcode will notify and guide you with an alert message on the first run.

To debug an iOS application in release mode modify the settings:
Build Settings -> Deployment -> Deployment Post Processing -> Release -> set value as "NO"
Set 'Deployment Post Processing: Release' value as 'No'

I had to briefly turn on automatic signing in order to accomplish this. You aren't able to build directly on device with an iOS Distribution certificate (you need an iOS Development certificate) and you can't release to the App Store with an iOS Development certificate (you need an iOS Distribution certificate).
My debug mode was configured to use an iOS Development certificate to build directly on device. My release mode was configured to use an iOS Distribution certificate to allow the app to be installed on all devices. In order to run in release mode on device I switched to automatic code signing briefly to test. Once I was done testing, I used git to revert to the previous Xcode configuration.
Not the most elegant way, but it got the job done.

Related

Is there a way to disable firebase analytics with a scheme argument in Xcode?

I want to disable firebase analytics from collecting & sending events when I'm building, testing & debugging via an Xcode scheme argument, if able.
I'm aware you can edit the info.plist to disable (Firebase Docs) but would prefer a solution that doesn't require me to edit the .plist every time I'd like to switch between enabled and disabled.
Any suggestions?
You can configure two different plists into two different build targets, each with an associated scheme.
Details here.
Solution I came up with is very similar to Paul Beusterien's answer, but doesn't require a seperate scheme.
I made a copy of my current info.plist and named it info-debug.plist. I added the required key and value to disable firebase analytics.
FIREBASE_ANALYTICS_COLLECTION_ENABLED = 0
Then I selected my scheme Testing and under Packing -> Info.plist File -> Debug I set the value to info-debug.plist
Anytime I build and run my app in Xcode it will use info-debug.plist because my Build Configuration is set to the default: Debug. When I archive my app it will use info.plist as set by the Build Configuration for Release.
https://medium.com/geekculture/what-are-debug-and-release-modes-in-xcode-how-to-check-app-is-running-in-debug-mode-8dadad6a3428
Debug vs Release Mode
When you create a new project in Xcode, it defines two build
configurations, Debug and Release. By default, Debug configuration is
used during development whereas the Release configuration is used for
TestFlights or App Store. In other words, when you run the app on the
simulators or real devices by hitting the Run button(cmd + R), your
app is running with Debug configuration, aka Debug mode; when you
archive and upload a build to App Store Connect, app is running in
Release mode. However, this is just the default behavior. Technically,
you can run apps on simulators in any mode you want. It’s also true
for archiving(builds that you upload to the App Store Connect). To
change build configurations for development and archiving, you can go
to Product → Scheme → Edit Scheme(Command + <):

Dev mode vs production mode in React Native (Xcode)

Memory errors when testing on physical iPhone
I currently am experiencing memory issues when I run my react-native app on a physical device (iPhone connected through USB cable). I have tracked it down to too many console.log outputs. I have come across a couple of different solutions:
On this [React-Native page][1] Facebook recommends using the babel-plugin-transform-remove-console plugin. It is to be installed to work in dev mode only npm i babel-plugin-transform-remove-console --save-dev with the following code in .babelrc:
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
Note: I do not have a .babelrc file. I only have a babel.config.js file.
Some people are recommending using:
if (!DEV) {
console.log = () => {};
}
I believe this is setting any instance of console.log to an empty object if you are not in DEV mode.
Issues with getting accepted at the App Store
Apple is rejecting my app due to a bug at the point this memory error is happening. So, I am assuming that the console.log() statements are being compiled with the app and that they are encountering the memory error as well. They have not told me that there is a memory error, but just that it is not working at that particular point.
DEV mode vs Production mode
With options 1 and 2 above both assume a production mode vs a dev mode. However, when I compile the app with Xcode to upload to the App Store, how do I know what mode it is going to be in?
When I select Product>Archive from Xcode does that automatically put it in Production mode instead of Dev mode? Or is there something else I am needing to do to ensure that it is compiling it in production mode?
When you archive your app in Xcode it will be in "PROD" mode (aka release mode). In Xcode you can run your app in both DEV (aka debug mode) and PROD in Xcode. That will make it easier for you to get to the bottom of this memory issue.
To do this:
1. select the scheme you're working with in the top bar, click "Edit scheme"
2. and then set "Build configuration" to Release, and uncheck "Debug executable"
You can select any Simulator or connected device press the "Play" button to run a release build, with all the performance optimizations that come with that.
what you have after doing archiving is a production code.
And in my cases, my production app got stuck when it stumbles to a code which logging a React.createRef() object. In dev mode everything is ok.
You may try using if(__DEV__){...} to log anything, as all those console.log still fire in production

How can I attach to released in the testflight application to debug?

I have XCode, Device with the application installed via testflight, Release IPA, dSym.
Simple attach to process fails.
error: attach by pid '66475' failed -- unable to attach
I want to debug using IDE. Is it possible?
You can't do this. For the debugger to be able to attach to a process, the app binary needs to be signed with a special entitlement (get-task-allow). Otherwise the OS will deny the debugger's ability to attach - as you have seen. The Store doesn't allow you to submit apps that have this entitlement, so you can't debug released versions of your app. OTOH, nor can anyone else, which many folks view to be a good thing...
You can make a "DebugRelease" Configuration that uses the same settings as your release build but adds this entitlement by hand if you need to debug the code that comes from the Release build - in case you have bugs that only show up in the fully optimized build, for instance. You just can't debug the Store version.

Run app phonegap with xcode on jailbroken iPhone

I developed an app with phonegap, and I hate to try on a apple device. I've jailbroken my iPhone5s for try my app without pay apple.
I follow this guide, but seems does't work:
On your Jailbroken device install AppSync Unified 5.2-1 (or later)
from AngelXWind’s repo. Don’t use any other AppSync, and if you have
others, be sure to remove them. Open
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/SDKSettings.plist
and change AD_HOC_CODE_SIGNING_ALLOWED to YES. You may need to
duplicate it to the desktop, change it, save it, then drag and drop
back into the original folder because OS X let you edit the file in
place. If XCode was running, restart XCode. Change your Project and
Target settings to “Ad Hoc Code Sign” in Build Settings Tell XCode to
run app on iPhone. At this point XCode will put app on your iDevice,
but can’t debug because it can’t attach to the process. The app will
start then close immediately. You can now manually start the app on
the phone now though. To enable debugging: In your project select
File>New File Property List and create a file called
“Entitlements.plist”. Add “Can be debugged” or “get-task-allow” (both
do the same thing) and set the value to YES. Now change your Project
and Target Code Signing Entitlements (In Build Settings) to
“Entitlements.plist” (you have to type it in). Now XCode can run and
debug the app. Good luck
This is the link of the guide.
When I run app, XCode tell me "Build Success", and on top it says :"Running on Iphone". If I open detail, it say: "Preparing to install " with a loading circle. It's 20 minute that is preparing to install my app.
How can I fix this problem?

use instruments - leaks with a device

I'm starting to use Instruments-Leaks with an iPhone 3G. When I try to run the app with Instruments on the iPhone I obtain
Target failed to run: Remote exception encountered: 'Failed to get task for pid 280'
Ideas?
The only time I succeed in running the app with instruments it run very slow, I couldn't test it.
What are the steps to run the app on the device searching for leaks?
The solution for me was to make sure that my Profile scheme was using the "debug" and not "release" build configuration.
In Xcode 4 select Product/Edit Scheme from the top menu
then click on the "profile" button on the left.
On the "info" pane you will see a setting for Build Configuration- set that to "debug"
This error is also thrown if you are trying to test your app on a device with a distribution profile selected. Make sure you have the correct code-sign settings for development.
You CAN profile the release build on the device. What you have to do is build the release build with a developer certificate. See here.
Instruments basically does its work by becoming the debugger for the app. If you can't run Xcode's debugger against it, then you can't run Instruments against it.
Mostly, entitlements need to be set to allow debugging.
Sometimes after using XCode to debug apps, I find I can't use Instruments until I reboot the device.
Unlike XCode, Instruments can be confused between two apps with the same name, but different bundle IDs. (Or perhaps same name and similar bundle IDs.) When I have multiple versions of an app on a device, I often have to delete the extra to get Instruments to connect to the correct app. If you have one debug build and one release build, this could be the problem.
So, delete any duplicates of your app and restart the device. (You could change the display name for release and debug build configurations.)

Resources