Stopping the background music at another UIViewController - objective-c

This may be a basic question but I'm a newby at IOS development..
I need a background music for my iPad application and I need to stop it at another UIViewController. I Start my background music just like that at my MainMenuViewController.m file
NSString* pathToBackGroundMusic = [[NSBundle mainBundle] pathForResource:#"MenuBackGround" ofType:#"mp3"];
backGroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:pathToBackGroundMusic] error:nil];
backGroundMusic.numberOfLoops = -1;
[backGroundMusic play];
Now i need to stop it when I press a button at an another UIVIewController CustomGameMenuViewController.m... I'm sorry if it is already answered but i couldn't find it... Any help will be appreciated. Thanks.

There are a couple of ways to do this. The simplest way would be to use NSNotifications. Look up the documentation on NSNotification and NSNotificationCenter. With this method the original view controller would register to listen for a certain notification and your other controller would send that notification when it needed to stop music.
Another route would be to set up the first view controller as a delegate or property of the second one. This is a little more involved and convoluted. If this is the only communication back and forth between these controllers I would go the notification route.

Related

MPMoviePlayerController Background playing

Okay guys i have a problem. I'm stream MPMoviePlayerController and i want it to play audio in background and i've somewhat achieved this.
This is what i do in my -didFinishLaunchingWithOptions:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
Now whenever the application calls -applicationWillResignActive:
i do a post notification to continue the playback. And this works but it's an ugly fix. As there is a second delay between the sound stopping and the notification being called. So the playback stops for a second and then continues again by calling the notification which just says [viewPlayer play];
And many other have achieved smooth background playback. Like spotify or other apps whenever you enter background mode there is no sound lag/clipping in sound. This is really annoying to listen to whenever i press the home button or lock the phone.
Yes i did set the background mode for playback.
I have also tried -applicationDidEnterBackground: but this notification is even slower. It comes after -applicationWillResignActive:
I have no idea how to fix this, and or how others achieved it. I have looked through almost all other similar questions. None have my problem.
Thanks in advance.
I've recently used a framework to stream YouTube video inline in a UIView. This framework has a category on MPMoviePlayerController which works pretty well. You notice a change in the music when going to background but it is still acceptable.
The category can be found here:
MPMoviePlayerController+BackgroundPlayback.h
MPMoviePlayerController+BackgroundPlayback.m

Navigate to a specific UIViewController after receiving a NSNotification

