iOS9 storyboard what is unhandled action (handleNonLaunchSpecificActions)? - error-handling

I've noticed the following error popping up in the console when running my app on iOS 9 when using a storyboard. I'm using xCode7. Is this something I need to be concerned about?
-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:] ** unhandled action -> <FBSSceneSnapshotAction: 0x176bfb20> {
handler = remote;
info = <BSSettings: 0x176a5d90> {
(1) = 5;
};
}

There is nothing wrong with your code. This is a logging message internal to Apple, and you should file a radar about it.
There are two hints that show that this is probably Apple's code:
The underscore leading the method name _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion is a convention indicating that the method is private/internal to the class that it's declared in. (See this comment.)
It's reasonable to guess that the two letter prefix in FBSSceneSnapshotAction is shorthand for FrontBoard, which according to Rene Ritchie in "iOS 9 wish-list: Guest Mode" is part of the whole family of software related to launching apps:
With iOS 8, Apple refactored its system manager, SpringBoard, into several smaller, more focused components. In addition to BackBoard, which was already spun off to handle background tasks, they added Frontboard for foreground tasks. They also added PreBoard to handle the Lock screen under secure, encrypted conditions. [...]
I have no idea what the BS prefix in BSSettings is for, but
BS is shorthand for BackBoard Settings, and an analysis of this log message would indicate that it's not anything you did, and you should file a radar with steps to reproduce the logging message.
If you want to try and grab a stack trace, you can implement the category linked to here. Some would argue that overriding private API is a bad idea, but in this case a temporary injection to grab a stack trace can't be too harmful.
EDIT:
But, we still want to know what this action is. So I put a breakpoint on -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion] and started printing out register values and found a class called FBSceneImpl which had a whole bunch of information about my application:
We are able to find out which private method is called next (stored in the program counter, instruction pointer, register 15.)
I tried finding the un-handled FBSceneSnapshotAction referenced in the log, but no dice. Then, I subclassed UIApplication, and overrode _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion. Now I was able to get at the action directly, but still, we don't know what it is.
Then, I looked at the FBSceneSnapshotAction again. Turns out it has a superclass called BSAction.
Then I wrote a tool similar to RuntimeBrowser and looked up all of the subclasses of BSAction. It turns out that there's quite a list of them:
The two method names we have (one from the log and one from the program counter on the devices) indicate that these actions are used under the hood for passing actions around the system.
Some actions are probably sent up to the app delegate's callbacks, while others are handled internally.
What's happening here is that there is an action that wasn't handled correctly and the system is noting it. We weren't supposed to see it, apparently.

AFAIK, the info above is related to iOS during snapshot the screen (i suppose for double click home multitask related behaviour).I deeply investigated my application and seems that it does not get any side behaviours. You can safely ignore it, for now.
You can use the following gist simple category to test yourself against the calls to the above function:

I have figured it out, it will happen when you have IBAction method declared in .h or .m file but you have not bind it to any control.
.m example:
- (IBAction)click:(id)sender{
}
but not assigned this method to any control in storyboard.

haven't find out why it happens in my app, but at least you can catch the exception, if you want to keep this from popping up in your log pane. It's not a solution, but it might give you more insight why it is happing by inspecting any of the arguments that are passed in the catch.
swift 2 version:
import UIKit
extension UIApplication {
func _handleNonLaunchSpecificActions(arg1: AnyObject, forScene arg2: AnyObject, withTransitionContext arg3: AnyObject, completion completionHandler: () -> Void) {
//whatever you want to do in this catch
print("handleNonLaunchSpecificActions catched")
}
}

Related

Cannot inspect Self in method while debugging

I have a method on one of my ViewController's that is called by one of its view's and delivered some value. It then sends out a message to a manager object with some information about the VC's state.
- (void)elementXChangedWithValue:(float)value {
ParameterManager * pMan = [ParameterManager sharedInstance];
[pMan updateParameter:self.elementX.parameter value:value];
}
In debugging, it was important for me to inspect what the .SomeElement.parameter state was so I could know what was getting lost in translation by the time I get to my ParameterManager.
Unfortunately, although Self is definitely non-nil and accessible the debugger shows scant information about the class making quick and practical glancing of the value difficult. (i will sometimes invoke "po" command in the debugger command line, however).
Not sure if it helps but this project is running heavy with the Objective-C/Swift interoperability although the ViewController is a fully Objective-C class.
Here is an image of what I am getting in the debugger. The drop-down arrow shows nothing but empty.
The debugger isn't perfect and sometimes you just cant see what is in certain areas, such as self. What does always work is NSLog's placed in code though, so if all else fails, add one of those in at the right place to print out the object you wish to know about.
The debugger may show more info after you make it execute these commands:
expr #import UIKit;
expr #import Foundation;
This loads the whole UIKit and Foundation symbols in the debugger at runtime, you only need to execute it once per debug session.
You can automate this with a user-defined breakpoint that'll be triggered every time your application starts in the debugger.
Source : http://furbo.org/2015/05/11/an-import-ant-change-in-xcode/

