How to create a new instance of an NSDocument with NSDocumentController? - macos

I tried
[[NSDocumentController sharedDocumentController] duplicateDocumentWithContentsOfURL:nil
copying:NO
displayName:nil
error:NULL] ;
but it is not working. I have the error
typeForContentsOfURL:error: must be overridden for your application to support non-'file:' URLs.

Did you try like this below:-
[[NSDocumentController sharedDocumentController]newDocument:self];

I don't really know about the NSDocument+NSDocumentController machinery but here is my guess . Since I am answering my own question, please don't hesitate to comment or react.
[[NSDocumentController sharedDocumentController] addDocument:[[Document alloc] initWithType:nil
error:NULL]] ;

Related

gnustep runloop

Does anyone tell is GNUstep NSRunLoop extension functions:
(void) addEvent: (void*)data
type: (RunLoopEventType)type
watcher: (id)watcher
forMode: (NSString*)mode;
this method is work?, and how to setup the argument data? I set a pipe to read file description, but it seems not work fine. Really hard to figure out the question, can anyone help me?
This method works. Please show more of your code.
eg. for reading,
[[NSRunLoop currentRunLoop] addEvent: (void*)anFd
type: ET_RDESC
watcher: anObj // must implement receivedEvent:type:extra:forMode:
forMode: NSDefaultRunLoopMode]; // rtfm

Connection Kit Basics

I need to implement file transfer in my application and it seems that in Cocoa ConnectionKit is unofficial standard. I was able to compile it but I have struggled finding any documentation or examples of it's use. The only example I found was outdated and even with modification I could not get it to work. Does anyone know the basic functions (creating connections, uploading...).
Thanks for any help
Its pretty simple once you figure out how its laid out.
Heres the code to create an ftp connection
CKConnectionRequest *request = [CKConnectionRequest requestWithURL:url];
CKFTPConnection *ftpConn = [[CKFTPConnection alloc] initWithRequest:request];
[ftpConn setDelegate:self];
[ftpConn connect];
self.connection = ftpConn;
[ftpConn release];
Then you would interact with the Connection Delegate methods found in CKConnectionProtocol.h
To authenticate to the server above you would use this delegate method where "cred" is an instance of NSURLCredential you have set up with the credentials you need.
- (void)connection:(id <CKConnection>)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
}
For an upload you would just call one of the upload methods specified in CKConnectionProtocol.h inside of a delegate method like below
- (void)connection:(id <CKConnection>)con
didOpenAtPath:(NSString *)dirPath error:(NSError *)error {
CKTransferRecord *tr = [con uploadLocalItem:localPath
toRemoteDirectory:remotePath
ignoreHiddenItems:YES];
}
Then you would receive callbacks as to the status of that upload via the Uploading Methods specified in CKConnectionProtocol.h
Hopefully that helps. Forgive any small errors in the code I typed it out not copy/paste

Need help with NSURLCredential initWithTrust:

