I'm experimenting with an WatchKit app that will trigger an audio alert on the iphone. I've got it setup to do the trigger, repeating every 5 seconds. On the iphone, I have the logic that will play the short audio wav file in the background. It is designed to work even if the app is minimized and play the audio. I've tested that stand-alone on the iphone, to work fine.
The step that is not working is the trigger on the watch to tell the parent Iphone app to play the audio. It mostly works, except that the 2 second audio alert is clipped at perhaps .5 seconds. It plays a chirp of the first part and is cut off. Each time I trigger it, it will do this clipped chirp of the entire wav sound.
The reply from the parent app comes across okay, and I'm wondering if as soon as that reply comes back all background processing is cut off entirely.
I have background-mode for Audio enabled in the application.
How can I get the watch to trigger the app to play the entire audio alert in the background?
// WatchApp InterfaceController
- (void)pingIphone {
[WKInterfaceController openParentApplication:@{@"requestString":@"findphone"} reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(@"\nReply info: %@\nError: %@",replyInfo, error);
}];
}
// Iphone AppDelegate
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString * request = [userInfo objectForKey:@"requestString"];
NSDictionary * replyContent = @{@"state":(application.applicationState == UIApplicationStateBackground ? @"back" : @"not back")};
if ([request isEqualToString:@"findphone"]){
ViewController *vc = [[ViewController alloc] init];
[vc pingIphone];
}
reply(replyContent);
}
// Iphone ViewController
@property (strong, nonatomic) AVQueuePlayer *player;
- (void)viewDidLoad {
[super viewDidLoad];
// get device's default audio level on start
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
Float32 volume;
UInt32 dataSize = sizeof(Float32);
AudioSessionGetProperty (
kAudioSessionProperty_CurrentHardwareOutputVolume,
&dataSize,
&volume
);
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew context:nil];
}
(void)pingIphone {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults boolForKey:@"vibrate_bool"] == YES){
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
for(int i = 0; i < 5; i++){
[_player insertItem:[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"alarm" withExtension:@"wav"]] afterItem:nil];
}
//NSLog(@"volume: %f",[userDefaults floatForKey:@"volume"]);
if (!(_player.rate > 0 && !_player.error)) {
[self startAudio];
}
}
- (void)startAudio {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
NSString* path = [[NSBundle mainBundle] pathForResource:@"alarm" ofType:@"wav"];
_player = [[AVQueuePlayer alloc] init];
for(int i = 0; i < 5; i++){
[_player insertItem:[AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:path]] afterItem:nil];
}
_player.volume = [userDefaults floatForKey:@"volume"];
[_player play];
if (setCategoryError)
NSLog(@"Error setting category! %@", setCategoryError);
}