NSBundle pathForResource nil - ios

I am attempting to load an M4A file but I can't get the path to the file using NSBundle.
NSString *fileURLString = [[NSBundle mainBundle] pathForResource:fileName ofType:fileExtension];
NSURL *fileToBePlayed = [[NSURL alloc] initWithString:fileURLString];
tourAudioPlayer = [tourAudioPlayer initWithContentsOfURL:fileToBePlayed error:nil];
When I run the code the debugger shows that fileURLString is nil and, thus, so are the subsequent two objects.
I've added the file to the Supporting Files directory and confirmed that the file is included under Copy Bundle Resources under Target > Build Phases.
Unfortunately the magic of Clean and Build has failed me in this case. Is there some stage in loading the file in that I'm missing?

Just try this....
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *vedioURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:FileName ofType:FileType]];
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:vedioURL];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
}

I've solved the problem, which turns out to have been two silly problems.
The first problem was that I was using initWithString: rather than fileURLWithPath:. Lazy reading of the documentation on my part.
The second problem was a mere embarrassing oversight. The code snippet provided represents the initial creation of the AVAudioPlayer and thus I was following to allocate space for it on the heap.
Making the changes above has remedied the problem. Thank you to everyone that offered advice and support.

Related

Error ARC 'release' is unavailable error becomes "expression result unused'

I know that this is a similar question to the ARC deprecated code however, I have some old code from NIB days that I am upgrading to Storyboards and in doing so, the code revisions are causing me some issues.
In the code below:
- (void)audioSound {
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound-file" ofType:#"mp3"];
if(theAudioSound)[theAudioSound release];
theAudioSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudioSound.volume = 0.30;
[theAudioSound play];
}
I get the ARC problem; After many attempts to find a solution I can only find the following advice.
Delete the 'release'
If I do delete the release - depending on how I delete it - I get the following error messages.
from
if(theAudioSound)[theAudioSound release];
to
if(theAudioSound)[theAudioSound];
the Error is "Expected Identifier"
and from
if(theAudioSound)[theAudioSound];
to
if(theAudioSound)theAudioSound;
the Warning is "Expression Result Unused"
if I use the second of the two changes will it work?
and if not; what would I need to do to change the code so that it does work?
Well, release actually releases( decreases the retain count) here, if any object has already has been created. But in ARC, you don't have to release it manually.
I suggest clearing the AVAudioPlayer instance in stead of release, and it will work. So the code will look like:
if(theAudioSound) {
theAudioSound = nil;
}
OR
Simply delete or comment out the line if(theAudioSound)[theAudioSound release]; like:
// if(theAudioSound)[theAudioSound release];
And continue with the rest of codes. Hope this helps.
// if(theAudioSound)[theAudioSound release];
You need to totally comment out that line for this to work.
Actually this is another way of writing following
if(theAudioSound)
{
[theAudioSound release];
}
If you simply delete release, that would generate a syntax error.
"Delete the 'release'" means you don't need to release it. So, you just remove the line or comment in. That's just all I think.
- (void)audioSound {
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound-file" ofType:#"mp3"];
//if(theAudioSound)[theAudioSound release];
theAudioSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudioSound.volume = 0.30;
[theAudioSound play];
}

Appcerator module in Xcode and using simple .wav files

I have an appcelerator module written in Xcode. Everything works, except it throws an error when I try to play a sound file. The code works in Xcode in a standalone app, but not as a module in appcelerator. I am not sure if the sound file is simply not building into the module, or if I have to change the path to something else. Where is the best place to store the sound files? Do I need to adjust the path? Please assist. Below is the playSound method that causes the error.
-(void)playSound:(NSString*)fileName
{
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:#"wav"];
NSURL *soundFileURL = [NSURL fileURLWithPath:path];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
[_audioPlayer play];
}
I think the module you have used in xcode doesnt work in appcelerator. Rather you can get sound file from below code. Hope it helps.
var player = Ti.Media.createSound({url:"sound.wav"});
player.play();

How to access file using pathForResource:ofType:inDirectory

