88

I have a NSURL object which gives me the path of a local file (in documents folder). I want to populate an NSData object with the contents of this file. Tried using dataWithContentsOfURL: but this fails. I know the file exists because the iPhone SDK returns the path.

Can someone please tell me how I can get an NSData object from the URL of a local file?

Thanks.

Rajesh Loganathan
  • 11,129
  • 4
  • 78
  • 90
lostInTransit
  • 70,519
  • 61
  • 198
  • 274
  • What does "but it fails" mean? – Marco Oct 03 '09 at 17:37
  • Means it freezes at this point! Gives an exception. I am trying to access a video's data, the URL of which we get from UIImagePickerController – lostInTransit Oct 03 '09 at 17:41
  • Seems you're trying to pass an object that is not a NURL. How are you getting the file URL, are you sure is an URL and not a NSString? – Marco Oct 03 '09 at 17:47
  • @AliKhaki: Please don't make trivial edits, it takes two people in the review queue to look over your changes. If you edit a question to improve it, feel free to remove useless stuff like "thanks", but don't edit the question just for that. Thanks! – Cris Luengo Oct 24 '18 at 19:06

5 Answers5

170
// Given some file path URL: NSURL *pathURL
// Note: [pathURL isFileURL] must return YES
NSString *path = [pathURL path];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];

Swift code:

let data = FileManager.default.contents(atPath: path)
Maciej Ciemięga
  • 10,125
  • 1
  • 41
  • 48
Tim
  • 59,527
  • 19
  • 156
  • 165
  • 1
    contentsOfFile takes an NSString with the file path. I am getting an NSURL object. – lostInTransit Oct 03 '09 at 17:44
  • I'm not sure but, using defaultManager instead of alloc, init might cause threading problems. – carlossless Mar 20 '13 at 15:35
  • 2
    The [NSFileManager docs](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html) have this to say under Threading Considerations: "The methods of the shared NSFileManager object can be called from multiple threads safely." The only exception they note is if you intend to handle delegate callbacks from the file manager's operations; I don't believe that applies here. – Tim Mar 20 '13 at 21:42
  • Note that the path is 'Full Path' of the file, which you can find it under File Inspector of XCode – Burak May 27 '16 at 11:53
29

To get this work you just need to do:

NSURL *imgPath = [[NSBundle mainBundle] URLForResource:@"search" withExtension:@"png"];
NSString*stringPath = [imgPath absoluteString]; //this is correct  

//you can again use it in NSURL eg if you have async loading images and your mechanism 
//uses only url like mine (but sometimes i need local files to load)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:stringPath]];
UIImage *ready = [[[UIImage alloc] initWithData:data] autorelease];
Marcin Małysz
  • 733
  • 8
  • 12
3

Make sure your local URL starts with "file://" then you would just have to do this:

 NSData *fileData = [NSData dataWithContentsOfFile:fileURL.path];
ahbou
  • 4,710
  • 23
  • 36
  • url is always returned as assets-library://asset/asset.MOV?id=095AA9E9-A4F5-4035-9A21-3CFF04F45C70&ext=MOV @ahbou – Mansuu.... Aug 17 '17 at 10:15
  • That's only valid for Assets (Photos and videos). The OP is askign about a file from the documents folder – ahbou Aug 17 '17 at 10:36
  • when I create data object from selected url fro asset_library it gives me nil @ahbou – Mansuu.... Aug 17 '17 at 10:47
  • Assets are only handled by the AssetsLibrary or the Photos.framework. To retrieve an asset you need to call asset.assetForURL{ } Search for this method or ask a new question as this a separate topic. – ahbou Aug 17 '17 at 10:53
0

For swift3 I found answer from following URL helpful

( I was getting following path , after capturing image using phonegap plugin

file:///var/mobile/Containers/Data/Application/B64B06DE-7976-45CF-9BE2-661F0F309A06/tmp/abcded.jpg )

https://stackoverflow.com/a/41043447/6383908

if let videoURL = URL(string: urlString), let videodata = try? Data(contentsOf: videoURL) { //Add code of Alamofire here }

Community
  • 1
  • 1
Chirag Purohit
  • 731
  • 11
  • 20
0
guard let data = FileManager.default.contents(atPath: path) else
    { ...
Anton Tropashko
  • 5,486
  • 5
  • 41
  • 66