Using Google-Mobile-Ads-SDK 7.68, users can't close GADInterstitial, the close button is upper the safe area (user interaction is not permitted here) :
It's happening at least on iPhone 12 pro and iPhone 12 pro max.
What I tried :
GADInterstitial *interstitial = [[GADInterstitial alloc] initWithAdUnitID:#"xxx"];
GADRequest *request = [GADRequest request];
[interstitial loadRequest:request];
Hiding status bar let the user click on the close button. Ugly deprecated method, but it's working for now.
/// Tells the delegate that an interstitial will be presented.
- (void)interstitialWillPresentScreen:(GADInterstitial *)ad {
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
/// Tells the delegate an ad request failed.
- (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error {
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
/// Tells the delegate the interstitial is to be animated off the screen.
- (void)interstitialWillDismissScreen:(GADInterstitial *)ad {
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
/// Tells the delegate that a user click will open another app
/// (such as the App Store), backgrounding the current app.
- (void)interstitialWillLeaveApplication:(GADInterstitial *)ad {
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
Related
I have implemented iBeacon Notification in iOS 10 using objective-c. Can some one help me solve this problem to get the iBeacon in background mode in ios 10?
Even if the app is not running, location events (related to the beacons in this case) are handled the same way as any other app launching events. Every time a phone enters or exits a region while the app is terminated, it will be automatically launched.
application:didFinishLaunchingWithOptions: method (of AppDelegate class) is called with UIApplicationLaunchOptionsLocationKey key existing in launchOptions parameter.
When you verify this key exists (so location was the reason that your app was launched) you should create new instance of ESTBeaconManager class, set delegate to AppDelegate object (or any other object that is working as ESTBeaconManagerDelegate and was created before this event occurred) and start monitoring.
Region you are passing to the startMonitoringForRegion: method is not important, as ESTBeaconManager delegate will receive the most recent region information. You can just pick any of the ones your app registered in iOS. After Monitoring is revoked, app will automatically receive most recent entered/exited region event in beaconManager:didEnterRegion: or beaconManager:didExitRegion: method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([launchOptions objectForKey:#"UIApplicationLaunchOptionsLocationKey"])
{
self.beaconManager = [ESTBeaconManager new];
self.beaconManager.delegate = self;
// don't forget the NSLocationAlwaysUsageDescription in your Info.plist
[self.beaconManager requestAlwaysAuthorization];
[self.beaconManager startMonitoringForRegion:[[ESTBeaconRegion alloc]
initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID
identifier:#"AppRegion"]];
}
return YES;
}
-(void)beaconManager:(ESTBeaconManager *)manager didEnterRegion:(ESTBeaconRegion *)region
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"Enter region";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
-(void)beaconManager:(ESTBeaconManager *)manager didExitRegion:(ESTBeaconRegion *)region
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"Exit region";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
When an app launches for the first time, it will ask the user for permission to send local notifications.
If the user denies the permission at launch, how do we ask for permission again in the future?
For example, is there a way that on a button click, I can request permission again?
Here is my code to initially ask for permission at launch:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// are you running on iOS8?
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)])
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
else // iOS 7 or earlier
{
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
}
If for the first time you have disallowed local notification and on the second time use the blow mentioned code:
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)]
{
UIUserNotificationSettings *grantedSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (grantedSettings.types == UIUserNotificationTypeNone)
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"app-settings:"]];
}
}
This will open your application settings where you can find the settings to enable/disable local notification and other settings.
Hope this helps!
You can not request the system prompt again. You can detect a situation in which the access was denied and show an alert yourself or show the button that will open settings app to make the process of changing the setting easier for the user.
These codes will be called when a page loads.
UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
Now I would like to present the next view controller as soon as the user handles the alert. Is it possible? Any help will be greatly appreciated.
Thanks.
Update
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(go)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (IBAction)buttonPressed:(id)sender
{
UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
- (void)go
{
TutorialViewController *tvc = [[TutorialViewController alloc] init];
[self presentViewController:tvc animated:YES completion:nil];
}
This seems to work. I'm wondering if the code will be efficient?
It's a bit tricky, but it's possible. The alert for notification permissions is a system alert, which means your app resigns active when it's shown, and you get a application:didBecomeActive call when the user dismisses it.
So the basic technique is to set a flag in your app delegate when you're about to trigger the alert. In your application:didBecomeActive implementation, check the flag and perform whatever work you need to do.
This is not 100% foolproof, as the app might be resigning active for a different reason. You can mitigate some of this by also tracking whether the app went to the background after resigning active. You should also be sure that the alert will be shown when you ask for permissions. If the user has previously answered, no alert is shown.
When The App is brought into running state via Notifications..This method is fired
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
You can then retrieve the notification received from the launchOptions dictionary and open the appropriate screen.
Hope this helps.
I'm using storyboard for my sample project. The architecture is Login View Controller and Home PageView controller. User clicks on button in Home PageView controller to start local notification.
-(IBAction)startLocalNotification { // Bind this method to UIButton action
NSLog(#"startLocalNotification");
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:7];
notification.alertBody = #"This is local notification!";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
notification.applicationIconBadgeNumber = 10;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
This code goes in AppDelegate file :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
[launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
// Override point for customization after application launch.
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
NSLog(#"didReceiveLocalNotification");
}
Now after pushing app to background state I'm getting below message in console but local notification is working fine as expected.
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
What this message is related to?
I have what I believe could just about stand up as an 'answer'... And that is that there's almost certainly nothing wrong, but maybe a problem with iOS (8.1.3/8.2). As far as I can tell, it's innocuous.
I played around with this and found that it was related to UITextField/Keyboard.
So a single view app with just a text field, follow the steps below (only tried on iPad):
Build and run
Put focus in text field
Close keyboard (it should have opened)
Click home button (app enters background)
Return to app
Click home button (app enters background)
Observe log output.
Here's a sample project: https://github.com/duttski/TestForStrangeSnapshotMessage .
Filed as a bug and trying to get some information through the dev forums too.
UPDATE: I think this may be fixed in later versions. But I haven't tested it. After speaking on the dev forums I was told that this isn't something to worry about.
"Attempting to schedule a local notification UIConcreteLocalNotification: with a sound but haven't received permission from the user to play sounds"
- (void)registerForRemoteNotifications
{
if ([[UIApplication sharedApplication] respondsToSelector:#selector(isRegisteredForRemoteNotifications)]) {
// iOS 8 Notifications
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge) categories:nil]];
} else{
// iOS < 8 Notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIUserNotificationTypeAlert)];
}
}
//added for ios8
- (void)successfullyRegisteredUserNotificationSettings
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
I followed the guide of other users in stackoverflow to use registerUserNotificationSettings for ios8. After invoking the function, I wait for the callback in AppDelegate:
- (void)application:didRegisterUserNotificationSettings:
In the function, I call my successfullyRegisteredUserNotificationSettings method above to formally register.
Even after doing this, I still get the error. Can someone tell me why? Or has anyone encountered the same issue? How can this be solved?