I have an mp3 file in my Supporting Files folder which I would like to play in my app on a loop. I am using the following code to attempt this:
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"smoothjazz" ofType:#"mp3" inDirectory:#"Supporting Files"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops = -1; //infinite
[player play];
However, this returns an error saying:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
How can I access my file in supporting files, and play it as intended? All help appreciated.
EDIT: SOLVED! See my answer for how I did it :)
If Supporting Files folder is the Supporting Files group you see in every Xcode project by default than the inFolder: argument is not needed as Supporting Files is a Xcode grouping and not a real folder. So you should do:
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"smoothjazz"
ofType:#"mp3"];
This should work.
Hope it helps.
May be the path you getting through this will be nil,
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"smoothjazz" ofType:#"mp3" inDirectory:#"Supporting Files"];.
Make sure you properly added the files to your bundle.
And add the proper checks before committing operations, its the best practice. Like follows, Hope this helps you..
// Define NSFileManager and add the proper checks for file existance like as follows.
NSFileManager *filemgr = [NSFileManager defaultManager];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"smoothjazz" ofType:#"mp3" inDirectory:#"Supporting Files"];
if (filemgr fileExistsAtPath:imageURL.absoluteString])
{
// Your code to play the sound file
}
Dan Spag was right - I didn't need to use 'inDirectory:', as it was in the supporting files. But the main problem was that I declared the AVAudioPlayer in the viewDidLoad method, meaning that it's lifespan was only as long as the method (or something along those lines). So I declared the variable as a global variable, and the problem was solved! The music plays.

UIWebView Delegates Not Triggering ? iOS

I am loading a local HTML into a UIWebView as follows :
- (void)viewDidLoad
{
[super viewDidLoad];
//Setup our UIWebView
webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
webView.delegate = self;
webView.scalesPageToFit = YES;
webView.userInteractionEnabled = YES;
[self.view addSubview:webView];
...
[self loadWebPage];
}
- (void)loadWebPage {
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
}
And in the header :
#interface ViewController : UIViewController <UIWebViewDelegate>
However for some reason my webview delegates are not being called :
- (void)webViewDidStartLoad:(UIWebView *)webView {
NSLog(#"Starting HTML Load Process");
}
- (void)webViewDidFinishLoad:(UIWebView *)webViewRef {
NSLog(#"Web View Finished Loading Method");
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(#"Error loading HTML ! %#", error);
}
Can anyone suggest why ?
Thanks !
Called the method [self loadWeb];
But on definition the method is - (void)loadWebPage;
Is it typo?
The only way I can reproduce is this by declaring the webView #property as weak. Can you confirm you are declaring it as a strong reference?
how did you declare your UIWebView instance variable, as a strong or weak? If weak make it strong.
The problem is that this call.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]];
Looks like you're loading the HTML from inside your bundle. This means you need to confirm that all the additional files (.js, .css, and any media files) also need to be present in your bundle.
So the first thing need to check fileURLWithPath: point either it's returning nil or not. If it's not then it means that .html page resolved, however the additional files not resolved as part of the request because it's not placed on the same "index.html" path.
First you need to confirm the directory structure of your "index.html" and all the additional files used inside the page. In order to do that, you have to right click on binary .app in your "build" directory in the finder and then select "Show Package contents".
binary (.app) > right click > Show Package contents
This shows what the app's main bundle contains. Look inside for your HTML file. If it's in a folder, that folder name needs to be in the inDirectory parameter of the pathForResource call. If it's on the top-level then you don't have a folder reference. Either delete & re-drag it into project or use the pathForResource version without inDirectory.
The best way to don't setup the base path or relative path for the resources inside .html page (.js, .css and images) because it don't work. Copy all the additional resources next to "index.html" file so it would be easy to resolve on runtime from bundle.
NSString *path = #"<Index.html Path>";
NSURL *url = [NSURL URLWithString: [path lastPathComponent]
relativeToURL: [NSURL fileURLWithPath: [path stringByDeletingLastPathComponent]
isDirectory: YES]];
Try this
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]isDirectory:NO];

XCode - How to access Data in specific filepaths

I want to access data (xml, to be specific) in different filepaths, depending on some parameters. In short, theres a /Saves/ folder, which contains several other folders (/Save1/, /Save2/, /Save3/, etc). I want to be able to parse.
Lets assume the file I want to access is in the following path:
/../projectname/Saves/Save1/dialogue.xml
Within finder I created the folder substructure and then copied it into my XCode project. That means, these folders exist in the filestructure and not just in XCode.
Afterwards I'm trying to do the following:
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:"#/Saves/Save1/dialogue.xml"];
NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:path];
However, that doesn't seem to work properly. Logging the path variable I get the following:
/Users/<username>/Library/Application Support/iPhone Simulator/5.1/Application/<appcode>/<appname>.app/Saves/Save1/dialogue.xml
Where's my mistake? Thanks in advance for any help.
Please make sure you have added same folder in project target also. One you add the same structure under project target and compile then same folders will be created in your .app file. then you can access it the way you mentioned.
try this:
//NSString *path = [[NSBundle mainBundle] pathForResource:#"dialogue" ofType:#"xml" inDirectory:#"Saves/Save1"];
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Saves/Save1/dialogue.xml"];
if([[NSFileManager defaultManager] fileExitsAtPath:path])
{
NSMutableData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:path];
}
else
{
NSLog(#"File doesnot exits");
}

Resources