Checking network status in Swift, observer does not get called - swift

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")
}
}

Related

NotificationCenter addObserver for reachabilityChanged not working

Here, i would like to addObserver to check if i got internet connection,
i used reachability-swift 5.0 from https://github.com/ashleymills/Reachability.swift and i use this code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let reachability = try! Reachability()
NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged(note:)), name: .reachabilityChanged, object: reachability)
do{
try reachability?.startNotifier()
print("start notifierrrr")
}catch{
print("could not start reachability notifier")
}
...
}
When i turn on/off my wi-fi, the function didn't called at all
#objc func reachabilityChanged(note: Notification) {
let reachability = note.object as! Reachability
switch reachability.currentReachabilityStatus {
case .reachableViaWiFi:
print("Reachable via WiFi bbb")
case .reachableViaWWAN:
print("Reachable via WWAN bbb")
case .notReachable:
print("Network not reachable bbb")
}
}
nb: i'm using real device iphone 7 and using ReachabilitySwift (5.0.0)
public convenience init(hostname: String,
queueQoS: DispatchQoS = .default,
targetQueue: DispatchQueue? = nil,
notificationQueue: DispatchQueue? = .main) throws {
guard let ref = SCNetworkReachabilityCreateWithName(nil, hostname) else {
throw ReachabilityError.failedToCreateWithHostname(hostname, SCError())
}
Intialise the reachability with a host name(www.google.com) before start notifier()

NotificationCenter Post request never gets received

I am trying to post a message to an observable in my app but for some reason it doesn't work at all and the only thing I can attribute it to is installing https://bugfender.com/ can anyone tell me what is wrong with this code or how to track down the root cause as there is no error messages at all
Both snippets have been moved to AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
NotificationCenter.default.post(name: Notification.Name("TestPost"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveData(_:)), name: Notification.Name("TestPost"), object: nil)
return true
}
and the receiver functions is
#objc func onDidReceiveData(_ notification:Notification) {
// Do something now
print("XXXXXX received")
}
===== Updating with my actual code for custom capacitor plugin =======
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
... code for receiving notification starts here
NotificationCenter.default.post(name: Notification.Name("TestPost"), object: nil)
... code for receiving notification ends here
return true
}
import Foundation
import Capacitor
#objc(myHelpers)
public class myHelpers: CAPPlugin {
public override func load() {
print("PluginLoaded")
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(handleSignal), name: Notification.Name("TestPost"), object: nil)
}
#objc func handleSignal()
{
print("XX WE RECEIVED AN EVENT AT handleSignal")
notifyListeners(
"myPluginEvent",
data: [:],
retainUntilConsumed: true
)
}
}
You need to register your observer before you post the notification.

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)
}

Parse.com chek push notification before showing

How to check push notification before showing?
I want check data and if incorrect data I don't want show notification
my code:
I just use simple Parse.com example. This is my AppDelegate class
let defaults = NSUserDefaults.standardUserDefaults()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("//",
clientKey: "//")
if application.applicationState != UIApplicationState.Background {
let preBackgroundPush = !application.respondsToSelector("backgroundRefreshStatus")
let oldPushHandlerOnly = !self.respondsToSelector("application:didReceiveRemoteNotification:fetchCompletionHandler:")
var pushPayload = false
if let options = launchOptions {
pushPayload = options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil
}
if (preBackgroundPush || oldPushHandlerOnly || pushPayload) {
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
}
var notificationActionAccept :UIMutableUserNotificationAction = UIMutableUserNotificationAction()
notificationActionAccept.identifier = "FIRST_ACTION"
notificationActionAccept.title = "Įvertinti"
var notificationCategory:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "CallNotificationCategory"
notificationCategory .setActions([notificationActionAccept], forContext: UIUserNotificationActionContext.Default)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Sound, .Badge], categories: NSSet(array:[notificationCategory]) as! Set<UIUserNotificationCategory>)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
if let launchOptions = launchOptions as? [String : AnyObject] {
if let notificationDictionary = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject : AnyObject] {
self.application(application, didReceiveRemoteNotification: notificationDictionary)
}
}
return
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool
{
return
}
func applicationWillResignActive(application: UIApplication) {
}
func applicationDidEnterBackground(application: UIApplication) {
}
func applicationWillEnterForeground(application: UIApplication) {
}
func applicationDidBecomeActive(application: UIApplication) {
}
func applicationWillTerminate(application: UIApplication) {
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
if error.code == 3010 {
print("Push notifications are not supported in the iOS Simulator.")
} else {
print("application:didFailToRegisterForRemoteNotificationsWithError: %#", error)
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
}
}
I Realy need help:/
No, unfortunately you can not stop notification from showing when your app is in background.
application:didReceiveRemoteNotification: is just a delegate method, which is invoked upon notification showing, it can not control if notification should be shown or not.

How to check launchOptions in 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
}