Disabling NSLog For Production In Swift Project
You'll need to set up a compiler flag to use the Swift preprocessor - go to the Swift Compiler - Custom Flags section of Build Settings to set up a -D DEBUG
flag:
Then in your code you can define a DLog()
function and only print your message if the DEBUG
flag is set:
func DLog(message: String, function: String = #function) {
#if DEBUG
println("\(function): \(message)")
#endif
}
Do I need to disable NSLog before release Application?
One way to do it is to go into your Build settings and under the Debug configuration add a value to "Preprocessor Macros" value like:
DEBUG_MODE=1
Make sure you only do this for the Debug configuration and not for Beta or Release versions. Then in a common header file you can do something like:
#ifdef DEBUG_MODE
#define DLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog( s, ... )
#endif
Now instead of NSLog
use DLog
everywhere. When testing and debugging, you'll get debug messages. When you're ready to release a beta or final release, all those DLog
lines automatically become empty and nothing gets emitted. This way there's no manual setting of variables or commenting of NSLogs
required. Picking your build target takes care of it.
How to disable NSLog all over the app?
Xcode has a precompiled header file ({project-name}-Prefix.pch
in the Supporting Files group by default) that is a great place to put code that will be used across every file in the project. For going a step further and improving the log message itself, see Is it true that one should not use NSLog() on production code?.
How do I disable NSLog?
Update:
The answer bellow is actually much better. See here.
Initial answer:
There is a little hack that you could do. Search for all NSLog
and replace them with //NSLog
and than do another search for ////NSLog
and replace them with //NSLog
.
Hide strange unwanted Xcode logs
Try this:
1 - From Xcode menu open: Product
> Scheme
> Edit Scheme
2 - On your Environment Variables set OS_ACTIVITY_MODE
= disable
Remove println() for release version iOS Swift
As noted, i am a student and need things defined a little more clearly to follow along. After lots of research, the sequence I needed to follow is:
Click on the project name at the top of the File Navigator at the left of the Xcode project window. This is line that has the name of the project, how many build targets there are, and the iOS SDK version.
Choose the Build Settings tab and scroll down to the "Swift Compiler - Custom Flags" section near the bottom. Click the Down Arrow next to Other Flags to expand the section.
Click on the Debug line to select it. Place your mouse cursor over the right side of the line and double-click. A list view will appear. Click the + button at the lower left of the list view to add a value. A text field will become active.
In the text field, enter the text -D DEBUG
and press Return to commit the line.
Add a new Swift file to your project. You are going to want to make a custom class for the file, so enter text along the lines of the following:
class Log {
var intFor : Int
init() {
intFor = 42
}
func DLog(message: String, function: String = __FUNCTION__) {
#if DEBUG
println("\(function): \(message)")
#endif
}
}
I was having trouble getting the class to be accepted by Xcode today, so the init may be a bit more heavyweight than necessary.
Now you will need to reference your custom class in any class in which you intend to use the new custom function in place of println()
Add this as a property in every applicable class:
let logFor = Log()
Now you can replace any instances of println()
with logFor.DLog()
. The output also includes the name of the function in which the line was called.
Note that inside class functions I couldn't call the function unless I made a copy of the function as a class function in that class, and println()
is also a bit more flexible with the input, so I couldn't use this in every instance in my code.
Is it true that one should not use NSLog() on production code?
Preprocessor macros are indeed great for debugging. There's nothing wrong with NSLog(), but it's simple to define your own logging function with better functionality. Here's the one I use, it includes the file name and line number to make it easier to track down log statements.
#define DEBUG_MODE
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
I found it easier to put this entire statement in the prefix header rather than its own file. You could, if you wanted, build a more complicated logging system by having DebugLog interact with normal Objective-C objects. For instance, you could have a logging class that writes to its own log file (or database), and includes a 'priority' argument you could set at runtime, so debug messages are not shown in your release version, but error messages are (if you did this you could make DebugLog(), WarningLog(), and so on).
Oh, and keep in mind #define DEBUG_MODE
can be re-used in different places in your application. For example, in my application I use it to disable license key checks and only allow the application to run if it's before a certain date. This lets me distribute a time limited, fully functional beta copy with minimal effort on my part.
Objective-C: Removing NSLog calls from 'Distribution'/production builds?
A common solution is to place the following code in your Prefix file (or you may create a dedicated class and #include
it as needed):
#ifdef DEBUG
#define DebugLog(...) NSLog(__VA_ARGS__)
#else
#define DebugLog(...) while(0)
#endif
Xcode already defines DEBUG for you when performing a debug build (as shown in your screenshot). VA_ARGS is a way of creating variadic macros that was introduced in C99. the do/while
ensures that DebugLog
has the same net syntactic effect even when it doesn't do anything — don't worry about the pointless loop, the optimiser will remove it for you.
Then you can just use DebugLog
exactly as you'd use NSLog
. This will do exactly what you propose with VIEW_DEBUG
but without you having to copy and paste the #ifdef
condition a thousand times over.
Related Topics
How to Pass Data from One Container to Another, Both Embedded in the Same Uiviewcontroller in Swift
Get iOS Contact Image with Abpersoncopyimagedata
Auto Adjust Custom Uitableviewcell and Label in It to the Text
Remove Space Navigationtitle But Not the Back Button
Count Unseen Messages with Firebase in Swift
Set a Maximum Number of Children in Firebase
What Is Lldb_Expr in Swift Playground
How to Store Push Notification Alert Message in Userdefault
iOS 9 Orientation Auto-Rotation Animation Not Working, But Always on Main Thread
Integration New Facebook Sdk by Swift
Decode Base-64 Encoded Png in an Nsstring
Uiimageview Missing Images in Launch Screen on Device
How to Implement a Swiping/Sliding Animation Between Views
After Switching to Xcode 7, App Size Grew from 9 Mb to 60 Mb, Is There a Fix
Xcode 4: Build Failed, No Issues
Attempting to Load the View of a View Controller While It Is Deallocating... Uisearchcontroller
How to Add a Image in Email Body Using Mfmailcomposeviewcontroller