Play audio from app, even when it is in the background - xcode

I am having difficulties determining how I would play audio in the background for my iOS app. I have a NSTimer and wish to have a sound be played when it reaches 5 minutes, even when in the background. I already have the audio background mode enabled, but unsure how to accomplish my idea.

Under capabilities select the following:
In your plist make sure where it says "Application does not run in background" is NO.
Then add the following to your your appDelegate.m file.
NSError *sessionError = nil;
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&sessionError];
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
In the following method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}

Related

How do I add background music to my spritekit file

Could someone give me a quick easy step by step to adding background m4a music once my app has loaded. It is a sprite kit Xcode file, and the music is in m4a format. Thanks
Try with this:
#import AVFoundation;
...
AVAudioPlayer * backgroundMusicPlayer;
NSError *error;
NSURL * backgroundMusicURL = [[NSBundle mainBundle] URLForResource:#"song" withExtension:#"m4a"];
backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
backgroundMusicPlayer.numberOfLoops = -1; //-1 = infinite loop
[backgroundMusicPlayer prepareToPlay];
[backgroundMusicPlayer play];
and to stop simply
[backgroundMusicPlayer stop];
note: I don't use SKAction to play background music because you can't stop it when you want
You can use AVAudioPlayer for this purpose:
In your .h:
#import <AVFoundation/AVFoundation.h>
and add the following to interface
AVAudioPlayer *player;
In .m, initialize player with audio oath url:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"bg_music"
ofType:#"mp3"]];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
player.numberOfLoops = -1;
and when you need to play the audio, you can call:
[player play];
Note:
"numberOfLoops" is the number of times that the sound will return to the beginning upon reaching the end.
A value of zero means to play the sound just once.
A value of one will result in playing the sound twice, and so on...
Any negative number will loop indefinitely until stopped.
Keep Coding................ :)

How to get the frame (origin, Size) of every visible windows on the active space?

