Xcode takes long time to print debug results. - swift

When I debug on Xcode it takes around 30 seconds or more to print results of po on Xcode console.
Unfortunately, this is only few information I have on the issue.
However, there is another point to consider. This issue is very specific to a project. This is because when I use po for other projects on same Macbook, it works immediately. Also, this particular project is slow on all other Macbook, and for all team.
I googled it but no relevant answer found. I find it easy to use print(...) rather than using debugging on Xcode console. However, it's more work and requires lots of rebuilds.

I have several explanations:
There is a lot of code (Xcode slows down after a certain amount of code) Also make sure your print statement is towards the top of your page. Xocde goes from top to bottom.
Your Mac is slow. Some Macs after a certain amount of usage slow down. Also if you have a Mac mini or air they are slower than others.
Xcode Beta. If you are using Xcode beta then there might just be a bug.
If none of those answer you provide me with more info and I provide other solutions.

Swift:
Try this solution which helps to reduce log time in debug mode.
Step 1: Create a new file called Utils.swift (File name based on your preference)
Step 2: Add following code in file
import Foundation
import UIKit
struct Utils { }
public func PrintLogs(_ message: Any, file: String = #file, function: String = #function, line: Int = #line) {
#if DEBUG
let className = file.components(separatedBy: "/").last ?? ""
let classNameArr = className.components(separatedBy: ".")
NSLog("\n\n--> Class Name: \(classNameArr[0]) \n--> Function Name: \(function) \n--> Line: \(line)")
print("--> Log Message: \(message)")
#endif
}
Usage: Call PrintLogs("Hello") instead of print("Hello")
Sample Output:
--> Class Name: HomeViewController
--> Function Name: logTest()
--> Line: 81
--> Log Message: Hello

Related

How to resolve Abort trap: 6 ERROR - xcode 12

We have faced the issue of "abort trap 6" in Xcode 12. Due to this reason app not running using Xcode 12. We are using the swift 5 versions and jsqmessageviewcontroller objective c library.
Below errors getting in Xcode 12.
<unknown>:0: error: fatal error encountered while reading from module 'wwww'; please file a bug report with your project and the crash log
<unknown>:0: note: module 'wwww' full misc version is '5.3.2(5.3.2)/Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)'
top-level value not found
Cross-reference to module 'JSQMessagesViewController'
... JSQMessageMediaData
error: Abort trap: 6 (in target 'zapwww' from project 'zapwww')
If anyone has a solution please help us.
I had the same error in Xcode 12.5.1 and it seems to be a bug that has been fixed in the next beta. However there seem to be several issues that could cause this error. So my solution might not work.
For me the problem was very specific and only happened in the following scenario:
A method that returns an optional RealmObject (might be different in your case) is called.
The returned RealmObject has been assigned a variable.
Trying to unwrap the variable with guard let or if let using the same name for the new safely unwrapped variable.
The easiest fix is using different variable names or
Safely unwrapping the returned object directly without assigning it a variable.
Example that causes the error in my case:
class MyClass {
func returnObject() -> Object? {
return nil
}
func anyMethod() {
let myObject = returnObject()
guard let myObject = myObject else { return } // <-- works anywhere else but here.
}
}
Same example that fixed the error in my case:
class MyClass {
func returnObject() -> Object? {
return nil
}
func anyMethod() {
let myObject = returnObject()
guard let myNewObject = myObject else { return } // <-- Changed name of new variable here
}
}
I've seen people had this issue with other types, so it's not limited to the RealmObject type. But going through all guard let or if let with the same variable name is a good start.
I've also seen other people use fix it by cleaning the build folder or removing packages and reinstalling them. That didn't help for me though.
Problem: Abort Trap (In my case my code is working perfectly but when I trying to make an Archive file I got the "Abort Trap")
Solution:- Just Select Your Project from project Navegater (most Left Pane) Select Project > Select Targets > Build Settings > Swift Compiler - Code Genration > Optimization Level > Debug and Realease make "No Optimization [-Onone]"enter image description here
Flutter Specific
I had to set Optimization Level to No Optimization [-Onone] for Pods target.
Just Select Your Project from project Navigater (most Left Pane) Select
Pods > Build Settings > Swift Compiler - Code Generation > Optimization Level > Debug and Realease make No Optimization [-Onone]
for me i have just remove the library which cause the problem from pods file , then installed again will fix the problem
just had to run: 'pod update' to update my Realm pods and fixed it for me.

Swift: OSLog/os_log not showing up in console app

