I am trying to create an AVCaptureSession. I based my code on the WWDC 2011 video, number 419.
I have the following line which is exactly the same as the code in the WWDC 2011 video and it also identical to code here http://www.bardecode.com/en/knowledge-base/214-detailed-description-of-work-around-for-avcapturevideopreviewlayer-problem-in-ios-41.html
// Create a device input with the device and add it to the session.
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
But Xcode says that the &error is the use of an undeclared identifier.
This is because you've not defined the NSError error variable, that you're providing the address of when you use &error.
If you define the variable via...
NSError *error = nil;
...on the line before, all should be well.
As a bit of an explanation, if you look at the signature for the AVCaptureDeviceInput deviceInputWithDevice:error: method you'll see the following:
+ (id)deviceInputWithDevice:(AVCaptureDevice *)device error:(NSError **)outError
In other words, this method expects the address of an NSError pointer variable to be provided as the ourError parameter.
Related
I've searching for about 3 hours of how to get the creation date of a file, I get the URL with an enumerator, after that I pass it to path correcting the percents, and finally I try to get the file attributes...so, I don no alter the path in anyway but I always get the same error "The operation couldn’t be completed. No such file or directory", and the path "file:///Users/raul/Desktop/DSC_0386.JPG".
The code sample:
NSError* error = nil;
//NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:[[url absoluteString] stringByRemovingPercentEncoding] error:&error];
NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:#"file://Users/raul/Desktop/DSC_0386.JPG" error:&error];
NSLog(#"%#",error);
NSDate *fecha = [fileAttribs objectForKey:NSFileCreationDate];
I've commented the first NSDictionary to try out the second statement with the nsstring directly.
I've checked that my file already exists.
Please, any help?? I'm missing anything?
Several issues:
1) In most cases, you shouldn't have to convert an NSURL to a path string in order to operate on a file. In particular, you can use the "resource value" API of NSURL to get the creation time directly:
NSDate* creationDate;
NSError* error;
if ([url getResourceValue:&creationDate forKey:NSURLCreationDateKey error:&error])
/* use creationDate */;
else
/* handle error */;
2) If you do need to get a path string from NSURL, don't use -absoluteString. That will still be a URL string, with things like "file://", etc. A URL string is not a valid path string. The error message you quoted in your question was already telling you this. It showed you a file "path" of "file:///Users/raul/Desktop/DSC_0386.JPG", but that's not a path at all.
You should just use the -path method. You do not need to do anything with percent encoding when you get the -path.
3) You should ignore any error output parameter until you have checked whether the method you called succeeded or failed, usually by examining its return value. That is, the code you posted should be reorganized like this:
NSError* error = nil;
NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:#"file://Users/raul/Desktop/DSC_0386.JPG" error:&error];
if (fileAttribs)
{
NSDate *fecha = [fileAttribs objectForKey:NSFileCreationDate];
// ... use fecha ...
}
else
NSLog(#"%#",error);
I'm on Mavericks.
I'm using the simulator.
It appears that NSFileManager URL based methods don't work properly on XCode 6 / iOS 8.
In my code sample at bottom, the path being searched in 'directoryToScan' is ...
/Users/xxxx/Library/Developer/CoreSimulator/Devices/A092C58C-1A43-4AF3-A9B1-109D7BA27F8D/data/Containers/Data/Application/41232C14-CF90-4E5C-72A7-8FF464FE7C32/Documents
In the code at bottom, even though I have files at the path I'm providing, when my code reaches the "for in" enumerator, it jumps right over the "for in" block to the end of it, and continues at the next line, and I get NO ERROR message from the block in the errorHandler.
I also tried a while clause, and that did the same.
Also, I tried two other techniques...
// THIS DOES NOT WORK
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:directoryToScan includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:&theError];
// THIS DOES WORK
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentDirectory error:&theError];
So it appears there's a problem with NSURL's in iOS 8.
Any idea what's going on? I would think if there were a permission issue, I would have seen an error in my handler.
NSURL *directoryToScan = [NSURL fileURLWithPath:documentDirectory];
NSDirectoryEnumerator *dirEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:directoryToScan
includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLIsDirectoryKey, nil]
options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsSubdirectoryDescendants | NSDirectoryEnumerationSkipsPackageDescendants
errorHandler:^(NSURL *url, NSError *error){
NSLog(#"Error occurred at url %#",url);
NSLog(#"Error message is %#",error);
return YES;}];
for (NSURL *theURL in dirEnumerator)
{
// Work with the files found by dirEnumerator.
// This whole block is being skipped over.
}
If you are still interesting in investigating the issue can You please provide the code for setting directoryToScan and documentDirectory? Have you tried to print both values during debug to ensure they both address same directory? In Xcode 6.1?
In Xcode 6.1 both for (NSURL *theURL in dirEnumerator) and for (NSURL* theURL = [dirEnumerator nextObject]) work fine for me.
I have a property on my document class called passDescription, of type NSMutableDictionary. When I call setPassDescription:, the current value of the property is archived into an NSData instance using NSJSONSerialization. The property’s backing ivar, passDescription, is updated, and then an undo action is registered. The selector invoked by the action reconstitutes the NSData given to it and calls setPassDescription:.
Now, here’s the joker: passDescription is being observed using Key-Value Observing. Considerable experimentation and examination in Xcode’s debugger reveals that the old value and the new value are identical. (I know that this isn’t a pointer-aliasing issue, as that’s why I’m using an NSData instance. The NSData is created before I record the new value, making it independent of what it was created from.) Thus, when I press Command-Z to undo, nothing happens as the value that has just been restored is no different from the value that has been overwritten by the undo.
The only thing I can think of that may be causing this is that KVO is setting the passDescription ivar for me, before setPassDescription: gets called. Why would this be, and how could I prevent KVO from doing that? (I have confirmed that the setter isn’t being called twice. If it was, I would see double output in the debugger console.)
Here is the source for setPassDescription:.
- (void)setPassDescription:(NSDictionary *)param
{
NSLog(#"passDescription (before) = \n%#", passDescription);
NSError *error;
NSData *archivedOldValue = [NSJSONSerialization dataWithJSONObject:passDescription options:0 error:&error];
NSAssert(archivedOldValue != nil, #"Could not archive old pass description: %#", error);
NSData *blob = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
if (blob == nil) #throw [NSException exceptionWithName:#"PBJSONException" reason:#"Could not serialize pass.json" userInfo:#{ #"error": error }];
[self.fileBrowserRoot fileWrapperWithName:#"pass.json"].fileContents = blob;
[passDescriptionLock lock];
[[self.undoManager prepareWithInvocationTarget:self] setPassDescriptionFromData:archivedOldValue];
passDescription = param;
[passDescriptionLock unlock];
NSLog(#"passDescription (after) = \n%#", passDescription);
// After the pass description has been set, refresh the list of build issues.
[self recheckForIssues];
}
NSError *error;
NSString *string = [[NSString alloc]
initWithContentsOfURL:URL
encoding:NSUTF8StringEncoding
error:&error];
When I test this on my iPhone it always works when I have wifi turned on. However when I'm on 3G I often get nil. If I try perhaps 15 times in a row (I have an update button for this) I finally get the desired result.
My question is, is this problem located at the server side or is my code unstable? Should I use a different approach to get a more secure fetch of data?
You haven't provided enough information to give anything but a vague answer, but you do have some options here.
Most importantly, you have an "error" parameter that you should be printing out the results of. There's also a slightly better API you could be using in the NSString class.
Change your code to something like this:
NSError *error = NULL;
NSStringEncoding actualEncoding;
// variable names in Objective-C should usually start with lower case letters, so change
// URL in your code to "url", or even something more descriptive, like "urlOfOurString"
NSString *string = [[NSString alloc] initWithContentsOfURL:urlOfOurString usedEncoding:&actualEncoding error:&error];
if(string)
{
NSLog( #"hey, I actually got a result of %#", string);
if(actualEncoding != NSUTF8StringEncoding)
{
// I also suspect the string you're trying to load really isn't UTF8
NSLog( #"and look at that, the actual encoding wasn't NSUTF8StringEncoding");
}
} else {
NSLog( #"error when trying to fetch from URL %# - %#", [urlOfOurString absoluteString], [error localizedDescription]);
}
I'm now using STHTTPRequest instead. I recommend this library very much, easy to use yet powerful.
I have been trying to use AVFoundation to record screen outputs. For reasons unknown it stopped working after I moved to the latest version of Mac (Mountain Lion). I have been trying to getting it work but is not fruitful so far. I know that the AVFoundation method startRecordingToOutputFileURL will not work if the output file already exists. So, I tried using NSFileManager to see if my destination file exists and if it is writable. My Filemanager always returns the values corresponding to non-existence of the destination file and not writable. I tried to set file permissions to no avail, could anyone throw some light on my possible mistake:
dest = [[NSURL alloc] initFileURLWithPath:#"~/Desktop/myMovie.mov"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSNumber numberWithInt:777] forKey:NSFilePosixPermissions]; //I tried 511 too, no avail
[fileManager setAttributes:attributes ofItemAtPath:[dest path] error:nil];
if (![fileManager fileExistsAtPath:[dest path]]) {
if ([fileManager isWritableFileAtPath:[dest path]]) {
/* Starts recording to a given URL. */
[captureMovieFileOutput startRecordingToOutputFileURL:dest recordingDelegate:self];
}
else{
NSLog(#"File doesnot exist but is not writable"); //This is the message I get as result
}
}
else
{
NSLog(#"File Exists...");
}
Unexpanded tildes are not valid paths in Cocoa. You must use -stringByExpandingTildeInPath or better, -stringByStandardizingPath on the string passed into NSURL's -initFileURLWithPath:.
Because of this, NSFileManager will return NO for isWritableFileAtPath because it's an invalid path (so it's not writable). This leads you to your NSLog() being fired.
Update based on comments:
You may still find NSURL is returning nil upon creation (so calling -path will return nil) because the path is still invalid. Also worth noting, the documentation says for -isWritableFileAtPath:, "It's far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle those errors gracefully than it is to try to figure out ahead of time whether the operation will succeed."
Take Peter Hosey's suggestion and make use of the NSError if the call fails as you attempt to write to the file and don't try to figure it out ahead of time.