How to check launchOptions in Swift? - swift

I'm pretty stumped here - I'm trying to detect if my app launched from a LocalNotification or not. But all my code is borked.
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
var firstWay = launchOptions.objectForKey(UIApplicationLaunchOptionsLocalNotificationKey)
var secondWay = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]
return true
}
Both of these fail with the message
"unexpectedly found nil while unwrapping an Optional value"
I am sure I am doing something very basic incorrectly here. Any pointers?

You are unwrapping the launchOptions dictionary, which is frequently nil, in your arguments. Trying to unwrap a nil value will lead to a crash so you need to check that it is not nil before using the trailing exclamation point to unwrap it. The correct code is as follows:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
if let options = launchOptions {
// Do your checking on options here
}
return true
}

cleanest way:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let notification:UILocalNotification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
//do stuff with notification
}
return true
}

You can also do this,
let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as! UILocalNotification!
if (notification != nil) {
// Do your stuff with notification
}

Related

Apple Watch Connectivity Status with iPhone

I am trying to get the connectivity status of the iPhone and the Apple Watch. I have tried using CoreBluetooth which didn't work. I think I am on the right track but I need a bit of help. My code is below :)
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if WCSession.isSupported() {
let session = WCSession.default
session.delegate = self
session.activate()
}
return true
}
Detail.swift
override func viewDidLoad() {
super.viewDidLoad()
if (WCSession.default.isPaired){
print("thumbsup")
} else{
print("thumbsdown")
}
}
you also have to check whether the activation state is active, otherwise isPaired should not be evaluated

UIApplicationLaunchOptionsShortcutItemKey not there in Swift 3?

Recently in Xcode 8 beta 6 (8S201h), this has become a problem.
UIApplicationLaunchOptionsShortcutItemKey
Here's the error :
Anyone else having this issue?
var performShortcutDelegate = true
if let shortcutItem = launchOptions[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
print("ok")
self.shortcutItem = shortcutItem
performShortcutDelegate = false
}
return performShortcutDelegate
The constant has changed (see the documentation). You also need to unwrap launchOptions before using any values it contains.
Enclosing function is included for context.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let launchOptions = launchOptions {
if #available(iOS 9.0, *) {
if let shortcutItem = launchOptions[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
print("Shortcut: \(shortcutItem)")
}
}
}
return true
}
The launchOptions Dictionary type has changed in the function parameters to [UIApplicationLaunchOptionsKey: AnyObject].
private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: AnyObject]?) -> Bool {
...
}
Try this.. Its work for me using Xcode8 , swift3
//Check for ShortCutItem
if #available(iOS 9.0, *) {
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
}
}

Push remote notification

I need create in my app a code that receive a remote information and push it to user when app is on background, I read on web that I need to use didReceiveRemoteNotification on appDelegate, to use remote push notication. I read something about and I need keys and certificates, I do not understand how to use didReceiveRemoteNotification
I need to learn about to push remote notification and how to use. I would like a tutorial or example how create it using swift 2.3.
I used this link and I found it the most helpful
http://www.appcoda.com/push-notification-ios/
I used this app for testing
https://itunes.apple.com/us/app/easy-apns-provider-push-notification/id989622350?mt=12
This is the code I have in my AppDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
registerForPushNotifications(application)
print(UIDevice.currentDevice().identifierForVendor!.UUIDString)
return true
}
func registerForPushNotifications(application: UIApplication) {
let notificationSettings = UIUserNotificationSettings(
forTypes: [.Badge, .Sound, .Alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
if notificationSettings.types != .None {
application.registerForRemoteNotifications()
}
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
var tokenString = ""
for i in 0..<deviceToken.length {
tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
print("Device Token:", tokenString)
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("Failed to register:", error)
}

Different APN Device Token ID for same application

I just followed the tutorial of http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1 for creating a sample push notification example....
But I dono where I went wrong I am receiving different token ID on different devices for the same application.
Here is my code for reference,
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var type = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound;
var setting = UIUserNotificationSettings(forTypes: type, categories: nil);
UIApplication.sharedApplication().registerUserNotificationSettings(setting);
UIApplication.sharedApplication().registerForRemoteNotifications();
return true
}
func application(application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
println("My token is \(deviceToken)") // am getting it different for different devices
}
//Called if unable to register for APNS.
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
println(error)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
println("Recived: \(userInfo)")
//Parsing userinfo:
var temp : NSDictionary = userInfo
if let info = userInfo["aps"] as? Dictionary<String, AnyObject>
{
var alertMsg = info["alert"] as! String
var alert: UIAlertView!
alert = UIAlertView(title: "", message: alertMsg, delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
}
One more problem is that I am receiving a sound and banner but not "badge"
Any help would be appreciated....
In your "didRegisterForRemoteNotificationsWithDeviceToken"
send your device Token to server like this
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let deviceTokenStr = HDDataLayer.convertDeviceTokenToStr(deviceToken)
HDDataLayer.postNotificationServiceResponseByUrlString("pushnotifications/notifications/register", andParams: tempDict, andDictCompletion: { (response: AnyObject!, error: NSError!) -> Void in
NSLog("Device Register successfully")
})
}
Please Note that HDDataLayer is my own class and you will use class you are using to interact with your server.

Checking network status in Swift, observer does not get called

I have imported Reachability.h .m files like written here into my Swift project, but observer / event handler will not get called after start, why?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: kReachabilityChangedNotification, object: nil)
let hostReachability = Reachability(hostName: "www.apple.com");
hostReachability.startNotifier();
return true
}
func reachabilityChanged(note: NSNotification) { // <- DOES NOT GET CALLED
let reachability: Reachability = note.object as Reachability;
if(reachability.currentReachabilityStatus() != .NotReachable) {
}
}
The Reachability object returned is an autoreleased object , so it has deallocated hence notification is not triggering . You can fix by keeping a strong reference to it.
create a property to hold Reachability object
var reachability:Reachability?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
// Override point for customization after application launch.
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name:kReachabilityChangedNotification, object: nil)
reachability = Reachability(hostName: "www.apple.com");
reachability?.startNotifier();
return true
}
This will fix your problem.
The observer's name is changed from ReachabilityChangedNotification to kReachabilityChangedNotification. Notice the "k"
As mentioned in other answers, you need to maintain a strong reference to the Reachability object. If you aren't checking a particular host, then call reachabilityForInternetConnection:
let internetReachability = Reachability.reachabilityForInternetConnection()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: kReachabilityChangedNotification, object: internetReachability)
internetReachability.startNotifier()
let hasInternet = internetReachability.currentReachabilityStatus().value == 0 ? false : true
// Save to user defaults, log to console, etc.
return true
}
func reachabilityChanged(note: NSNotification) {
var hasInternet = Bool()
if let reachability = note.object as? Reachability {
hasInternet = internetReachability.currentReachabilityStatus().value == 0 ? false : true
}
// Update user defaults, log to console, show error message, etc.
}
For iOS 3+, use below code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
NotificationCenter.default.addObserver(self, selector: #selector(checkForReachability(notification:)), name: NSNotification.Name.reachabilityChanged, object: nil)
reachability = Reachability.forInternetConnection()
reachability.startNotifier()
return true
}
// MARK:
// MARK: Check Internet Status
func checkForReachability(notification:NSNotification)
{
let networkReachability = notification.object as! Reachability;
let remoteHostStatus = networkReachability.currentReachabilityStatus()
if (remoteHostStatus == NotReachable)
{
print("Not Reachable")
}
else
{
print("Reachable")
}
}