Ask for Permission for Remote Notifications in iOS 8 - ios

I'm adding remote notifications with ArenaDeamons, but I'm getting an error (MY APP KEY is my private key):
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
BDArenaConnector.initializeWithAppKey("MY APP KEY", runInSandboxEnvironment: true)
BDArenaConnector.getInstance().requestAuth()
// register for remote notifications
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings.settingsForTypes((UIUserNotificationTypeSound|UIUserNotificationTypeAlert|UIUserNotificationTypeBadge), categories: nil))
UIApplication.sharedApplication().registerForRemoteNotifications()
BDArenaConnector.getInstance().pushConnector.feedbackServiceDidFinishLaunchingWithOptions(launchOptions)
return true
UINavigationBar.appearance().barTintColor = UIColor.redColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
UIBarButtonItem.appearance().tintColor = UIColor.blueColor()
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
return true
}
Error1: use of unresolved identifier 'UIUserNotificationTypeBadge'
Error2: use of unresolved identifier 'UIUserNotificationTypeSound'
Error3: use of unresolved identifier 'UIUserNotificationTypeAlert'
I also have some errors here:
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("UIApplication : didFailToRegisterForRemoteNotificationsWithError : \(error.localizedDescription)")
var alert: UIAlertController = UIAlertController(title: "did Fail To Register For Remote Notifications", message: error.localizedDescription(), preferredStyle: UIAlertControllerStyleAlert)
var okAction: UIAlertAction = UIAlertAction.actionWithTitle("Ok!", style: UIAlertActionStyleDefault, handler: { (action: UIAlertAction) in
})
alert.addAction(okAction)
self.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
}
Error1: use of unresolved identifier 'UIalertcontrollerstylealert'
Error2: use of unresolved identifier 'UIalertactionstyledefault'
How Can I fix it? The app is in Swift 2.

For ios 8 and above, you can use registerUserNotificationSettings,
try this code, i have not tested it but, it will help you for sure.
let types = UIUserNotificationType.Badge.union(UIUserNotificationType.Alert).union(UIUserNotificationType.Sound)
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: types, categories: nil))
UIApplication.sharedApplication().registerForRemoteNotifications()
Fix for Error 3
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("UIApplication : didFailToRegisterForRemoteNotificationsWithError : \(error.localizedDescription)")
let alert: UIAlertController = UIAlertController(title: "did Fail To Register For Remote Notifications", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)
let okAction: UIAlertAction = UIAlertAction(title: "Ok!", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction) in
})
alert.addAction(okAction)
self.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
}

Fixed in part. Now I have only 2 errors. Thanks Prabhu.Somasundaram.
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("UIApplication : didFailToRegisterForRemoteNotificationsWithError : \(error.localizedDescription)")
let alert: UIAlertController = UIAlertController(title: "did Fail To Register For Remote Notifications", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)
let okAction: UIAlertAction = UIAlertAction(title: "Ok!", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction) in
})
alert.addAction(okAction)
self.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
}
Error 1: invalid use of '()' to call a value of non-function Type 'String'
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
BDArenaConnector.getInstance().pushConnector.feedbackServiceDidReceiveRemoteNotification(userInfo)
// handle push
BDArenaConnector.getInstance().pushConnector.handlePush(userInfo, withPresentingController: self.window!.rootViewController, withActionButtonHandler: {
}, withCancelButtonHandler: {
})
}
Error 2: Value of optional type 'UIWindow' not unwrapped; did you mean to use '!' or '?'?
How Can I fix?

You need to use UIAlertActionStyle.Default and UIAlertControllerStyle.Alert.

Related

Swift display an alert after tapping on notification

So what i am trying to achieve is when a notification launch and the user tap on it, an Alert controller should appear with 2 options. However, when the app launch from the notification tap, nothing appears.
These codes are inside the AppDelegate.swift file
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
showAlert()
}
func showAlert() {
let alert = UIAlertController(title: "Confirm", message: "Confirm?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "No", style: .destructive, handler: nil))
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: nil))
window?.rootViewController?.present(alert, animated: true, completion: nil)
}
var topVC: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
topVC?.rootViewController = UIViewController()
let alert = UIAlertController(title: "Alert", message: "Notification Received", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in
// action OK
})
topVC?.makeKeyAndVisible()
topVC?.rootViewController?.present(alert, animated: true, completion: nil)
Try this:
func showAlert() {
var alertController = UIAlertController(title: "Confirm", message: "Confirm?", preferredStyle: UIAlertControllerStyle.alert)
var okAction = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) {
UIAlertAction in
// action
}
var cancelAction = UIAlertAction(title: "No", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
// action
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
}
I think you are calling the func showAlert() from the wrong place.
When the app launch from the notification tap, the app gets an event in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
So you should try this,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//Handle remote notification event on app launch
if let remoteNotification = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] {
showAlert()
}
}

Can't present alertViewController on rootViewController in AppDelegate