I am developing an iOS application that handles a hierarchy of UIViewController objects using a UINavigationController:
MenuViewController
|
|-ListOfAnimalsViewController
|
|-AnimalDetailsViewController
|
|-ListOfPlantsViewController
|
|-PlantDetailsViewController
The application receives local NSNotification objects with information of a certain animal or plant. The usual behavior when you touch the notification is to open the application and load the first view controller in hierarchy.
Is there a way of programmatically navigating to an instance of a UIViewController deep in the hierarchy instead?
EDIT: I am not asking for pushing the controller into the navigation stack, but for pushing the previous controllers as well, i.e. I would like to keep the navigation schema above.
I'm gonna have to disagree with Suresh. While this solution may work in a simple case like this where you only have 1 previous ViewController, what if you wanted to add a 10th ViewController and keep the entire hierarchy? First of all you'd have to pass the final piece of data you want to show (in this case the plant or animal) through every ViewController and you'd be creating 10 ViewControllers at once. The transition between the current ViewController and the 10th would be far from seamless, performance would be terrible. Also no need to go and create your own navigation system, no need to make things more complicated than they are since this issue isn't too difficult.
Just push the ViewController you want to show, that way you'll only be creating 1 ViewController. In every ViewController that can be pushed as a result of a notification (and all the ones below that), override the behavior of the back button. Check in the viewControllers property of the navigationController if the ViewController before is is the one you expect, using NSStringFromClass. If not, create an NSMutableArray as a copy of the viewControllers, create the ViewController you do expect and insert it at the second to last spot in the array. Then replace the entire stack by calling the setViewControllers:animated: method on the navigationController with the mutable array, animated NO. Finally do the pop. Again you'll have created just 1 ViewController at a time, keeping your performance optimal.
Ican't post code right now since I'm on an iPad but if you need it, just ask and I'll add an example when i have a real keyboard.
If you know the name of the class you can use the following code to navigate.
NSString *className = #"viewControllerName";
UIViewController* myClass = (UIViewController*)[[NSClassFromString(className) alloc] init];
[self.navigationController pushViewController:myClass animated:YES];
I think you will have to invent your own mechanism for following the navigation order since there's nothing in an iOS view controller's static definition that defines an ordering. (Segues seem to be as close as it gets and that's not very close.)
If I had to do this for a hierarchy of view controllers with some unknown depth, I'd consider creating a superclass that worked with a path, sort of like network routing. It would have a method such as displayNextControllerOnPath:(NSString *)path. A MenuViewController that was a RoutingController subclass would receive a path like #"ListOfAnimalsViewController.AnimalDetailsViewController", strip off the first path element, instantiate it (it being another RoutingController subclass), and send it #"AnimalDetailsViewController".
Other details would involve knowing when to stop and perhaps passing an object or dictionary as a payload for the last controller to use as content.
I would reconstruct the stack in the following way:
MenuViewController *menuController = [[MenuViewController alloc] init];
ListOfAnimalsViewController *listController = [[ListOfAnimalsViewController alloc] init];
AnimalDetailsViewController *detailsController = [[AnimalDetailsViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] init];
[navigationController setViewControllers:#[menuController, listController, detailsController]];
self.window.rootViewController = navigationController;
You may need to set some properties to based on your implementations.

objective c iphone musicplayer crashing

I am creating a non appstore jailbreak tweak and I came across a problem that causes my app to crash.
I am using musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
the music player has complete functionality, play/pause, next, previous. it displays the title of the song, the artist, the artwork and everything.
the problem seems to be the loading and unloading of the musicplayer.
for example, if i am running the app, and i close the iphone's Music app, it will cause my app to crash. also if i load the app without the Music app running in the background it will crash.
as long as the music app is running in the background my app will not crash.
can anyone help me with this?
is something to be set to nil? or how do i go about releasing them?
should they be synthesize/property?
I was having this problem also for my tweak, and I couldn't figure out a way to fix it. I ended up using the AVPlayer Method, It seems to work well for me. Granted I only need to play one song, so if you need to play a playlist of some sorts you are out of luck.
I used it like the following in the mediapickerclass:
NSURL *url = [[mediaItemCollection.items objectAtIndex: 0] valueForProperty:MPMediaItemPropertyAssetURL]
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
[player play];
If you need you need to reference it from somewhere else you can just write the url to a .plist

Using AppDelegate method in ViewController

NOTE: Problem Solved. Thanks
I'm simply a high school student on a brand new app developer program. So, please excuse me seeming like I know very little, as, I really don't know as much as I will yet. Bear with me XD
I need to use the following startup from AppDelegate to display a start screen for the webView in my application, rather than a blank white screen:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// THIS SECTION IS WHAT I NEED
NSURL *url = [NSURL URLWithString:#"http://www.earlham.k12.ia.us"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
return YES;
}
To use that, however, I need access to webView, which is my WebView object that I declared in ViewController.h. However, that doesn't work, because I can't declare it twice, nor use it from the other header file, to my knowledge. I know it's possible, but at this basic level, I don't know how. Please include code examples.
Many thanks!
Why would you put this in the application delegate? This looks like something the actual ViewController should be able to handle.
The instance of UIWebView should only be managed by its containing UIViewController. The app delegate is responsible for getting the view controller on screen as a subview of the window. From there, it is the view controllers responsibility to manage the web view appropriately.
I agree with the other answers that this code should belong in the view controller, not in the app delegate.
If you do want to access code in your app delegate, you'll have to create a method containing the code you want and call that from your view controller (since you don't want to be calling didFinishLaunchingWithOptions yourself, it gets called for you at the right time).
In general though, it's better to separate out responsibility in your code and not put general code in your app delegate.

Best way to wait app Launch

I have an app that requests from the server some data on xml type. Ok, it does ok.
But seems this action loads a little the app on launching.
TBXML *tbxml = nil;
tbxml = [[TBXML tbxmlWithURL:[NSURLURLWithString:#"http://www.someplace.com/test/test.xml"]] retain];
So, what i figured is make the app wait to launch completely to do this action. So, i've search for it, and find two ways.
applicationDidFinishLaunching;
awakeFromNib;
I dont know if this is the correct way to do this. So, im open to suggestions.
Thanks!
First, I would suggest you to put that XML loading code in a separate thread using NSOperationQueue or NSThread so that it won't block the main thread.
applicationDidFinishLaunching, IMHO, should be used to initialize your RootViewController, handle incoming push notifications, local notifications, etc. Use viewDidLoad in RootViewController for your purpose.