I have been beating my head against the wall for the last few hours and cannot find even a glimmer of a solution anywhere.
I am working on an app to learn how to work with JSON so I am just building a simple app that at first just returns a list of all of my repos on GitHub.
I am able to extract the JSON response from the data returned by NSURLConnection with no problem, unfortunately when I try to access anything that requires authentication the response is always {
message = "Not Found";
}
If I send a request to just get public information about my username I get back the correct response with all the correct info so I know that I am successfully communicating with api.github.com.
First off to start the request I use:
-(IBAction)retriveRepos:(id)sender
{
responseData = [[NSMutableData data] retain];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://api.github.com/user/repos"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
When - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge gets called the authentication method comes back as NSURLAuthenticationMethodServerTrust (which I find strange since I feel like I should be supplying a username and password to login). According to Apple's docs I need to create my NSURLCredential with initWithTrust:. I Googled for answers and finally found a few places that said to just take the serverTrust from the protectionSpace of the NSURLAuthenticationChallenge that was passed in. Doing this shows no signs of having any effect at all, in fact it looks like my NSURLCredential has pretty much nothing in it.
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
NSLog(#"challenge.protectionSpace.serverTrust: %#", challenge.protectionSpace.serverTrust); // This logs "challenge.protectionSpace.serverTrust: <SecTrust 0x10340b2e0 [0x7fff7cc12ea0]>"
NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
NSLog(#"credential: %#", credential); // Always logs something like "credential: <NSURLCredential: 0x1002d2f20>: (null)"
NSURLCredential *otherCredential = [[NSURLCredential alloc] initWithUser:#"user" password:#"password" persistence:NSURLCredentialPersistencePermanent];
NSLog(#"otherCredential: %#", otherCredential); // This logs otherCredential: <NSURLCredential: 0x1018d0840>: user"
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
I used more extensive logging as well that showed that credential did in fact exist (at first I thought it hadn't been created at all) but that it had none of it's attributes set certificates: (null)
hasPassword: 0
identity: (null)
password: (null)
. I can only assume that the problem is in my authentication but I followed the examples I found to the letter. I am using the GM preview of Lion, so I guess it is possible I found a bug, or that there is some bug in the GitHub API, but given my skill level I find it much more likely that I am an idiot that is looking over the answer sitting right in front of me.
If anyone knows of a good guide that actually walks you through all the steps of authenticating (preferably in all the styles) rather than the severely lacking Apple URL loading guide that just says to use a method but doesn't say where the SecTrustRef comes from it would be greatly appreciated.
NSURLAuthenticationMethodServerTrust is what you will get back as it negotiates an SSL connection. It's giving you the opportunity to evaluate the trust of the server (or vice versa). Technote 2232 describes this in a bit of detail. Your delegate needs to handle it, the technote links to the source for the sample code Advanced URL Connections which should show you how to respond to that challenge.
Don't despair, if there is an HTTP authentication step coming from your server, you will see the delegate get that later.

How to properly save a QTMovie after editing using QTKit?

I am making minor edits to a QTMovie in an application using NSDocument architecture (such as adding a track, as shown below). After the edit, I want to save to the original file. However, I keep getting a 'file is busy' error. I assume this is due to some oversight I made in the handling of the files, or a failure in how I am using NSDocument. Any tips would be helpful! Here is (some of) the relevant code:
// open file that has the track I want to add to my movie
QTMovie* tempMovie = [QTMovie movieWithURL:outputFileURL error:nil];
// Use old API to add the track
AddMovieSelection([movie quickTimeMovie], [tempMovie quickTimeMovie]);
// get the filename from the NSDocument
NSString *filename = [[self fileURL] path];
NSLog(#"writing to filename: %#", filename);
// FLATTEN the movie file so I don't get external references
NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:1];
[attributes setObject:[NSNumber numberWithBool:YES] forKey:QTMovieFlatten];
// attempt to write
NSError *error;
// this is where I get the "file is busy"
if (![movie writeToFile:filename withAttributes:attributes error:&error]) {
NSLog(#"Error: %#", [error localizedDescription]);
NSRunAlertPanel(#"Error", [error localizedDescription], nil, nil, nil);
}
Do I have to first release the movie in my NSDocument? What is the "proper" way to do that? Keep in mind, I am not necessarily finished with this document, I am not closing it. I have just finished this operation, and I want the file on disk to reflect my changes. I would love to use [movie updateMovieFile], but that call doesn't seem to flatten the movie. I don't want any external references in my file.
I am not too familiar with the QuickTime C API, so I honestly can't tell you anything about what is going wrong there. Absolute guesswork: Maybe a call to EndMediaEdits is missing?
Though that shouldn't be required by AddMovieSelection, you said "[...] such as adding a track [...]". So maybe there is something else going on, like AddMediaSample or something similar?
That said, if you don't need to target anything below 10.5 and all you need to do is add some segment from another movie, you can achieve that without dropping down to the C API:
Have a look at
-[QTMovie insertSegmentOfTrack:fromRange:scaledToRange:]
and
-[QTMovie insertSegmentOfMovie:fromRange:scaledToRange:], if you want to have the inserted segment "overlayed" (temporally speaking).
-[QTMovie insertSegmentOfMovie:timeRange:atTime:] and -[QTMovie insertSegmentOfTrack:timeRange:atTime:], if you want { movieA.firstPart, movieB, movieA.secondPart }.
Do I have to first release the movie in my NSDocument?
You mean in order to write it to disk? No: That should even result in a crash.
The role of release is to handle memory-management. It doesn't have much to do with the busy-state of a file.
Turns out I just wasn't using the NSDocument architecture properly. When I changed it to use Save/SaveAs properly, this problem went away.

Why is -[NSPasteboard writeObjects:] returning NO for an array of NSURL objects?

I have an NSArrayController that I'm using to provide data to an IKImageBrowserView. I want to support drag and drop from the IKImageBrowserView to other applications. Here's the relevant method from my code:
- (NSUInteger) imageBrowser:(IKImageBrowserView *) aBrowser writeItemsAtIndexes:(NSIndexSet *) itemIndexes toPasteboard:(NSPasteboard *)pasteboard{
NSArray *items = [[resultsArrayController arrangedObjects] objectsAtIndexes:itemIndexes];
if(![pasteboard writeObjects:items]){
return 0;
}
return [items count];
}
My app is new so I'm targeting 10.6+ and according to the documentation, "On Mac OS X v10.6 and later, use writeObjects: to write URLs directly to the pasteboard instead."
I've verified that the objects that I am attempting to write are indeed NSURL objects, so I'm not sure where the process is breaking down or how to further troubleshoot the problem. Thanks in advance for any help.
Have you cleared the pasteboard yet? You need to do that, and thereby become the pasteboard's owner, before you can write objects to the pasteboard.
Have you verified that your pasteboard variable is not nil?
Are the objects that are to be sent to -[NSPasteboard writeObjects:] supposed to be NSPasteboadItems? You can set their string value to the absoluteString of the NSURL and write an array of NSPasteboadItems.

Resources