Xcode: "Spurious Update" console warning?

I'm writing a pretty straightforward ObjC app. (The only minor complexity is that it uses an external library called Chilkat for some basic networking, but I don't think that that's relevant.)
Occasionally, my project spontaneously pops up this warning message:
May 14 01:24:01 Neovenator-2.local Project[22645] : void
CGSUpdateManager::log() const: conn 0x4b29b: spurious update.
And I have no idea how to handle or even interpret it. There's nothing in my project called CGSUpdateManager, and my project doesn't call a log() function anywhere. I can't even reliably reproduce it, but it's popped up often enough to raise my interest level.
Searches at both Google and here for the term "spurious update" reveals a lightly scattered set of conversation, but nothing relevant to my project. Meanwhile, a Google search for "CGSUpdateManager" reveals it's something to do with Swift, which I'm not using at all.
Can anyone help me understand what this means? Or should I just disregard it?
Make sure to call super in viewDidLoad, viewWillAppear and viewWillDisappear.
Sorry, my code with correct Highlight/indentation:
- (void)setNeedsDisplay
{
//#if 1 //TEST (suppose we are only called by us)
if(wvImageRep_DoRebuild)
//#endif
[super setNeedsDisplay]; // "spurious update" ?
}
It's an example (#see my full response), it helped me

EXC_BAD_ACCESS on animationForKey:

