Issues playing local files with AVPlayer? - objective-c

Basically, I'm writing a video file to the Application Support directory and then saving it's path:
NSString *guid = [[NSUUID new] UUIDString];
NSString *outputFile = [NSString stringWithFormat:#"video_%#.mp4", guid];
NSString *outputDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *tempPath = [outputDirectory stringByAppendingPathComponent:outputFile];
NSURL *fileURL = [NSURL fileURLWithPath:tempPath]
// code to write a video to fileURL
I save the string path itself by calling [fileURL path];
Now later when I try to create an AVAssetItem from it, I can't actually get it to play.
EDIT:
Ok, so it seems the issue is the space in Application Support. I tried saving the file to just the Library directory and it worked fine.
So the question becomes, how can I play a video I save in the Application Support directory. I wasn't able to create a valid NSURL without escaping the space (when I tried it would return a nil NSURL) but it seems that the space/escaping doesn't allow it to play correctly.
Assume the NSURL to NSString conversion is required (unless it really should be avoided).
Also, side note, but if anyone could give some insight as to why this question was down voted so I can improve the quality of my questions, that would be appreciated. I don't understand?

While I am not informed enough to opine about whether this would change if I had used matt's recommended methods: URLForDirectory:inDomain:appropriateForURL:create:error: and URLByAppendingPathComponent: the actual issue here isn't converting an NSURL to NSString
It's that I'm saving the full URL ([fileURL path]). This is because the [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0]; dynamically changes and the full path won't always point me to the appropriate file.
Instead I need to save just the name of my file (in my case I needed to persist outputFile) and then later dynamically build the the full path when I need it.
The same exact process:
NSString *outputDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *tempPath = [outputDirectory stringByAppendingPathComponent:outputFile];
NSURL *fileURL = [NSURL fileURLWithPath:tempPath];
worked just fine.
TLDR: Saving a full path doesn't work

Related

Can't read text file from desktop using objective-c

Can anyone help me to find what's wrong with my code while reading file from desktop
NSString *filename=#"~/Users/user12345/Desktop/Sample/Data.txt";
NSString *fileString=[NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:nil];
NSArray *namesArray=[fileString componentsSeparatedByString:#"\n"];
for(NSString *names in namesArray)
{
NSLog(#"names:%#",names);
}
If you want to use the tilde – which represents /User/<currentUser>/ – you have to ...expandingTildeInPath and remove /Users/user12345
NSString *filename = [#"~/Desktop/Sample/Data.txt" stringByExpandingTildeInPath];
that makes the path independent of the current user name, otherwise remove the tilde:
NSString *filename = #"/Users/user12345/Desktop/Sample/Data.txt";
Caveat: If your app is sandboxed the path does not point to the visible desktop.
NSString *filename=#"~/Users/user12345/Desktop/Sample/Data.txt";
The ~ used in a path is a convention which means your home directory, but it doesn't work in all contexts (e.g. when used in -stringWithContentsOfFile:`) and you've supplied an absolute path anyway. Remove it from the front of your path
NSString *filename=#"/Users/user12345/Desktop/Sample/Data.txt";
and it should work as long as the file does actually exist at that path.

How to see the path of a NSURL bookmark even if it's unavailable

I'm saving a NSURL given from a save panel in the user preferences. I'm wondering how to see the path of the URL even if the device on which the file resides is not available, i.e. [NSURL URLByResolvingBookmarkData:options:bookmarkDataIsStale:error:] returns nil.
The last known path of a bookmark can be retrieved like so:
NSDictionary *values = [[NSURL resourceValuesForKeys:#[NSURLPathKey]
fromBookmarkData:bookmarkData]
NSString *path = [values objectForKey:NSURLPathKey];
I made a full writeup of this.

Embedding XML to iOS application

I'm making my first game in iOS and I need to load some levels that are stored as XML. Level files are stored locally and everything works fine from emulator. However, since XML is loaded in the runtime when i try to test my game on an actual device it can't find the XML files since they are not actually part of the app.
I'm coming from Flash background so I might have a wrong idea how this is done on iOS but I need to somehow bundle those XML files with the app, or embed it in the code somehow? Is this possible?
Thanks a lot :)
Well The code to look up your app bundle for the specified file is
NSString *path = [[NSBundle mainBundle] pathForResource:#"fileName.xml" ofType:nil]
NSURL *xmlURL = [NSURL fileURLWithPath:path];
[[NSXMLParser alloc] initWithContentsOfURL: xmlURL]
Hope this helps you...
You could add the XML file to your project and run time read it up with something like this
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *myPath = [myPathList objectAtIndex:0];
NSError **err;
myPath = [myPath stringByAppendingPathComponent:fileName];
if([[NSFileManager defaultManager] fileExistsAtPath:myPath])
text = [NSString stringWithContentsOfFile:myPath encoding:NSUTF8StringEncoding error:err];
You could consider using JSON in instead of XML. At least to my knowledge the available XML parsers are not nearly as simply to use as SBJson for instance (https://github.com/stig/json-framework/)
Here is my solution in Swift 3.0. In addition to the code, you'll need to add your xml file as a data set in your Assets.xcassets. Do this by creating a new Data Set, giving it any name, and then dragging the xml file from the finder to your newly created data set. When you reference the file in your code, you'll use the file name of the file, and not the name of the data set.
var parseResults = false
if let path = Bundle.main.path(forResource: fileName, ofType: ".xml") {
let url = URL(fileURLWithPath: path)
if let xmlParser = XMLParser(contentsOf: urlToFile) {
xmlParser.delegate = self
parseResults = xmlParser.parse()
}
}

NSURL fileURLWithPath where NSString has a space

I've looked at quite a few of the related questions and cannot find a similar problem or a solution so my apologies if there is a duplicate out there somewhere.
Anyway, I'm trying to generate a file's NSURL to use with an NSXMLDocument. I have the following components:
const NSString * PROJECT_DIR = #"~/SP\\ BB/";
const NSString * STRINGS_FILE = #"Localizable.strings";
and construct the URL like so:
NSURL * stringsURL = [NSURL fileURLWithPath:[[NSString stringWithFormat:#"%#%#",PROJECT_DIR,STRINGS_FILE] stringByExpandingTildeInPath]];
however, the resulting path in the NSURL is:
file://localhost/Users/timothyborrowdale/SP2B/Localizable.strings
I have tried changing the PROJECT_DIR to
#"~/SP BB/"
#"~/SP\\\\ BB/" (changes to SP엀2B)
#"~/SP%20BB/"
#"~/SP\%20BB/"
with the same problem. I also tried typing out the file url completely and using [NSURL URLWithString:]
I have also tried using stringByAddingPercentEscapesUsingEncoding with both NSUTF8Encoding and NSASCCIEncoding and these have the same issue.
The NSString displays properly before being passed to NSURL or stringByAddingPercentEscapesUsingEncoding but has the problem once outputted from either.
Try this:
NSString *fnam = [#"Localizable" stringByAppendingPathExtension:#"strings"];
NSArray *parts = [NSArray arrayWithPathComponents:#"~", #"SP BB", fnam, (void *)nil];
NSString *path = [[NSString pathWithComponents:parts] stringByStandardizingPath];
NSURL *furl = [NSURL fileURLWithPath:path];
Foundation has a host of platform-independent, path-related methods. Prefer those over hard-coding path extension separators (often ".") and path component separators (often "/" or "\").
Try abandoning stringWithFormat: (never the right answer for stapling paths together) and stringByExpandingTildeInPath and using NSHomeDirectory() and stringByAppendingPathComponent: instead.
#"~/SP\\ BB/" (changes to SP엀2B)
How did you arrive at that conclusion?

Failure to write NSString to file on iPad

I'm using a text file to save the changes made by a user on a list (the reason that I'm doing this is so that I can upload the text file to a PC later on, and from there insert it into an Excel spreadsheet). I have 3 data structures: A NSMutableArray of keys, and a NSMutableDictionary who's key values are MSMutableArrays of NSStrings.
I iterate through these data structures and compile a file string that looks much like this:
(Key);(value)\t(value)\t(value):\n(Key);(value).. .so on.
SO, onto the actual question: When I attempt to save it, it fails. I'm 99% sure this is because of the file path that I'm using, but I wanted backup to check this out. Code follows:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *filePath = [paths objectAtIndex:0];
NSString *fileString = [NSString stringWithString:[self toFileString]];
if(![fileString writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:NULL]){
NSLog(#"File save failed");
} else {
// do stuff
}
(Code above is re-copied, since the actual code is on a different computer. It compiles, so ignore spelling errors?)
I tried using NSError, but I got bogged down in documentation and figured I might as well ask SO while trying to figure out how to properly use NSError (might be a little bit of an idiot, sorry).
99% sure it's the NSArray *paths line that's tripping it up, but I don't know how else to get the documents directory.
Edit: Problem solved, and one final question: If I save it to the App's document directory, where can I go after I close the app to see if it saved properly? If it works like I think it does, isn't it sandboxed in with the app's installation on the simulator? (i.e. no way of checking it)
NSLog() that filePath string. I think you're trying to write to the directory itself, not to a file.
Try this instead:
filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"myfile.txt"];
What is the file name you want to save? The method
NSArray *paths = NSSearchPathForDirectoriesInDomains(...);
NSString *filePath = [paths objectAtIndex:0];
...
if(![fileString writeToFile:filePath ...
means you are saving the string into a file path which has the same name as a folder. This will of course fail. Please give it a name, e.g.
NSString* fileName = [filePath stringByAppendingPathComponent:#"file.txt"];
if(![fileString writeToFile:fileName ...
and try again.
BTW, to use NSError:
NSError* theError = nil;
if(![fileString writeToFile:fileName ... error:&theError]) {
// ^^^^^^^^^
NSLog(#"Failed with reason %#", theError);
// theError is autoreleased.
}