How to debug iOS 8 extensions with NSLog? - ios

- (void)viewDidLoad
{
NSLog(#"%s", __func__);
// ...
}
in viewDidLoad of an iOS 8 extension. the NSLog outputs nothing in Xcode. NSLog works as usual in the container app though.
How can I get output from debug messages from an extension?

Debugging works for app extensions.
It works on simulator too.
If your app ext crashes in the simulator, you may find it is not easy to restart your app ext. Restarting your simulator is a quick solution.
Steps to debug an app extension:
Run the container app. In this step, Xcode uploads the container app and app extension to the device or simulator.
Stop the container app. This step is important when you debug in simulator. If you don't do it, Xcode will tell you the simulator is in use.
In Xcode, press menu Debug -> Attach to Process -> By Process Identifer (PID) or Name..., input the app ext's identifier, e.g. com.abc.ContainerApp.MyExtension, to start debugging. Don't forget to set break points. (Update on Aug 25, 2014: you can input MyExtension(your extension's name) directly.)
In the device or simulator, open your app extension.
Updates on Aug 23, 2014:
I found the debugging steps above do not work well on Xcode 6 beta 6 with iOS 8 SDK beta 5 on the simulator.
Solution:
Run your extension in the simulator.
Xcode menu Debug -> Attach to Process -> Choose "MyExtension(your extension's name)" in System section in the menu.
The breakpoints work. But I don't know why logs do not show in the output window.

I'm having this problem too. It works for me if you go in your Simulator under the menu Debug -> Open System Log...
From here you can see all the logs of the iPhone Simulator (included your extension's logs).

NSLog is working perfectly.
You just don't see what is being logged in the debug area of Xcode because the Xcode debugger isn't attached to your extension. Extensions are nearly completely independent from their containing app. They have separate bundle identifiers, for example, and they also are separate processes on the OS.
I have had varied success in getting Xcode to attach to extensions. Supposedly it seems it would attach automatically, and it appears in the debug navigator as "Waiting to attach", but never attaches.
Sometimes, I am able to run my extension target in Xcode:
And then have the option to choose what application to run my extension in. In this case, I would choose its recommendation of "today", which is notification center.
And then it would sometimes attach the debugger to my extension. Note this method only works on physical devices, it seems.
If it doesn't attach you can use the manual attachment method in #VinceYaun's answer,
I have also had varied success using other methods of attachment. Most have been unsuccessful, and it seems they are just bugs that will be fixed at a later date.
To view your log messages you go to Window -> Devices in the top bar and select your device. You can bring up the device log from the bottom of that window. If you are testing on a simulator, you can use #BalestraPatrick's answer.
Some of the bugs have been fixed in Beta 2, and my guess is that eventually the debugger will attach automagically when launching the extension.
Update: In the iOS 8 Beta 4 release notes:
Extensions
Fixed in beta 4
Extensions sometimes fail to launch when debugging from Xcode.
When Extension with UI is killed, it relaunches and is not dismissed.
Sometimes your Sharing or Action extension can hang.
Redeploying an extension may disable it in Notification Center.

I'm having this problem too. Xcode never attaches my debugger to the extension or displays NSLog messages. If you attach your Xcode debugger manually to your extension process, at least breakpoints work like a charm:
Debug->Attach to process->Your extension name (mine was "com.example.MyExtensionApp.MyExtension")

Create scheme for your extension
Run scheme
In a dialog choose container app
Enjoy
It works for me :)

Xcode 8 is able to debug extensions:
Choose the extension scheme in the combo next to the stop button and run it.
Select the parent application in the dialog that appears.
Result: breakpoints and log work as usual.

What finally allowed me to see the log in the debugging area, based on Michael's suggestion and Apple's documentation, is:
Build & Run the app extension in the simulator and, when prompted for a host app, choose the specific app that you're going to call the extension from. In my case I was launching my Action extension from Safari by pulling up a share sheet on a PDF.
What wasn't working before was following other people's suggestions of using Today as the host but then leaving that app and going over to Safari to call my extension. I no longer even need to run my containing app first before running the extension.
From Apple's Documentation:
In your extension scheme’s Run phase, you specify a host app as the executable. Upon accessing the extension through that specified host’s UI, the Xcode debugger attaches to the extension.

I actually got the logs to run quite simply in Xcode 6.3. Firstly, build and run the containing app. Once the containing app is running on the device, build and run the app extension by changing the scheme to the app extension.
Apple has documentation directly related to debugging, profiling and testing your app extension.

A trick which works for me (although it is quite an ugly one) is to place a dummy UILabel somewhere in the bottom corner of my extension. I usually call it logLabel. It is then possible to update the text of this label with any log statement that you want to get logged. Such approach is not very good if you need to log statements from instances of different classes. And, obviously, it clutters your UI.
However, if you have a fairly simple widget and you don't mind about slight cluttering of the UI this does the trick. I have tried all other solutions outlined in this discussion and, sadly, none of them worked for me.

The only way debugging works for me is by selecting Debug->Attach To Process By PID or Name
Then enter the PID not the extension name.
You can find the PID by running the extension on a device, go to Window->Devices. Find your device and viewing the console. When you see the name of your extension, its followed by 5 digit number. That is the PID
I also put a bunch of NSLog's in the extension in order to find the PID as well.
This is on xCode 7

Encounter the same problem about extension for NSLog, and break points. I have fought it with many days.
Device log can be found as following image. It is at XCode -> Window -> Devices and Simulators.
After enter the Open Console, there is a search field at the top-right of dialog. I can apply filter rule in there. For example, a process name contains Notification key word, or process name must equal to the name of extension target, ex: equal to MyNotificationServiceExtension process name.

Clearly something is broken in Xcode6-B5.
If I try to run a Photo extension on the Simulator I cannot see any Photos.app as an option for the extension attaching process.
The same, running on a real device, give me the correct behaviour.
In the first case any breakpoint is not honorated. In the latter case, breakpoints work like a charm.

You should know that the container app and extension are totally two difference process in iOS while the LLVM debugs only a thread a time, so when you are debugging, the console never log the extension and never stop at breakpoint.
You can solve most of the problems by #Vince Yuan's method.
However, my problem is that Xcode debugger hardly hook on my keyboard extension on both iOS Simulator and devices, like 1 time in 7-8 runs, It's totally a matter of probability. #Vince Yuan's method also work for just sometimes.
My little experience is that when you run you debug scheme, if the debug Session in the left panel showing that 'No Debug Session', there is no need to open your extension and test it, the debugger didn't hook on, just run again for lucky.
but when you see com.xxx.xxx.xxx is waiting to Attach, the extension can definitely get debugged.
This is a little trick for whom cannot debug iOS extension, especially keyboard extension.

As of Xcode 6 Beta 5, I've been able to use an actual device running iOS8 to debug my extension. Try running it on a device and select Safari to launch into

To overcome all the states caused by ever changing IDE, I'm using iOS Console by lemonjar.com – it displays a console window for any connected iOS device rendering syslog messages regardless the process ID. You can see both app and extension debug log messages at once here.

I could debug my extension with the way I describe below:
Xcode : Debug -> Attach to process by PID or Name. Your extension scheme name.
Then select your main app target and run.
I hope it also works for you guys.

Related

how to see NSLog in my SDK project under iOS 10

I have a SDK project which will compile and build a framework. Inside this project, I have my person NSLog shown there. I have another framework test app to using this framework to do my task. After upgrading to iOS 10 and Xcode 8, I notice all the NSLog are gone. I cannot find it anywhere.
I search and find this answer: iOS 10 doesn't print NSLogs, I gave a try for both my SDK project and my framework test app, adding OS_ACTIVITY_MODE "disabled", however, it is still not showing NSLog.
Update: I still have one device which is iOS 9, I gave a try on that one, NSLogs are still shown in device console. Using Mac's console app I can also see my own logs.
This is a MFI project so I cannot directly debug this project, because the lighting cable is always connected with my hardware. I can only use log to see what happened.
OS_ACTIVITY_MODE set as disable remove OS activity state which is printed during the when project is runs. OS_ACTIVITY_MODE is only printed only in the x-Code 8.0 but when you upgrade your x-codefrom 8.0 to 8.1 you can found that it does not print any console for OS. But in overall procedure I have found that NSLog is working properly.
For your confirmation i just update my old project and run it into x-code 8.1. Output as below images
Environment variable
Nslog Code
console print
Suggestion
I have checked your problem in multiple style with multiple project but I didn't found any problem. So I just suggest you
To update your x-code
or
Re-install x-code after removing previous x-code completely.
Because If it is x-code bug them i also have to face the same in my every experiment.
If you still have any query you can ask.
Apple did some changes the way NSLog works and I probably you might not be able to get them.
My recommendation is that you change your NSLog to something that prints to the output console without using NSLog.
I'm the co-founder of a product called Bugfender that might help you, what we do is that we provide a BFLog function that will print the logs to the console and also upload them to our servers, so you can always check the logs without any need to connect the device to your computer.
The only problem our product has is that it's not in real time, but usually there's a delay of a few seconds. Some of our customers are using it to debug the app instead of using the XCode console.
If you set this,you can not see any log in your device ,but you can see that in simulator.

Testing a closed ios app

I'm currently trying to handle different application states (closed, background or in a different tab of the app) however when I try to test how the app works when it is closed and receives a push notification(double click home and force close the app then reopen it) I'm not sure where I'm going wrong in the code. Since I'm reopening the app from the phone itself and not xcode I can't test to see which method isn't being reached because no output is available in the console. Is there any way to test a situation like this or simulate a force close event in xcode so that when i re run the app on the phone it also launches in xcode?
I appreciate any responses.
Cheers!
If you force close app or stop (from xcode) then it close the connection with xcode. Then if you open it from phone then it will not make connection with xcode. You must run it from xcode. And there is no difference in opening app from phone or running from xcode. App's flow will be same in both case. So what you want to test that which methods get calls and in which sequence that you can check by rerunning the project.
Update:
Select the Scheme on the toolbar (just left beside from your device or simulator list)
Choose Edit Scheme
Select Run in the left panel
For the Launch option, select Wait for executable to be launched
Refer this link for more details
Since I'm reopening the app from the phone itself and not xcode I can't test to see which method isn't being reached because no output is available in the console.
In Xcode, hold down the Option key and choose Product->Run..., and then edit the Run scheme to use the "Wait for executable to be launched" option. You should then be able to choose Run in Xcode, and then open your app by some other means, such as responding to a notification, and Xcode will still connect and let you debug.
To debug the process after restarting the app again, attach the Xcode debug console to the running process.
In Xcode do:
Debug > Attach to process > [select your process]

Can't debug iOS 8 App Extension

I'm trying to debug the sample Action App Extension provided on Xcode 6 (6A313).
Even though the app runs flawlessly, I can't see any NSLog messages on the Debug Area neither Xcode will stop on my break points.
Things I've tried:
I've tried uninstalling Xcode 6, re-downloading it from the Mac Store and installing again with no success.
I've also tried to go through Debug -> Attach to Process -> By Process Identifier (PID) or Name... but the Status Bar shows "Waiting for -bundle id- to launch" when it is already running.
Tried different devices.
Tried running on the simulator, but my App Extension won't show on the App Extensions list (it is not present in the "more" list also).
I've checked this answer also, which didn't help me.
I've ran out of ideas on what to do :)
When you added the Application Extension target Xcode should have added also a new Scheme for the Extension (or you can create one in 'Manage Schemes...').
If this happened you just have to change the Active Scheme, on the very left of the drop down with which you choose the device/os of the simulator, and run.
If you change the Active Scheme to the Widget one, then breakpoint and NSLog works, at least for me.

Xcode-Instruments cannot run app on simulator with the app target I choose

I am trying to run an automation on an iOS App using UIAutomation with Instruments.
It had worked well when I had tried it out a few weeks back. However, I tried out another automation testing framework (KIF from Square) in the meantime, and now when I try and run Automation with Instruments, it refuses to work.
When it had worked, I had carried out the following steps:
Open my app in Xcode
Run the app
Quit the iOS simulator
Open Instruments (not necessarily through Xcode, but just by searching for Instruments in Spotlight), choose Automation
Instruments opens, and when I click on Choose target, I do not need to browse for the target. I can see the name of my app in the list (description: the app name is without the .app extension and has an icon before the name like the icon which appears at the top of the output window in Xcode - a black and white icon with a gradient) even though I haven’t opened it before i.e even when I had opened Instruments for the first time.
I choose this target from the list, choose a javascript file for the automation to run, and then click ‘Record’. The automation used to run and I could see it run in the simulator which used to open up.
However, opening Instruments no longer shows me the target in the list of targets anymore.
I have tried choosing a target from my filesystem (from the Derived Data folder) as well as from the iPhone Simulator applications folder; but no luck. The target does not appear as it used to before (in the description above), but appears with a .app extension and with the typical application icon. The automation does start and open up the simulator, but gives the following message: (although the page or the script haven't changed at all)
Cannot perform action on invalid element: UIAElementNil from target.frontMostApp().mainWindow().elements()[2]
(Would have liked to post images, but can't, since I am a new user and do not have the required permissions yet - hope the description makes up for it)
Have been stuck on this issue for long and any help would be appreciated! Thanks so much!
I just profiled the app using Product -> Profile in Xcode, and that opened up Instruments with the target. The target was the Unix executable under Derived Data -> MyApp -> Build Products -> Release-iphonesimulator -> MyApp.app -> MyApp unix executable.
Also, while using KIF, I had enabled accessibility labels for some views in the storyboard. While running the automation tests in Instruments, the app seemed to somehow consider the views which had the accessibility labels set as one single element and could not access sub-elements on this view. In order to run with Instruments, I just disabled the accessibility labels for the views and it worked like a charm again!

How to attach debugger to iOS app after launch?

I have an issue I am troubleshooting which occurs very infrequently and doesn't seem to happen when I have things running under Xcode.
Is it possible to run an app normally (i.e. from Springboard) until my issue occurs, and then attach a debugger at that point?
I would prefer to do this without jailbreaking if possible.
Attach your device connected your Mac
Debug > Attach to Process by PID or Name
In the dialog sheet, enter the name of your App as it appears in the Debug navigator when started via Xcode (e.g. Target's name not bundle-id).
If the app is already running, the debugger will attach to the running process. If it isn't running, it will wait for the app to launch and then attach.
I'll leave this here since neither of the other 2 answers gave me quite enough detail without a little bit of a struggle.
Run your app in the simulator and take note of the name in the Debug navigator
Plug in your device and don't forget to select your device as the target
Debug > Attach to Process > By Process Identifier (PID) or Name
Enter the name from step 1 and attach. That should be all you have to do.
In Xcode 5.0.1 and 6 it's the menu bar items:
Debug > Attach to Process > By Process Identifier (PID) or Name...
In Xcode 7 it's just:
Debug > Attach to Process by PID or Name...
I was able to debug the app by adding a breakpoint on the AppCoordinator file init() method on the super.init() line.
I was able to turn off the wifi/internet and then by pass the developer verification.

Resources