Can't delete a file created by mkstemp() on Mac OS X - cocoa

Apparently, NSFileManager is unable to delete files created by mkstemp(). Here's some test code to demonstrate this:
char pathCString[] = "/tmp/temp.XXXXXX";
int fileDescriptor = mkstemp(pathCString);
if (fileDescriptor == -1) {
NSLog(#"mkstemp failed");
} else {
close(fileDescriptor);
NSURL *url = [NSURL URLWithString:[NSString stringWithCString:pathCString encoding:NSASCIIStringEncoding]];
NSLog(#"URL: %#", url);
NSError *error;
if (![[NSFileManager defaultManager] removeItemAtURL:url error:&error]) {
NSLog(#"could not delete file: %#", error);
}
}
Here's what I see in the log when I run the above code:
URL: /tmp/temp.A7DsLW
could not delete file: Error Domain=NSCocoaErrorDomain Code=4 UserInfo=0x1001108a0 "The file “temp.A7DsLW” doesn’t exist."
I'm running this on Snow Leopard. Any ideas on why the problem is occurring and/or how to work around it?
Thanks!

Don't use -URLWithString:, use -fileURLWithPath: you didn't make a valid file URL. Passing the path string directly to NSFileManager's -removeItemAtPath: will of course be shorter.
Also, for file paths, always make the path string with -stringWithUTF8String:.

Related

OSX Dropbox Sync API Error - unable to verify link request

Coded in Swift I implemented after the Tutorial.
DBAccountManager is setup in AppDelegate on applicationDidFinishLaunching.
Later, when the user activates dropbox support in my application I'm trying to link the account.
The Window Panel is displayed and my application is waiting for the callback.
Sometimes I do not get a linked account, even the user logs in and accepts.
The Log says
"[ERROR] unable to verify link request"
When this occurs on a machine it wont't work, you can retry and retry...
if it worked, it works like a charm and in future I always get the linked account directly from the library without the login window.
What does this error mean and what can I do?
AppDelegate:
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Dropbox API Key & Secret
let _appKey = "------"
let _appSecret = "------"
// Accountmanager
if (DBAccountManager.sharedManager() == nil)
{
let accountManager = DBAccountManager(appKey: _appKey, secret: _appSecret)
DBAccountManager.setSharedManager(accountManager)
}
....
}
The linking in my class, when user clicked to activate dropbox:
internal func __start(parentWindow:NSWindow?, callback:((Bool) -> Void))
{
let am = DBAccountManager.sharedManager()
if am == nil
{
NSLog("Dropbox not available!")
callback!(false)
return
}
// link account
let linkedAccount = am!.linkedAccount
if (linkedAccount != nil)
{
// Already linked
DLog("Dropbox link found.")
let fileSystem = DBFilesystem(account: linkedAccount!)
DBFilesystem.setSharedFilesystem(fileSystem)
callback(true)
}
else
{
// link with window must be in mainthread
dispatch_async(dispatch_get_main_queue())
{
am!.linkFromWindow(parentWindow) {
account in
if (account != nil)
{
DLog("Dropbox linked")
let fileSystem = DBFilesystem(account: account!)
DBFilesystem.setSharedFilesystem(fileSystem)
callback(true)
}
else
{
DLog("NOT LINKED (Dropbox)")
callback(false)
} // if - else account
} // accountmanager block
} // dispatchblock main
} // if - else linkedaccount
}
Here the full log, the app is not doing anything else:
2015-02-23 10:25:39.443 TestApp[39226:30958267] Dropbox init
<<<< MediaValidator >>>> mv_ValidateRFC4281CodecId: Unrecognized codec 1.(null). Failed codec specific check.
<<<< MediaValidator >>>> mv_LookupCodecSupport: Unrecognized codec 1
[10:25:40.979] mv_LowLevelCheckIfVideoPlayableUsingDecoder signalled err=-12956 (kFigMediaValidatorError_VideoCodecNotSupported) (video codec 1) at line 1851
<<<< MediaValidator >>>> mv_TestCodecSupportUsingDecoders: Unrecognized codec 1
<<<< MediaValidator >>>> mv_ValidateRFC4281CodecId: Unrecognized codec 1.(null). Failed codec specific check.
<<<< MediaValidator >>>> mv_LookupCodecSupport: Unrecognized codec 1
[10:25:40.979] mv_LowLevelCheckIfVideoPlayableUsingDecoder signalled err=-12956 (kFigMediaValidatorError_VideoCodecNotSupported) (video codec 1) at line 1851
<<<< MediaValidator >>>> mv_TestCodecSupportUsingDecoders: Unrecognized codec 1
2015-02-23 10:25:43.873 TestApp[39226:30958267] [ERROR] unable to verify link request
2015-02-23 10:25:43.879 TestApp[39226:30958267] NOT LINKED (Dropbox)
I have same issue [ERROR] unable to verify link request after long research and studying the DropBoxSDK I come to the point that this error occurs when state ID is different from value saved at key KDBKLinkNonce. Every time at new Session it generates new state ID. See below code of [[DBSession sharedSession] handleOpenURL:url] method.
- (BOOL)handleOpenURL:(NSURL *)url {
NSString *expected = [NSString stringWithFormat:#"%#://%#/", [self appScheme], kDBDropboxAPIVersion];
if (![[url absoluteString] hasPrefix:expected]) {
return NO;
}
NSArray *components = [[url path] pathComponents];
NSString *methodName = [components count] > 1 ? [components objectAtIndex:1] : nil;
if ([methodName isEqual:#"connect"]) {
NSDictionary *params = [DBSession parseURLParams:[url query]];
NSString *token = [params objectForKey:#"oauth_token"];
NSString *secret = [params objectForKey:#"oauth_token_secret"];
NSString *userId = [params objectForKey:#"uid"];
NSString *state = [params objectForKey:#"state"];
NSString *nonce = [[NSUserDefaults standardUserDefaults] objectForKey:kDBLinkNonce];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kDBLinkNonce];
[[NSUserDefaults standardUserDefaults] synchronize];
if (![nonce isEqual:state]) {
DBLogError(#"unable to verify link request");
return NO;
}
[self updateAccessToken:token accessTokenSecret:secret forUserId:userId];
} else if ([methodName isEqual:#"cancel"]) {
DBLogInfo(#"DropboxSDK: user cancelled Dropbox link");
}
return YES; }
For further reference please check this link dropbox-sdk-ios
I found something and since I found a fix for that, even the dropbox error is gone.
The problem seems to be, that NSUserDefaults did not store any data (not in memory and not on disk!). Since Dropbox uses NSUserDefaults to check the state before and after, this killed the whole process.
With getting the NSUserDefaults back working it seems the whole dropbox problem was gone.
OSX NSUserDefaults not Working

`PFFile getDataInBackgroundWithBlock` block not getting called Obj-C

I have the following code, to retrieve an image from Parse. This code block is in a recursive loop that gets called for a list of images in an array.
PFFile *remoteImageFile = object[#"Image"]
[remoteImageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
DDLogInfo(#"%s:%d %#", __PRETTY_FUNCTION__, __LINE__, [error debugDescription]);
// other logics
}];
The code fetches most of the images successfully, the sizes of the images being 2MB to 3MB. But randomly it fails for certain files and the block is not getting fired and my whole fetching operation freezes. Couldn't find the reason.
Any help please
I doubt that there is a bug in the Parse framework here. The most probable cause is that your remoteImageFile is nil which means that getDataInBackgroundWithBlock: is not even called.
Can you check by using the following code :
PFFile *remoteImageFile = object[#"Image"];
if (remoteImageFile == nil || ![remoteImageFile isKindOfClass:[PFFile class]]) {
NSLog(#"Error : remoteImageFile = %#", remoteImageFile);
} else {
[remoteImageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
DDLogInfo(#"%s:%d %#", __PRETTY_FUNCTION__, __LINE__, [error debugDescription]);
// other logics
}];
}

Load files in xcode unit tests

I have an Xcode 5 unit test project and some test xml files related to it. I've tried a bunch of approaches but I can't seem to load the xml files.
I've tried the following which does not work
NSData* nsData = [NSData dataWithContentsOfFile:#"TestResource/TestData.xml"];
NSString* fileString = [NSString stringWithContentsOfFile:#"TestData.xml" encoding:NSUTF8StringEncoding error:&error];
Also if I try to preview all the bundles using [NSBundle allBundles] the unit test bundle does not appear in the list?
I tried to create a separate resource bundle and I can't seem to locate it programmatically although it does get built and deployed.
What am I doing wrong ?
When running tests the application bundle is still the main bundle. You need to use unit tests bundle.
Objective C:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:#"TestData" ofType:#"xml"];
NSData *xmlData = [NSData dataWithContentsOfFile:path];
Swift 2:
let bundle = NSBundle(forClass: self.dynamicType)
let path = bundle.pathForResource("TestData", ofType: "xml")!
let xmlData = NSData(contentsOfFile: path)
Swift 3 and up:
let bundle = Bundle(for: type(of: self))
let path = bundle.path(forResource: "TestData", ofType: "xml")!
let xmlData = NSData(contentsOfFile: path)
With swift Swift 3 the syntax self.dynamicType has been deprecated, use this instead
let testBundle = Bundle(for: type(of: self))
guard let ressourceURL = testBundle.url(forResource: "TestData", ofType: "xml") else {
// file does not exist
return
}
do {
let ressourceData = try Data(contentsOf: ressourceURL)
} catch let error {
// some error occurred when reading the file
}
or
guard let ressourceURL = testBundle.url(forResource: "TestData", withExtension: "xml")
As stated in this answer:
When the unit test harness runs your code, your unit test bundle is NOT the main bundle. Even though you are running tests, not your application, your application bundle is still the main bundle.
If you use following code, then your code will search the bundle that your unit test class is in, and everything will be fine.
Objective C:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:#"TestData" ofType:#"xml"];
NSData *xmlData = [NSData dataWithContentsOfFile:path];
Swift:
let bundle = NSBundle(forClass: self.dynamicType)
if let path = bundle.pathForResource("TestData", ofType: "xml")
{
let xmlData = NSData(contentsOfFile: path)
}
Swift 4+
I found none of the answers here up–to date or using a URL.
First add the following function to your testClass:
/// getFile. Opens a file in the current bundle and return as data
/// - Parameters:
/// - name: fileName
/// - withExtension: extension name, i.e. "json"
/// - Returns: Data of the contents of the file on nil if not found
static func getFile(_ name: String, withExtension: String) -> Data? {
guard let url = Bundle(for: Self.self)
.url(forResource: name, withExtension: withExtension) else { return nil }
guard let data = try? Data(contentsOf: url) else { return nil }
return data
}
Then you can call it in your test class like this:
func test() throws {
let xmlData = Self.getFile("TestData", withExtension: "xml")
XCTAssertNotNil(xmlData, "File not found")
}
Note: Apple recommends that URL's should always be used for resources (not paths) for security reasons.
Relative paths are relative to the current working directory. By default, that's / — the root directory. It's looking for that folder at the root level of your startup disk.
The correct way to get a resource that's within your bundle is to ask your bundle for it.
In an application, you'd get the bundle using [NSBundle mainBundle]. I don't know if that works in a test case; try it, and if it doesn't (if it returns nil or an unuseful bundle object), substitute [NSBundle bundleForClass:[self class]].
Either way, once you have the bundle, you can ask it for the path or URL for a resource. You generally should go for URLs unless you have a very specific reason to need a path (like passing it to a command-line tool using NSTask). Send the bundle a URLForResource:withExtension: message to get the resource's URL.
Then, for the purpose of reading a string from it, use [NSString stringWithContentsOfURL:encoding:error:], passing the URL you got from the bundle.
One thing to note is(It waste me serval minutes to figure it out):
Don't forget to add the test file to "Copy Bundle Resources" section of Build Phases
Without it, you couldn't load the file successfully.
Get main bundle
Use main bundle to get local mock data
Load data from JSON
let mainBundle = Bundle(identifier: "com.mainBundle.Identifier")
if let path = mainBundle?.path(forResource: "mockData", ofType: "json") {
do {
let testData = try Data(contentsOf: URL(fileURLWithPath: path))
networkTestSession.data = testData
} catch {
debugPrint("local json test data missing")
}
}
I know this specific question is asking for xml files, but if you're trying to do the same with json files, try this:
let url = Bundle.main.url(forResource: "data", withExtension: ".json")
guard let dataURL = url, let data = try? Data(contentsOf: dataURL) else {
fatalError("Couldn't read data.json file") }

How can I save and read AVAudioRecordings on sqlite?

I am working on an app that requires me to save audio recordings in the database and retrieve them later. However, while I'm somewhat aware of how to use sqlite, I'm not sure if I'm using the right method when it comes to saving audio recordings, as I have a hard time getting it to work. The current code I'm using to save recordings is listed below and I would appreciate any feedback I receive regarding my code.
self.renameString =[NSString stringWithFormat:#"%#/%#.caf",DOCUMENTS_FOLDER,self.soundName.text];
NSLog(#"%#",self.renameString);
self.soundFileURL2 = [NSURL fileURLWithPath:self.renameString];
NSLog(#"%#",self.soundFileURL2);
NSFileManager *fm = [NSFileManager defaultManager];
NSError *renameError;
[fm moveItemAtURL:self.soundFileURL toURL:self.soundFileURL2 error:&renameError];
[self checkAndCreateDatabase];
self.soundName.text = #"";
BOOL checkQuery;
NSData *blob;
blob = self.voiceData;
sqlite3_stmt *statement;
const char *insert = [self.renameString UTF8String];
if(sqlite3_prepare_v2(soundDB, insert, -1, &statement, NULL)!= SQLITE_OK) {
checkQuery=NO;
}
else {
sqlite3_bind_blob(statement, 1, [blob bytes], [blob length], NULL);
if(SQLITE_DONE != sqlite3_step(statement)) {
checkQuery=NO;
}
else {
// NSLog(#"Query Working nicely");
checkQuery=YES;
sqlite3_reset(statement);
}
}
//}
sqlite3_finalize(statement);
sqlite3_close(soundDB);
I'm also aware that in order to retrieve the saved file, you have to declare a new NSData variable and assign the reading to that variable. Afterwards, you have to extract the NSData and put it in another variable itself. The problem is, while I'm aware of how to extract NSString and UIImage data, I'm not sure about the rules for extracting AVAudioRecorder data. Can someone please help me on this? Thanks.

How do I get just the audio files from the iTunes main library (returned by Scripting Bridge)?

I have quite a simple problem. I want to put the audiofiles into my table view. How do I distinguish them from pdfs and movies, etc?
I get them from iTunes over Scripting Bridge:
iTunesSource *source = [[[self iTunes] sources] objectAtIndex:0];
iTunesPlaylist *mainPlaylist = [[source libraryPlaylists] objectAtIndex:0] ;
library_ = [[NSArray arrayWithArray:[mainPlaylist tracks]] retain ] ;
This gives me an error saying the class iTunesFileTrack could not be found ( at linking time)
:
[track get];
if(![track isKindOfClass:[iTunesFileTrack class]]) {
DLog1(#"SKIPPING kind: %#", [track kind]);
}
I'm sure I'm missing something simple :)
On a related note: Is there a faster way to read the iTunes library? I just advice on loading it from an xml file but that seems unsafe to me. If apple changes anything in the next release I'm screwed.
Thank you
EDIT: With sdef /Applications/iTunes.app | sdp -fhm --basename iTunes I can generate the .m file I need to check for the class. But it does not seem to work:
[track get];
if(![[track className] isEqualToString:#"ITunesFileTrack"]) {
DLog1(#"SKIPPING kind: %#", [track kind]);
continue;
}
Skipps just my streams :P Not the movies. (Even when I add (track.videoKind != iTunesEVdKNone)). Even the PDF's are iTunesFileTracks. But the .h states:
// a track representing an audio file (MP3, AIFF, etc.)
#interface iTunesFileTrack : iTunesTrack
I use something like this in my code so it should work (app is the iTunes SBApplication):
1.) First get the library source
- (ITunesSource *)librarySource {
NSArray *sources = [[app sources] get];
NSArray *libs = [sources filteredArrayUsingPredicate:[NSPredicate
predicateWithFormat:#"kind == %i",
ITunesESrcLibrary]];
if ([libs count]) {
return [libs objectAtIndex:0];
}
return nil;
}
2.) Iterate through the library playlist(s)
NSArray *libraryLists = [[[self librarySource] libraryPlaylists] get];
for (ITunesLibraryPlaylist *list in libraryLists) {
NSArray *listTracks = [[list fileTracks] get];
for (ITunesTrack *listTrack in listTracks) {
// do stuff...
}
[listTracks release];
}
3.) You can check for other track types like so
if (track.videoKind != ITunesEVdKNone || track.podcast) {
// track is not of type music
}

Resources