I'm trying to use a recent feature of the Scintilla component, which provides OSX-like text-highlighting effect (the yellow animated bouncing box), and I'm stuck with an error that pops up intermittently :
EXC_BAD_ACCESS
pointing to this particular line :
if (layerFindIndicator!=nil)
if ([layerFindIndicator animationForKey:#"animateFound"])
[layerFindIndicator removeAnimationForKey:#"animateFound"];
(the ifs are mine; just in case I caught the object layerFindIndicator being nil, or deallocated or whatever... Unfortunately, it doesn't help...)
layerFindIndicator is seemingly a subclass of CAGradientLayer. (You may see the full code for layerFindIndicator, here).
Since, I'm an absolute newbie to Quartz Core, could please give me any hint as to HOW this could be debugged?
Since, I'm an absolute newbie to Quartz Core, could please give me any hint as to HOW this could be debugged?
This doesn't have anything to do with QuartzCore specifically (at least, I hope not)—it's general this-object-has-been-killed-before-its-time-how-do-I-find-the-killer stuff.
In Xcode:
Edit your current scheme.
For the Profile action, set it to use the Debug build configuration.
Dismiss that and then hit the Profile command.
Xcode will build for that action and then launch Instruments.
Instruments will prompt you to choose a template; you want the Zombies template. Once you've chosen it, Instruments will create a trace document and run your application. Switch to your application (if it isn't already frontmost), then do whatever causes the crash.
If the crash really is a dead-object crash, Zombies will reveal it. You'll get a flag in Instruments's timeline saying something like “message sent to zombie object 0xd3c2b1a0”, and your program will probably exit shortly thereafter.
In that flag is a tiny little button that looks like this: ➲ except it'll be gray. Click on it.
That takes you to the history of that object (actually of that address, including any previous objects or other allocations that have started at that address). Show your Extended Detail Pane (the one that appears on the right showing a stack trace), then scroll down to the end and then move backward (upward) step by step through time, looking at releases and autoreleases, looking for the one that isn't balancing out the object's allocation or a retain.
The solution will probably involve one or more of:
Changing a property to be strong or weak rather than assign/unsafe_unretained
Adding a property where you previously did not strongly own an object
Rearchitecting some things, if it's not clear which of the above you need to do or if either one of them seems like a filthy hack
Switching to ARC to get weak properties and __weak instance variables (both of which get set to nil automatically when the referenced object dies) and to get local variables being implicitly initialized to nil
But it'll depend on what you find in Instruments. And, of course, there's the chance that your problem—the bad access—isn't a dead object at all and all of the above will not help you.
Try this:
if (layerFindIndicator!=nil){
if ([layerFindIndicator animationForKey:#"animateFound"]){
[layerFindIndicator removeAnimationForKey:#"animateFound"];
}
}
Also check to see if it is released else were.
EDIT:
Another thing I found was you didn't have an white space in the if. Your code should now look like this:
if (layerFindIndicator != nil){
if ([layerFindIndicator animationForKey:#"animateFound"]){
[layerFindIndicator removeAnimationForKey:#"animateFound"];
}
}

Core data/NSPersistentDocument marking file "clean" every time any field finishes editing

I'm working with a document-based core-data OS X application. The problem I'm having is that whenever I edit any field on the document, after I press tab or click to something else (i.e. I finish editing/change focus), the document is marked as clean and undo is reset. When I try to save the file, however, the resulting document opens without the data I entered. What might be the problem, or, any pointers on where to look to fix this? Here's some stuff I know and things I've already tried:
I know it's not somehow saving because it never stops at the breakpoint in my overridden writeSafelyToURL:(NSURL *)inAbsoluteURL ofType:(NSString *)inTypeName forSaveOperation:(NSSaveOperationType)inSaveOperation error:(NSError **)outError and it also never sends an NSManagedObjectContextDidSaveNotification.
The documents are packaged in an NSFileWrapper directory with the core data store inside (and also some other files). I access the entities through an NSObjectController and a couple NSArrayControllers. It happens with both core data properties and manually registered changes in the rest of the file wrapper.
Update: At the suggestion of Martin, I tried NSUndoManager's notifications, and all I can seem to glean from it is that more than one undo manager is in play. If I add an observer for NSUndoManager, it won't post if I specify an object, and then if I don't, the notification object is not equal to [self undoManager]. I added updateChangeCount to my category on NSPersistentDocument, and it never gets called. setDocumentEdited basically confirmed that something about losing first responder is passing NO into that method. What could be causing this, and how can I fix it?
You could break on the method setDocumentEdited: of NSWindow to see which operation updates the change status.
In addition updateChangeCount: of NSDocument might be a place to take a look at.
NSUndoManager also posts several Notifications which can give additional hints what to look at.
The answer is actually pretty silly considering how long this stumped me. I was working on some objects on load, and I accidentally set [[self undoManager] disableUndoRegistration] at both the points where I should disable and enable. It was a little more than that, though. A related element in Interface Builder needed to be checked Prepares Content. When I had done both those things, the problem vanished.

Objective-c -> class method to main file query

Sorry to bug twice so quickly, but since people were so kind in their informative responces, I figured it couldnt hurt to ask another question.
The same program i tried to make it rather swanky and have a main screen which allows you to click on a button which leads to a limited options screen. This lets you switch the music on or off. Or at least it should do.
The music running code is in the main file (game.m), under the following:
//Music
[Settings setMusicEnabled:YES];
music = [SPSound soundWithContentsOfFile:#"music.caf"];
channel = [[music createChannel] retain];
channel.loop = YES;
channel.volume = 0.25;
if([Settings musicEnabled]){
[channel play];
}
I apologize for the strange format, but it is Sparrow framework. basically, the Settings file contains the class methods I am trying to use. If the methods cause YES, the music is on. If it is No, then the music is off.
settings.m
static BOOL isMusicEnabled;
#implementation Settings
+ (BOOL)musicEnabled
{
return isMusicEnabled;
}
+ (void)setMusicEnabled:(BOOL)value
{
isMusicEnabled = value;
NSLog(#"SME? %i", isMusicEnabled);
}
#end
Now, the options file is working and i tested that section. The program is reading that isMusicEnabled is getting a new value, thus musicEnabled is being altered as well, so there should be a change and the music should be switched off.
However, nothing happens. I have tried to use debugger, but I am not very good at it and I dont understand a lot of the information i am given. I do understand that the problem is sending the message from Settings file to the main/Game file.
I would appriciate anyone's help who could enlighten me as to how this could be solved.
I'm not familiar with Sparrow Framework, but let me make a guess anyway.
[channel play]; starts playing the music in background until the channel is asked to stop playing.
Changing the isMusicEnabled does not trigger any code to stop the currently playing music. When you change the value in Settings, you should inform the channel to stop (most probably by somehow accessing the channel and calling [channel stop].
There's another problem - isMusicEnabled is just a variable in memory, your program will not remember its state between restarts. And Settings are usually supposed to be remembered.
To summarize I see two problems: persisting settings between restarts first and informing about change of settings second. To remember settings I suggest you look into NSUserDefaults class. To inform the channel to stop playing you have couple of options - depending on you skills. Easiest is to simply access the channel variable from within the setMusicEnabled and call stop. Another option would be to use notifications, but for a beginner programmer that is more complicated (look for NSNotificationCenter if interested).