I'm trying to build an application that uses QTKit, with some compress options. I saw this example in the apple developer page QTCompressionOptionsWindow that uses a Window for that purpose.
in MyController.m line 65 there is a comment:
// ******** Compression Options Window *****
// create our window with the media type and set ourselves as the delegate
// you could also instantiate the window directly in the nib and hook up the delegate
// simply call showWindow or setMediaType if you want to change the list of compression options shown
mCompressionOptionsWindow = [[QTCompressionOptionsWindow alloc] initWithMediaType:[[[mCaptureMovieFileOutput connections] lastObject] mediaType]];
if (nil == mCompressionOptionsWindow) {
NSLog(#"Compression Options Window did not load!\n");
return;
}
[mCompressionOptionsWindow setDelegate:self];
Can someone explain me what it's the author trying to explain
"you could instantiate the window
directly in the nib"
?. He does have a nib with the QTCompressionOptionsWindow
Thanks for your replies
The purpose of the MyController-class in this sample is to simply illustrate how to use the QTCompressionOptionsWindow-class -- especially, how to set up the delegate-relationship.
In the MyController sample, the author chose to set this relationship up in the code snippet you posted.
The comment simply states that, if you don't want to do that programmatically, you could instead use IB for this purpose: simply create an instance (== instantiate) of the QTCompressionOptionsWindow-class in the NIB where you put your own controller and connect its "delegate" outlet to your controller.
If that sounds all jibberish to you, have a look at the sections "Controller Objects" and "Creating and Managing Outlet and Action Connections" of the "Interface Builder User Guide". Although I find them a little sparsely illustrated (given the target audience), they are quite good.
A technical note was written back in 2008 that discusses how to manage QTCompressionOptions in QTKit Capture and talks about the QTCompressionOptionsWindow sample in depth.
Technical Note 2219
"Managing QTCompressionOptions - An overview of the QTCompressionOptionsWindow sample"
http://developer.apple.com/library/mac/#technotes/tn2008/tn2219.html
Related
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")
}
}
I am learning Objective-C Cocoa programming for OS X, and object-based programming in general, so I am a big novice here, so my question is a bit general and my guess is the answer to this is simply "experience"; however, I am curious if there is some route of knowledge to understanding what methods in various classes are best or perhaps required for getting tasks done.
For example, in a programming guide I am instructed to create a document-based program, and the document class contains an array to store data, with the following method bound to a button to create a new entry in the array:
- (IBAction)insertItem:(id)sender {
if (!theItems) {
theItems = [NSMutableArray array];
}
[theItems addObject:#"Double-click to edit."];
[theTableView reloadData];
[self updateChangeCount:NSChangeDone];
}
The array is "theItems" and its data is being presented in a TableView object. I understand that the steps here add a new string to the array and then refresh the table to display it, followed by setting the document to be set to an unsaved state.
What I am not getting is how one would know these specific steps and methods are required. Intuitively it seems one would just add items to the array, and that would be all that's required to have the new values simply show up in the table view for which the array is the data source, so how would one know that the tableView would need to be refreshed with the "reloadData" call? I can see someone (myself) figuring it out by trial and error, but is there some quick resource or guide (ie, some quick flow-chart) either in XCode or elsewhere that indicates for a table view that this would have to be a required action to display the new entry?
If I look at Apple's NSTableView class reference, it claims in the overview that you "modify the values in the data source and allow the changes to be reflected in the table view" which suggest the view is updated automatically, so the requirement to call "reloadData" on the view seems a little obscure.
Look for the guides. In the online class reference for NSTableView, there's a section at the top called "Companion Guides". For NSTableView, it lists the Table View Programming Guide for Mac. (In the prerelease 10.10 docs, the guides are listed under Related Documentation in the left-hand sidebar.)
I could have sworn this same information was available in Xcode's Documentation window, albeit somewhat hidden behind a "More related items" pseudo-link, but when I check right now there's no link to the guide anywhere in the NSTableView class reference. Which is a terrible oversight.
You can also browse or search the Guides section of the developer library.
Familiarity, studying the documentation and possibly reading some good books is the answer. For example, in the docs you quoted (emphasis mine)
you should modify the values in the data source and allow the changes to be reflected in the table view
You should do both these things. If you want it to happen "automatically", look into bindings, which uses several other Cocoa features you won't understand at this point either to do the table data source stuff for you. I'd recommend understanding what is happening manually before handing over control to bindings, so you have some chance of understanding when things go wrong.
As well as looking at the table view documentation, you also need to study the cell, delegate and datasource references. All of those objects work together to give you the functioning table view.
Is it possible to get the keyboard state in Objective-C without referring to NSEvent?
In general I can't use NSResponder methods like -[NSResponder flagsChanged:] but I need to know if the Command key is currently pressed.
I'm still wondering why you can't use NSEvent, but I'm going to answer the question anyways. Perhaps you're building a "command-line tool" and are only linked against Foundation? You're going to have to include at least one more framework. If you want to link against AppKit, you can (as I mentioned in the comments) use +[NSEvent modifierFlags]; this is a class method on NSEvent, so you can use it anywhere, without needing to have access to an individual event, to get the current state of the modifier keys as a bitmask. The docs explain the meaning of the bitmask.
if( NSCommandKeyMask & [NSEvent modifierFlags] ){
NSLog(#"Oh, yeah!");
}
You can also get this info using Quartz Event Services. In this case you have to include the ApplicationServices framework*. The CGEventSource functions will give you the same bitmask you get from NSEvent:
CGEventFlags theFlags;
theFlags = CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState);
if( kCGEventFlagMaskCommand & theFlags ){
NSLog(#"Uh huh!");
}
*This is already included if you are, in fact, writing a Cocoa app -- it's part of Quartz.
Use this code when targeting macOS 10.12 or newer:
if (NSEventModifierFlagCommand & NSEvent.modifierFlags) {
// Do whatever is needed
}
I would just like to know how to create ("instance") a new NSWindow in a Mac OSX application via it's Objective-C code.
Have you taken a look at the "Creating Windows" section of the NSWindow class reference - it tells you pretty much all you need to know about creating windows programmatically.
Additionally, there's quite a bit of sample code (see the "Related sample code" section at the top of the above link) if you're after examples.
In .NET I just do something like DataForm.Source = Object and then magic happens. Platform routes data changes from ui fileds to object properties, does validation and so on. Can I do something similar with Cocoa Touch and CoreData objects?
The closest thing in Cocoa is 'Key-Value Observing'. In the desktop Cocoa framework you can use bindings to hook user interface elements up to underlying objects so that changes in the objects or UI elements are reflected in the other.
Whilst Cocoa on iOS doesn't have this sort of UI bindings, you can still use 'Key-Value Observing' to synchronise changes in the data model with UI elements as described here:
http://developer.apple.com/library/iOS/#documentation/General/Conceptual/Devpedia-CocoaApp/KVO.html
I wrote a little open-source library that provides some simple data-binding functionality. It's basically just a wrapper around key-value observing (KVO).
http://github.com/kristopherjohnson/KJSimpleBinding
There are a few other similar libraries on GitHub:
http://github.com/dewind/KeyPathBindings
http://github.com/jonsterling/Observe
http://github.com/mruegenberg/objc-simple-bindings
http://github.com/zeasy/EasyBinding
Probably should also mention Github's Reactive Cocoa, a framework for composing and transforming sequences of values, an objective-C version of .NET's Reactive Extensions (Rx).
Binding mechanics can be done really simple (from the sample):
// RACObserve(self, username) creates a new RACSignal that sends a new value
// whenever the username changes. -subscribeNext: will execute the block
// whenever the signal sends a value.
[RACObserve(self, username) subscribeNext:^(NSString *newName) {
NSLog(#"%#", newName);
}];
Don't forget NSFetchedResultsController.
Not a full blown data bound controller, but makes table views a lot easier to use with Core Data.
If you're using Swift, check out Bond framework: https://github.com/ReactiveKit/Bond
Binding is as simple as:
textField.reactive.text.bind(to: label.reactive.text)
It plays well with functional:
textField.reactive.text
.map { "Hi " + $0 }
.bind(to: label.reactive.text)
And provides simple observations:
textField.reactive.text
.observeNext { text in
print(text)
}
STV (http://sensiblecocoa.com) is a framework that can do that within tableviews
I use CoreDataTableViewController from the Stanford University for my TableViewControllers. It hides a lot of details that you would normally implement in your TableViewController.
Googling for CoreDataTableViewController.h and .m will help you on the road. There are versions from several courses available, the latest does ARC, the old ones don't.
For syncing labels and edit fields with an NSManagedObject, I am still looking for a good solution.
Yes, there is a data binding framework that integrates well into Interface Builder and requires only minimal code overhead (if at all).
Take a look at https://github.com/mutech/aka-ios-beacon
EDIT:
You can for example bind a table view to a fetched results controller simply by setting the data source binding property of the table view in interface builder to:
[ yourResultsController ] { defaultCellMapping: "YourCellId" }
And the only thing you have to do is to define a property yourResultsController in your view controller.
The wiki provides a rather complete documentation and a lot of example use cases.