I am building a Swift 5 application with XCode 10.3. For this, I have a framework which contains a implementation for a logsystem (for debugging purposes). The default implementation for this logsystem is based on OSLog/os_log. When using the system in the consuming app, then none of the logs appear in the Console app. However, when placing breakpoints, I can see that the os_log statement (see code example below) is reached and that the correct parameters are passed on to the os_log function. However, when I use os_log or NSLog in the host application, then they do show up.
I have verified that it is not an issue with the LogSystem / DefaultLogImplementation types as all of the breakpoints that need to be hit, are hit, and all unit tests are green. In addition, the os_log statement is reached and executed, but the logs do not appear. I have verified that all messages are shown in the console app, I have verified that I have selected the correct device, I have tried multiple filters (and even dug through all the logs without filters enabled)...
Can anyone help / give a pointer at what the issue may be? I am currently suspecting that there is a bug in the implementation of OSLog/os_log.
Code sample
App-side code, which consumes code similar to the examples provided below
class SomeClass {
private let logSystem = LogSystem()
func doSomethingImportant() {
// Do important stuff and log the result
logSystem.debug("Finished process with result \(result)")
}
}
Framework-side code, which is consumed by the app
public class LogSystem {
private let logImplementation: LogImplementation
init(_ logImplementation: LogImplementation = DefaultLogImplementation()) {
self.logImplementation = logImplementation
}
public func debug(_ message: String) {
logImplementation.log(message, type: .debug) // And some other parameters...
}
public func error(_ message: String) {
// Similar to debug(:)...
}
}
public protocol LogImplementation {
func log(_ message: String, type: LogType, ...other parameters...)
}
public class DefaultLogImplementation: LogImplementation {
func log(_ message: String, type: LogType, ...other parameters...) {
let parsedType = parseLogType(type) // Function that parses LogType to OSLogType
let log = OSLog(subsystem: "my.subsystem.domain", category: "myCategory")
os_log("%{private}#", log: log, type: parsedType, message) // Breakpoint here is reached, but log does not appear in console app (even with debugger attached, which should remove the effect of "%{private}%". Either way, at the very least censored logs should still appear in console app.
}
}
Additional info
Swift version: 5.0
XCode version: 10.3
Target device: iOS 12.2 iPhone X simulator
NSLog appears in console app: Yes
Selected correct device in console app: Yes
Correct filters: Yes
Update 2019-08-16 13:00 (Amsterdam time)
It appears that only .debug level messages are not appearing in the Console app. This bug occurs when using any simulator device in combination with OSLog. I have tried several commands to fix this:
sudo log config --mode level:debug,persist:debug
sudo log config --subsystem my.reverse.domain.name --mode level:debug,persist:debug
Neither of them fixed the issue. In fact, not a single debug-level message of the simulator is showing up in the console app (not even from iOS itself). Yes, the option to show .info and .debug level messages is enabled.
I tried setting the log-level for the simulator specifically through the following command:
xcrun simctl spawn booted log config --mode level:debug
But this result in an error:
log: Simulator unable to set system mode
In the console app, there are two options to include / hide debug and info messages:
I've spoken with an Apple DTS Engineer and it's a know issues not being able to see debug messages using a simulator (in Xcode 11 too): open a feedback

How to print out the method name and line number in swift

