Swift app function not called in release mode - ios

I have a iOS Swift app. I recently added a feature and uploaded the new version to TestFlight. For some reason, the main function for this new feature is not being called in release mode, but works perfectly in debug mode.
What I tried so far: within 'Apple LLVM 6.0 - Code Generation' for Release
1) Changed Optimization Level to None, and
2) Changed 'Symbols Hidden By Default' to No
I do not believe that the function's specifics matter here, but for what it's worth: it receives and manipulates some JSON data from the backend. I have ten other functions which do exactly the same thing for different types of data - not facing the same problem there.
Any ideas around this? What other differences are there between Release Mode and Debug Mode? that might be a good start to troubleshoot.
Thanks,

What other differences are there between Release Mode and Debug Mode?
Aside from different device architectures, there's a DEBUG preprocessor macro that is excluded in Release.
You can make a scheme that allows you to debug in Release mode, and check where it breaks.

Assertions will not run in release mode. Sometimes people make this mistake (I've made it a few times over the years):
assert(doSomethingImportant(), "Failed")
This works in Debug, but doSomethingImportant doesn't get called in Release.

Related

Could Xcode affect app performance while debugging?

I have an application written in Swift on SceneKit + Metal. When I build and run the app from Xcode fps counter shows 40fps. But if I run the app myself by tapping the icon on springboard fps counter shows 60fps. How could it be? Could Xcode somehow affect app performance while debugging? I have no idea how this all works, but I suppose there could be some hooks for debugging to work correctly which affect performance. If so, can I opt-in from this?
I'm aware of different build flags for debug and release builds, but I don't make release build. Performance differs in the same debug build while running from Xcode vs when I run the app manually on the phone.
By default, Xcode enables the Metal validation layer. That does a bunch of additional checking of how you're using it to catch incorrect uses. The additional checking is slow, which is why Metal doesn't do it unless validation is enabled.
This can be changed in Xcode's Scheme editor. This is documented in Apple's Metal Programming Guide.
A nice tutorial on iOS Assembly. This might be insightful on the topic
As stated, this is because the compiler is in debug mode, meaning no optimizations are made. If you turn optimizations on, then you’ll see a much smaller function generated.
And also check out this answer about changing optimization levels.
I've experimented with different options in scheme editor and have find out that Debug executable checkbox affected performance in my case. So my assumption about debugger was right, but I didn't know about that checkbox before.

IOS/Objective-C: Removing NSLog statements for Release and Build Settings in 2018

A lot of tutorials and answers on SO from the 2008 to 2013 eras say you should remove NSLog statements before releasing an app on the Apple store due to the high overhead of NSLog.
However, by default, Apple seems to have two build configurations, Debug and Release and when you archive the app for release, it now seems to automatically assign the Release configuration.
My question is, in light of this, do you still need to remove the NSLogs or does the Release configuration now automatically do this for you?
Many of the previous answers suggest making an entry in the pch file which no longer exists by default. If you use an alternative debugger apparently you are supposed to make an entry in the Preprocessor Macros however this is beyond my level of knoweldge.
Can anyone shed some light on the preferred approach to the NSLog issue today.

DYLD_PRINT_STATISTICS not showing anything

I'm trying to profile app startup after moving from static libraries to frameworks. We have 30 or so frameworks (fyi: cocoapods) so I want to check that it's not affecting performance. Anecdotal testing in the team says that it isn't, but I would like some numbers as well!
I've added the environment variables DYLD_PRINT_STATISTICS and DYLD_PRINT_LIBRARIES to see what the linker is doing, but all the output I get is from the DYLD_PRINT_LIBRARIES variable. I can see that the frameworks are loading correctly, but get no statistics from them.
I've tried restarting the device to make sure that the frameworks aren't in memory already but that hasn't helped.
Any other suggestions as to why I'm not getting any output from DYLD_PRINT_STATISTICS?
Looks like you can do it on device if you enable both environment variables in your scheme:
DYLD_PRINT_APIS = YES
DYLD_PRINT_STATISTICS = YES
Reference:
https://github.com/artsy/eigen/issues/586#issuecomment-118606377
While other flags, like DYLD_PRINT_BINDINGS work fine on the device, DYLD_PRINT_STATISTICS only seems to work on the simulator (for me, iOS 9.0).
In this (possibly unrelated) version of dyld.cpp, from osx 10.10.5 there doesn't seem to be any obvious exclusion of DYLD_PRINT_STATISTICS for devices, although there are conditionally compiled TARGET_IPHONE_SIMULATORs sprinkled throughout the code.
I guess it's a bug.

Creating iOS framework: how to prevent insight into source code while debugging

I've just developed my own (universal) framework with Xcode. When I import it into a test project (which definitely needs the classes of my framework), all runs well - both with the simulator as well as a real device (iPhone).
I've built a debug and a release version.
Under "edit schemes", I've also disabled "view debugging" within the release version.
However, when I set a break point into my source code of my test project (which - as mentioned - fetches some info from the release version of my framework), I can still step into the classes (.m files) without any problems.
As I want to deliver this framework to paying customers, I want to prevent anybody from seeing my source code while debugging. Experimenting with several flags in "build settings" had no effect ...
Any ideas?
nobody could help me, so I rookie had to help myself :-)
The solution could no bet easier:
just goto Targets -> Build Settings and then make a search for "Generate Debug Symbols" - arrived there, simply change form YES to NO
... and that's it!
Happy Frameworking :-)

Script for checking Build Mode in Xcode

I am creating a iOS Static Library in Xcode. I will be distributing two separate binaries, one for running in simulators(x86 architecture) & other for devices(ARM architecture).
I am aware of aggregate target, but I want to know whether it is possible to write a script to check whether the code is running in Debug or Release mode, i.e in Simulator(debug) or Device(Release) in ideal scenario.
Depending on this, I can put some check in my respective binary to compile or not.
Devices do not run in debug or release. The user chooses to build their target in debug or release. You can supply a debug version of your library, if you'd like, though. That is something I have seen other vendors do, and is greatly appreciated by developers.

Resources