I have looked around, and I can't seem to find out how to resume audio when the app enters background in iOS 8. This is what's in my app Delegate:
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
[[AVAudioSession sharedInstance] setActive:NO error:nil];
SKView *view = (SKView *)self.window.rootViewController.view;
view.paused = YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[[AVAudioSession sharedInstance] setActive:YES error:nil];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
SKView *view = (SKView *)self.window.rootViewController.view;
view.paused = NO;
[[AVAudioSession sharedInstance] setActive:YES error:nil];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
The problem is that when the app enters background, the audio doesn't resume playing in ios 8. It returns this error:
ERROR:
[0x35ad49dc] AVAudioSession.mm:646: -[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
This problem doesn't exist in ios7. The Audio plays as an SKAction like this:
SKAction *music = [SKAction playSoundFileNamed:#"new music.mp3" waitForCompletion:NO];
[[self scene] runAction:music];
Can someone please tell me how to properly pause and resume audio in iOS8?
Related
I used the following code to create a blur effect and it worked fine on iOS 10, but it stopped working on iOS 11.I am not able to view the blur when app moves to background.When the app comes to foreground, some times,the blur stays alwaysand the application no longer works,only way to make it work is by relaunching the app.
Is there any work around for this for iOS 11 ?
-(void)addBlurEffect{
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
blurEffectView.frame = window.frame;
blurEffectView.tag = 4444;
[window addSubview:blurEffectView];
}
-(void)removeBlurEffect{
NSArray *allWindows = [[UIApplication sharedApplication] windows];
for (UIWindow * aWindow in allWindows) {
UIView *blurEffectView = [aWindow viewWithTag:4444];
if (blurEffectView){
[blurEffectView removeFromSuperview];
}
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self addBlurEffect];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self removeBlurEffect];
}
This happens because you are doing it in the WRONG delegates the entire time. You need to read the documentation or the comments in AppDelegate on what each method does..
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
[self addBlurEffect];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
[self removeBlurEffect];
}
So think of the two methods above as "pausing" or "unpausing" a game.. When a game goes in the background or gets interrupted, typically you pause it for the user so they don't lose progress or die or something while it's in the background state or transitioning state (IE: The task manager state).
Then when they resume and the app is on screen, you unpause it. This would require refreshing and invalidation of graphics.. Which the two methods above handle..
However, you were doing it in:
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
This method is for saving states and cleaning up.. not modifying UI.. IE: Storing stuff in a database or syncing the user settings to disk or something or releasing memory.. User can potentially kill the app in this state or the system can kill it too.
This only gets called when the application is actually minimized (minimized/background state is NOT the same as task-switcher state/in-active state!).. iOS 11 has a different transition so now we actually see the difference I guess..
If you move your code into active state handlers, it works 100% fine..
I've migrated 9 iOS Hybrid apps from MobileFirst 6.3 to MobileFirst 7.1 using MobileFirst Studio. 4 of the apps work fine. But the other 5, the UI is unresponsive to clicks. As part of the automated migration process, the headers of these 5 apps (only) were changed to reference the new WLAppDelegate interface. Strangely I've noticed that if I switch my AppName.h file from extending WLAppDelegate back to extending the original WLCordovaAppDelegate everything works fine. Why? I'd love to move off this deprecated code to your new WLAppDelegate interface.
My header and .m file match the defaults generated by MobileFirst Studio 7.1 when you request a new iOS app so it must be something else.
Here's my non-working .h and .m file
//
// MyAppDelegate.h
//
//
#import <IBMMobileFirstPlatformFoundationHybrid/IBMMobileFirstPlatformFoundationHybrid.h>
#interface MyAppDelegate : WLAppDelegate <WLInitWebFrameworkDelegate> {
}
#end
//
// MyAppDelegate.m
// IssuesReturns
//
//
#import "IssuesReturns.h"
#import <IBMMobileFirstPlatformFoundationHybrid/IBMMobileFirstPlatformFoundationHybrid.h>
#import "CDVMainViewController.h"
#implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL result = [super application:application didFinishLaunchingWithOptions:launchOptions];
// A root view controller must be created in application:didFinishLaunchingWithOptions:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController* rootViewController = [[UIViewController alloc] init];
[self.window setRootViewController:rootViewController];
[self.window makeKeyAndVisible];
[[WL sharedInstance] showSplashScreen];
// By default splash screen will be automatically hidden once Worklight JavaScript framework is complete.
// To override this behaviour set autoHideSplash property in initOptions.js to false and use WL.App.hideSplashScreen() API.
[[WL sharedInstance] initializeWebFrameworkWithDelegate:self];
return result;
}
// This method is called after the WL web framework initialization is complete and web resources are ready to be used.
-(void)wlInitWebFrameworkDidCompleteWithResult:(WLWebFrameworkInitResult *)result
{
if ([result statusCode] == WLWebFrameworkInitResultSuccess) {
[self wlInitDidCompleteSuccessfully];
} else {
[self wlInitDidFailWithResult:result];
}
}
-(void)wlInitDidCompleteSuccessfully
{
UIViewController* rootViewController = self.window.rootViewController;
// Create a Cordova View Controller
CDVMainViewController* cordovaViewController = [[CDVMainViewController alloc] init] ;
cordovaViewController.startPage = [[WL sharedInstance] mainHtmlFilePath];
// Adjust the Cordova view controller view frame to match its parent view bounds
cordovaViewController.view.frame = rootViewController.view.bounds;
// Display the Cordova view
[rootViewController addChildViewController:cordovaViewController];
[rootViewController.view addSubview:cordovaViewController.view];
[cordovaViewController didMoveToParentViewController:rootViewController];
}
-(void)wlInitDidFailWithResult:(WLWebFrameworkInitResult *)result
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"ERROR"
message:[result message]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
WLCordovaAppDelegate is a deprecated compatibility API to allow easier migration of pre v6.2 apps to 6.2+ apps. It can be used but the recommendation is to use WLAppDelegate.
I have a problem during I developing application IOS and I used Parse Push Notification Framework for push remote notification. the problem is when the application is running and the same time the notification has been sent, the application is display modal alert box automatically. So, I don't want the modal alert display. I spent much times on it, and I do research on internet, read documents but no result found, I feel nobody knew about this. Please Help me!
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIImage *navBackgroundImage = [UIImage imageNamed:#"nav_bg_new"];
[[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}];
// ****************************************************************************
// Uncomment and fill in with your Parse credentials:
// [Parse setApplicationId:#"your_application_id" clientKey:#"your_client_key"];
// ****************************************************************************
[Parse setApplicationId:#"my_app_id" clientKey:#"my_client_key"];
// Override point for customization after application launch.
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
currentInstallation.channels = #[#"global"];
[currentInstallation saveInBackground];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
if (error.code == 3010) {
NSLog(#"Push notifications are not supported in the iOS Simulator.");
} else {
// show some alert or otherwise handle the failure to register. NSLog(#"application:didFailToRegisterForRemoteNotificationsWithError: %#", error);
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
}
Thanks so much in advance.
If you only want to make sure you DO NOT see notifications when the app is opening, set a BOOL isOpening to TRUE in your application:willFinishLaunchingWithOptions: and set it to FALSE during application:didFinishingLaunchingWithOptions:, then change the behavior of didReceiveRemoteNotification: and the call to PFPush handlePush: accordingly.
You can try this instead:
#property (nonatomic, assign) BOOL isLaunching;
- (void)applicationWillEnterForeground:(UIApplication *)application
{
isLaunching = TRUE;
}
- (void)applicationDidEnterForeground:(UIApplication *)application
{
isLaunching = FALSE;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (!isLaunching) {
//Only fire the push handler if the application isn't active
[PFPush handlePush:userInfo];
}
}
#import "AppDelegate.h"
#import "Scringo/scringo.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
[Scringo initWithAppId:#"" completion:nil];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
--
Is this the correct spot? the sidebar doesn't slide out in the emulator and I'm not getting any errors?… help
Use before return statement,
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Scringo initWithAppId:#"YOUR_SCRINGO_APP_ID" completion:nil];
// Override point for customization after application launch.
return YES;
}
I am new to Objective-C and I'm making my first app, a single-view app. When I run my program ,the fullscreen ad that is supposed to appear (I'm using RevMob) appears. However, when I exit the ad I get a black screen with a blue status bar at the top.
I have tried many things, such as setting my main view controller as initial view controller, restarting my computer, changing/removing debugger, resetting the iOS simulator, etc.
My Xcode version is 4.6 and my OS is mac OSX 10.8.4
I don't want to delete Xcode and I also don't want to remove ads because that is my only source of income.
Here is my code:
Appdelegate.m
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
[RevMobAds startSessionWithAppID:#"myappid"];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
RevMobFullscreen *ad = [[RevMobAds session] fullscreen];
[ad loadWithSuccessHandler:^(RevMobFullscreen *fs) {
[fs showAd];
NSLog(#"Ad loaded");
} andLoadFailHandler:^(RevMobFullscreen *fs, NSError *error) {
NSLog(#"Ad error: %#",error);
} onClickHandler:^{
NSLog(#"Ad clicked");
} onCloseHandler:^{
NSLog(#"Ad closed");
}];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (void)dealloc
{
[_window release];
[super dealloc];
}
#end
Appdelegate.h:
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic)UIWindow *window;
#end
There is nothing wrong with the ad code. What seems to be (not) happening is that your app has no content. I suspect that you haven't set up the rootViewController (initial view controller) for the app correctly.
This is what you need to do:
Get rid of all of the app ad code and just make an app that works. All it has to do is correctly show an initial view controller. You could just make a new project in XCode using the Single View Application template.
Add your app code as per this example. You will invoke the code from your initial view controller via a button.
Once that is working, you can add the code into - (void)applicationDidBecomeActive:(UIApplication *)application as per your question. When you dismiss the advert, you should see your initial view controller.