I want to show alertViewController on my rootViewController in AppDelegate when app is launched. Here snippet of code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let alert: UIAlertController = UIAlertController(title: "This is title", message: "This is message.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
return true
}
alert is not appearing on rootViewController. Please help me.
The reason is that the view isn't yet loaded, if you look at console you may find log like this:
Warning: Attempt to present on 'swiftHere.ViewController: 0x7ff289007740' whose view is not in the window hierarchy!
You may dispatch it until rootViewController loads:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
let alert: UIAlertController = UIAlertController(title: "This is title", message: "This is message.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}

Swift - how to change layout content in AppDelegate

I try to show an alert when the app launches (a tabbed app)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let welcomeAlert = UIAlertController(title: "Turn on Bluetooth?", message: "Turn on Bluetooth?", preferredStyle: UIAlertControllerStyle.alert)
welcomeAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {
action in self.alertServerClient()
}))
welcomeAlert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(welcomeAlert, animated: true, completion: nil)
return true
}
In alertServerClient() I want to change UIImage like
func alertServerClient() {
let vc = FirstViewController()
let imgBTOn = UIImage(named: "BT_Button.png")
vc.btnBT.setImage(imgBTOn, for: .normal)
}
Unfortunately, it doesn't work and throw error
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Is it possible to change UI content from AppDelegate?

RequestAuthorization for push outside the didFinishLaunchingWithOptions

For ios 10 i used this for registering the push notifications :
Registering for Push Notifications in Xcode 8/Swift 3.0?
Is there a way to ask for the requestAuthorization(options:[.badge, .alert, .sound]) outside the appdelegate and the func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
The reason i ask is because i don't want to present the pop up for push notifications after the user has used the app for a bit. Any ideas?
Like #dan said it isn't necessary to request the notifications permission in the AppDelegate. You can do it wherever you want to. This is what you probably be doing for that.
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { (success, error) in
if error == nil {
if success {
print("Permission granted")
// In case you want to register for the remote notifications
let application = UIApplication.shared
application.registerForRemoteNotifications()
} else {
print("Permission denied")
}
} else {
print(error)
}
}
And Remember
to import the UserNotifications framework where you use this code.
if you register for remote notifications you need to implement the didRegisterForRemoteNotificationsWithDeviceToken method in your AppDelegate
The question for me is the pop up won't show again once user agreed or denied it.
So we have to redirect users to Settings after that manually.
Here comes the code in Swift:
#IBAction func userDidClickButton(_ sender: Any) {
// initialise a pop up for using later
let alertController = UIAlertController(title: "TITLE", message: "Please go to Settings and turn on the permissions", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
// do something
}
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
// check the permission status
UNUserNotificationCenter.current().getNotificationSettings () { settings in
switch settings.authorizationStatus {
case .denied, .notDetermined:
self.present(alertController, animated: true, completion: nil)
case .authorized:
// continue the stuff
DispatchQueue.main.sync {
// Update UI
}
}
}
}

How to add method from VC in alert handler/closure in DidReceiveLocalNotification?

everyone!
When my app in foreground I want it to show alert when DidReceiveLocalNotification triggered.
I can add alert to mimic local notifications in AppDelegate.swift, but the problem is I don't know how to add method from my ViewController to UIAlertAction closure (see commented line), to finish animation when timer stopped.
My code below:
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
let alertTimerEnds = UIAlertController(title: "Timer finished!", message: nil, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: .Default) { finished in
print("You've pressed OK button")
//self.ViewController().finishAnimation()
}
alertTimerEnds.addAction(okAction)
self.window?.rootViewController?.presentViewController(alertTimerEnds, animated: true, completion: nil)
}
Maybe I should do it in ViewController usind AppDelegate?
let someAppDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
someAppDelegate?.application(UIApplication.sharedApplication(), didReceiveLocalNotification: UILocalNotification) { code for alert }
If you want to do that
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification)
{
var viewController : UIViewController = (application.keyWindow?.rootViewController)!
while ((viewController.presentedViewController) != nil) {
viewController = viewController.presentedViewController!
}
let alert = UIAlertController(title: "", message: notification.alertBody, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: {(action: UIAlertAction!) in}))
viewController.presentViewController(alert, animated: true, completion: nil)
})
Show UIAlertController in didReceiveLocalNotification method
Try with below code, this will display alert on viewcontroller which is present at a moment.
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
var latestViewController : UIViewController!
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
if let viewControllers = appDelegate.window?.rootViewController?.presentedViewController {
latestViewController = viewControllers as UIViewController
}
else if let viewControllers = appDelegate.window?.rootViewController?.childViewControllers {
latestViewController = viewControllers.last! as UIViewController
}
//var alert: UIAlertView!
//alert = UIAlertView(title: "Title", message:"Message , delegate: nil, cancelButtonTitle:"Ok" )
//alert.show()
let alert = UIAlertController(title: "Title", message:"Message", preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default) { _ in
// Put here any code that you would like to execute when
// the user taps that OK button (may be empty in your case if that's just
// an informative alert)
}
alert.addAction(action)
latestViewController.presentViewController(alert, animated: true){}
}
How do I migrate from UIAlertView (deprecated in iOS8)

Resources