Here is an example of what I want to do:
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError)
{
let nm = NetworkModel()
nm.sendlog("file name :AppDelegate , line number : 288", info: " Failed to register: \(error)")
}
current scenario i done that hard coded value line number and file name . but is it possible to programatically pick line number and file name .
Literal Type Value
#file String The name of the file in which it appears.
#line Int The line number on which it appears.
#column Int The column number in which it begins.
#function String The name of the declaration in which it appears.
#dsohandle UnsafeMutablePointer The dso handle.
Example
print("Function: \(#function), line: \(#line)")
With default values in parameters you can also create a function
public func track(_ message: String, file: String = #file, function: String = #function, line: Int = #line ) {
print("\(message) called from \(function) \(file):\(line)")
}
which can be used like this
track("enters app")
In Swift 2.1
Literal Type Value
__FILE__ String The name of the file in which it appears.
__LINE__ Int The line number on which it appears.
__COLUMN__ Int The column number in which it begins.
__FUNCTION__ String The name of the declaration in which it appears.
for more info see the documentation
You can use #function, #file, #line
Here is the implementation of log method in swift : https://github.com/InderKumarRathore/SwiftLog
Below is the snippet
public func debugLog(object: Any, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
#if DEBUG
let className = (fileName as NSString).lastPathComponent
print("<\(className)> \(functionName) [#\(lineNumber)]| \(object)\n")
#endif
}
For swift 4 and swift 5:
func printLog(_ message: String, file: String = #file, function: String = #function, line: Int = #line) {
#if DEVELOPMENT
let className = file.components(separatedBy: "/").last
print(" ❌ Error ----> File: \(className ?? ""), Function: \(function), Line: \(line), Message: \(message)")
#endif
}
// "❌ Error ----> File: classNameViewController.swift, function: functionName(), Line: 123, Message: messageError"
Example Logging Code (TL;DR)
import os.log
#available(OSX 11.0, iOS 14.0, *)
extension Logger {
private static var subsystem = Bundle.main.bundleIdentifier!
/// Logs the payment flows like Apple Pay.
#available(OSX 11.0, iOS 14.0, *)
static let payments = Logger(subsystem: subsystem, category: "payments")
}
static func DLog(message: StaticString, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, column: UInt = #column, category: String, type: OSLogType = .info, bundle: Bundle = .main) {
// This method is only for iOS 14+
if #available(OSX 11.0, iOS 14.0, *) {
Logger.payments.debug("\(file) : \(function) : \(line) : \(column) - \(message, privacy: .private)")
// This makes the message unreadable without a debugger attached.
} else {
// Fallback on earlier versions
let customLog = OSLog(subsystem: bundle.bundleIdentifier!,
category: category)
// IMPORTANT: I have assumed here that you only print out non-sensitive data! Using %{private}# or %{public}# in an interpolated string is not portable to `Logger`!
os_log(message, log: customLog, type: type)
// Unfortunately this legacy API doesn't support non-StaticString logs. :(
}
}
Note that you may need to rework this code for more flexibility over private/public access levels - os_log and Logger don’t handle privacy levels in the same way. This is just to show how to use the API if you don’t add os_log privacy levels in message.
Apple recommend using OS Logging which is why I have used this approach rather than print statements. I added this answer because of the new Logger API in iOS 14 that also enables string interpolation.
Motivation
I think the answers here solve the question for < iOS 14, but they can be improved further for memory efficiency since this Debug Logging function will likely be used all across a codebase in iOS 14+ (new Logger API). Apple recommend using OS Logging which is why I have used this approach rather than print statements (although these will still work).
These are minor improvements but I think they can help because even minor improvements add up. In fact, the Swift Standard Library uses these optimizations everywhere they can)! These optimisations are contributing factors to the incredible memory efficiency of Swift despite being a high-level language (and part of great API Design!). (-:
Because this function would probably fit well as part of a generalized (OS) Logging service, I have also included considerations I make when logging within apps. I think these could help you when logging for debugging purposes (I answered this question because it was probably for debug logging!).
Improvements
I prefer to use UInt in certain situations if I know the Int is going to be positive, and any edge case crashes are unlikely. Note, I don't use UInt when interfacing with Foundation classes that use Int types for this reason. This allocates less memory at runtime and I find being more specific also helps me understand the code better.
I prefer to use StaticString where I know the string is known at compile-time. From the docs, StaticString only provides low-level access to String contents and is immutable. Thus only use it where appropriate. Even concatenated String literals cannot be used to initialize a StaticString. Because its functionality is more restricted than String this means that it is lightweight - only requiring an address pointer and length under the hood. Using StaticString also provides a small performance boost with OS-level memory management because it is neither allocated nor deallocated (no need for reference counting).
Using Apple's recommended Logger API for logging is better than print statements for multiple reasons: performance, privacy and unified management. It can be better for debugging issues in released products (OS Logs provide more context).
I would recommend using StaticString where you can, for example with the function and file names, and UInt for the line and column numbers. This is only now possible with the Logger iOS 14+ API.
(Bonus) Logging Considerations
Should I do LOTS of logging?
I think logging is a balancing act. Lots of logging can be very helpful to debug issues when viewing crash reports if you have access to these. However, you need to balance Privacy, Size of the Compiled Binary and Overwhelming the Logging System.
1. Privacy: Redact sensitive info using "\(message, privacy: .private)" and "\(message, privacy: .public)" with Logger, and DON'T print sensitive information when using NSLog or print statements. I would recommend replacing print statements (for production) with OS Logs when they are for debugging purposes. Or use a preprocessor directive (#if DEBUG) inside the logging service to print only on a Debug scheme..
2. Size of the Compiled Binary: Logging statements are essentially more lines of code. The more code you add, the bigger your binary. This is usually not an issue, as long as you don't log everything under the sun since only a large increase in this metric would affect the binary size.
3. Overwhelming the logging system: If you log excessively, the device may have to discard some logs in order to keep running (limited RAM or swap space at runtime due to OS multitasking - worse for older devices). Apple is usually reliable in handling lots of user logging, and it's hard to achieve this in practice. Nevertheless, if you do encounter this, some more useful log events could be pushed out of the window.
OS Logs
The most important thing to get right is the log level. By default on iOS log entries at .info and below will be suppressed at the point of log generation, so the only real negative with those is the binary size. If you log at .log (.default for os_log) or higher, you need to be careful about not logging too much. Apple's general advice is that you look at each of these higher-level log entries to make sure they contain info that might be useful while debugging.
Finally, make sure to set the subsystem and category. The unified logging system processes a lot of log entries - the subsystem with category makes it much easier for you to focus on specific problems.
How to choose the category and subsystem?
This is a pretty opinionated topic, so I will focus on what I would think about when deciding. YMMV: there may be better options and if so, please let me know.
1. By feature (product-specific): For example, if you are a shopping app, maybe organise the subsystem by the payment, login or other app flows. If you aren't already using a modular codebase for organisation into features (or frameworks for shared code) then I can recommend this tutorial series.
2. By technology: What I mean by this is the domain of the code, is it for Push Notifications, Deep Links, User Defaults (or persistence) logic. This could be helpful for the category parameter.
3. By target: I like to also use the bundleIdentifier of the current Bundle if I can for the subsystem. This makes even more sense if you have Extension Targets (Push Notifications), multiple Targets, or different Platforms (like WatchOS, SiriKit extensions and similar). You can get the current bundle, using this code:
let myBundle = Bundle(for: MyClass.self)
Debugging user issues using OS device logs
See here for a detailed walkthrough (Access Device Console Logs). The main idea is to connect the device to your Mac (or use the Mac itself for Mac apps ;)), open Console.app, run the app and try to reproduce the crash. If you manage to get that far in the first place, then you can correlate the time of the crash with the logs for more context.
Any other reasons for logging less?
If you are an Apple Early-Adopter then you know how buggy some of the iOS Betas can be ;). When posting bug reports to Apple, the OS Logs get included in sysdiagnose files, so you may get a faster turnaround time because your bug reports have less noise.
Should I use a third-party logging service?
Depends if you can afford it and whether you really need it. I prefer to minimise the number of third-party dependencies I import in my code (if I can control this) and the native (Apple) Logging APIs worked fine for most of my use cases. These services charge extra per month, but the advantage is the user cannot view the logs (even if he wants to) by hooking his device up to Console.app on his Mac. Note that this is NOT an issue if you apply the .private log levels, so I don't usually use third-party services (YMMV). A potential reason to go for web-logging is more security against reverse-engineering though, as long as you trust the third-party vendor against data breaches (BUT also it's not as eco-friendly ;)).
static func DLog(message: String, file: String = #file, function: String = #function, line: Int = #line, column: Int = #column) {
print("\(file) : \(function) : \(line) : \(column) - \(message)")
}
add where ever you want in your code (inside a struct/var/closure/func...) the next line:
let _ = print("**** \(#file)" + String(describing: type(of: self)) + ".\(#function)[\(#line)]")
and it will print the next line:
**** /path/to/my/file.swift MyClass.someFunc()[17]