I'm trying to figure out how to get the frame of all visible windows.
I tried the following code, but it only works for the app itself other windows report {0,0,0,0}
NSArray *windowArray = [NSWindow windowNumbersWithOptions:NSWindowNumberListAllApplications | NSWindowNumberListAllSpaces];
for(NSNumber *number in windowArray){
NSLog(#"Window number: %#", number);
NSWindow *window = [[NSApplication sharedApplication] windowWithWindowNumber:[number intValue]];
NSLog(#"Window: %#", NSStringFromRect( [[window contentView] frame]));
}
Sample code is appreciated.
I figured it out:
NSMutableArray *windows = (__bridge NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
for (NSDictionary *window in windows) {
NSString *name = [window objectForKey:#"kCGWindowName" ];
CGRect bounds;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:#"kCGWindowBounds"], &bounds);
NSLog(#"%#: %#",name,NSStringFromRect(bounds));
}
You can't create an NSWindow for a window of another application. In general, you can't access the objects of other applications except through an interface that they cooperate with, like scripting.
You can get what you're looking for using the Quartz Window Services (a.k.a. CGWindowList) API.
I'm not at all sure that the window numbers returned by Cocoa are the same as the window numbers used by that API. In fact, the docs for -[NSWindow windowNumber] specifically say "note that this isn’t the same as the global window number assigned by the window server". I'm note sure to what use you can put the window numbers returned by +[NSWindow windowNumbersWithOptions:] which are not for your application's windows.

MPMoviePlayerController doesn't work after upgrading to iOS 5

This code works perfectly on iPad 4.3 Simulator:
NSString *source = [mediaObject objectForKey:#"source"];
NSString *videoPath = [NSString stringWithFormat:#"%#/%#", path, source];
NSURL *videoUrl = [NSURL fileURLWithPath:videoPath];
MPMoviePlayerController *videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoUrl];
videoPlayer.shouldAutoplay = NO;
videoPlayer.view.frame = CGRectMake(xPos, yPos, width, height);
[backgroundImageView addSubview:videoPlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoPlaybackStateDidChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:videoPlayer];
but it doesn't work on iPad 5 Simulator. I get a black frame with no movie nor playback controls.
I read the Apple changelog about MPMoviePlayerController, but I didn't found anything about this problem. Can you help me?
I solved the problem in this way: in my header file I wrote:
MPMoviePlayerController *moviePlayer;
with this property:
#property(nonatomic, strong) MPMoviePlayerController *moviePlayer;
and in the method in which I init the moviePlayer:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:movieUrl];
self.moviePlayer = player;
It seems that assigning the player to a property "saves" the player. But don't ask me why...
You don't mention what type of URL you are trying to play, however, if it's an HTTP Live Streaming resource (.m3u8 file), then be aware that iOS 5.0 seems to have tightened up on validating the contents of the m3u8 index file.
Specifically, I've discovered that:
No individual segment can be more than twice as long as the #EXT-X-TARGETDURATION value;
The #EXTINF value (segment length in seconds) can, now, only be an integer value.
If one of these is your problem, running your application under the iOS 5.0 simulator should show a warning in the debugger console.
For HLS on iOS5, the TARGETDURATION value is really not the target duration but needs to be the maximum duration. So it should be set to the largest segment in the file.

Thread 1: Program received signal:"Sigbart 1"

When I run the app in the iPhone Simulator, everything works just fine .. but with time I'll try to get my iPhone
Thread 1: Application Received
signal:" Sigbart 1"
why?
Here is the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
golfbaner *detailViewController = [[golfbaner alloc] initWithNibName:#"Golfbaner" bundle:nil];
detailViewController.golf = [banenavn objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
XCode says it's HERE:
[self.navigationController pushViewController:detailViewController animated:YES];
it goes wrong
I can admit that I'm quite a beginner.... lol
seems to be u are new bee.so here i assume u would be created the golfbaner with nib file .so it would be same as filename for nibname.
Golfbaner.NIB is not with your project.//check out this
maybe like golfbaner.NIB
so use
golfbaner *detailViewController = [[golfbaner alloc] initWithNibName:#"golfbaner" bundle:nil];
Most likely is that detailViewController is nil. If you look at the console output it will tell you for certain.
The reason its nil on hardware is that the file system is case sensitive on hardware and hence
golfbaner *detailViewController = [[golfbaner alloc] initWithNibName:#"Golfbaner" bundle:nil];
"Golfbaner" != "golfbaner"
Check your nibname for case match. I suspect its "golfbaner.xib".
See iOS Objective-C Image file name/path different behavior betwewen simulator and device
As a style point class names should be capitalised otherwise it makes a class hard to separate from a variable when reading code.
It may be spelling mistake after #"Golfbaner"
just copy nibfile name and paste it.

How to gradually retrieve data from NSTask?

I am working on a GUI (Cocoa) for a command-line tool to make it more accessible to people. Despite it being a GUI, I would like to display the output to an NSTextView. The problem is that the output is large and the analysis the tool carries out can take hours/days.
Normally, when working with NSTask and NSPipe, the output is displayed only after the task is completely finished (which can take a long time). What I want to do is split the output up and display it gradually (updating every minute for example).
So far I have placed the processing of the data in a separate thread:
[NSThread detachNewThreadSelector:#selector(processData:) toTarget:self withObject:raxmlHandle];
- (void)processData:(id)sender {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *startString = [results string];
NSString *newString = [[NSString alloc] initWithData:[raxmlHandle readDataToEndOfFile] encoding:NSASCIIStringEncoding];
[results setString:[startString stringByAppendingString:newString]];
[startString release];
[newString release];
[pool release];
}
All this is still a bit of voodoo to me and I am not exactly sure how to deal with this challenge.
Do you have any suggestions or recommendations?
Thanks!
You need to use a notification provided by NSFileHandle.
First, add yourself as an observer to the NSFileHandleReadCompletionNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(outputReceived:)
name:NSFileHandleReadCompletionNotification
object:nil];
Then, prepare a task, call readInBackgrounAndNotify of the file handle of the pipe, and launch the task.
NSTask*task=[[NSTask alloc] init];
[task setLaunchPath:...];
NSPipe*pipe=[NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:pipe];
// this causes the notification to be fired when the data is available
[[pipe fileHandleForReading] readInBackgroundAndNotify];
[task launch];
Now, to actually receive the data, you need to define a method
-(void)outputReceived:(NSNotification*)notification{
NSFileHandle*fh=[notification object];
// it might be good to check that this file handle is the one you want to read
...
NSData*d=[[aNotification userInfo] objectForKey:#"NSFileHandleNotificationDataItem"];
... do something with data ...
}
You might want to read Notification Programming Topics to understand what is going on.

Resources