Xcode 8 random command failed due to signal segmentation fault 11

I have a strange problem with the new Xcode 8 (no beta version) and swift3.
Once every other 3-4 times that I compile my code I get a 'command failed due to signal segmentation fault 11' error. I just need to enter new empty line, or sometimes changing some spaces, or add a comment (everywhere in the code) and the error disappears and I can compile again.
This is really strange because I'm not changing anything in the code! And sometimes I can compile and it works, then I don't change anything, I compile again and I get the error.
This is really annoying!
I have noticed this is happening since I have installed several 'Firebase' pods (Firebase, Firebase/Auth etc...). But I need them.
Anyone has any suggestion?
PS: I have set the Enable Bitcode of my project to No as many solution suggested, but nothing. In the error message it is not indicated any swift page where the error can be, an example is:
While loading members for 'Class_name' at
While deserializing 'func_name' (FuncDecl #42)
'func_name' is this one:
public class func loginUser(fir_user: FIRUser) {
let user = SFUser()
user.email = fir_user.email
user.isLogged = true
try! sfRealm.write() {
sfRealm.add(user, update:true)
}
var userToAdd = [String:AnyObject]()
userToAdd["email"] = fir_user.email! as NSString
let ref=FIRDatabase.database().reference()
let usersRef = ref.child(childName)
usersRef.setValue([key:value])
}
But then, as I said, I can just enter an empty row in another file and it compiles!
Thanks
I have the same issue i just figure out that i was using xcode 8.1 and the project's working copy was in xcode 8.2.1 so i just re install xcode 8.2.1 and problem got solved. Hope other can get the help trough this.
Ok, it seems that I have found the solution: it is a problem with Firebase and cocoapods, so 2 solutions:
Download Firebase and import into your project
I, instead, updated cocoapods to the last version and it worked. Upgraded Firebase - Now Getting Swift Compile Error
In my case there was some type checking issue deep down the compiler so the editor didn't give error in the gutter but on building the project I was getting signal setmentation fault 11 error:
1. While type-checking 'GetStoreAPIRequestModel' at /Users/.../StoreAPIModel.swift:9:1
2. While type-checking expression at [/Users/.../StoreAPIModel.swift:15:18 - line:15:31] RangeText="[Dictionary]()"
3. While resolving type [Dictionary] at [/Users/.../StoreAPIModel.swift:15:18 - line:15:29] RangeText="[Dictionary]"
So I changed my code from:
var stores = [Dictionary]() {
willSet {
allStores.removeAll()
for model in newValue {
allStores.append(StoreAPIModel(dictionary: model as! Dictionary).getModel())
}
}
}
To (more descriptive dictionary):
var stores = [[String : Any]]() {
willSet {
allStores.removeAll()
for model in newValue {
allStores.append(StoreAPIModel(dictionary: model as [String : AnyObject]).getModel())
}
}
}
This is tricky problem. Issue can be with line of code or syntax. I was getting similar error and it was due to incorrect usage of dictionary. I was trying to increment the value of dictionary element.
Solution is to triage the code, detailed error provide which module has issue, so try commenting part of code until you find the line which is causing the issue.
Hi i had the same issue with FireBase , my problem was that i was extending FIRStorageReference and FIRDatabaseReference and some time it compile successfully some time i get
command failed due to signal segmentation fault 11
so i removed that files and implement the method other way , now everything works fine.
Found my problem when this occurred. (No cocoapods.) I thought I had left the program in a working state, but I was wrong. I am writing a straightforward command-line program. What it does is somewhat general, so I defined all the strings that make it specific in let statements at the top of the program so that I could someday use the program in a different context.
Since that was working so well, I thought I'd be clever and do the same with a filter of an array of dictionaries. I turned:
list.filter { $0["SearchStrings"] == nil }
into:
let test = { $0["SearchStrings"] == nil }
// ...
list.filter(test)
meaning to continue working on the let, but I never went back and did that. Building gave me the segmentation fault error. Defining test as a function fixed the problem.
(Incidentally, I understand how to strip a filtering function down to the terse braces notation in the context of the call to Array.filter, and why that works, but I don't understand why I can't assign the brace expression to a constant and use it as such.)

po Swift String "unresolved identifier"

I am having trouble debugging Swift Strings
func stringTest() {
let test1:String = "test1";
let test2:NSString = "test2";
// <-- Breakpoint here
println(test1);
println(test2);
}
If I set a breakpoint after these lines and try and print test1 I get the following error:
po test1
error: <REPL>:1:1: error: use of unresolved identifier 'test1'
test1
^
But I am able to print test2 successfully:
po test2
test2
It is a bug of Beta. Xcode6-Beta5 has still this bug.
You can only get debug info for swift's variables, but can't get it for swift's constants.
Temporarily you can change let test1 to var test1 and you will got debug info.
Hope this will be fixed in release version. Good Luck in debugging ;)
EDIT:
Unfortunately, the same issue is still happening in first release of Xcode Version 6.0.1 (6A317)
let test1:String -> debug info is unavailable
var test1:String -> debug info is available
EDIT2:
Yes, confirmed. It is fixed also for iOS apps in the latest Xcode 6.1 under OS X Yosemite.
This is most likely a bug in the debug information output. You can check this by grabbing the PC, for instance from register read pc, and then doing:
(lldb) image lookup -va <PC VALUE>
That will print a bunch of stuff, but the last entries will be all the variables currently visible to the debugger, and where they live (in registers or memory.) If you don't see the variable there, then the debug information must have told lldb that the variable is not currently live.
If you can reproduce this in some example code you can make available, please file a bug with bug reporter.apple.com.