reachability issue when open my app. Swift - swift

My reachability function is executed if I open my app with internet. So, if I turn off the wifi, alert would be displayed. But, it doesn't work if I open my app with no internet. No alert is displayed. Any suggestions? Thanks.
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var reachability: Reachability?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "checkForReachability:", name: kReachabilityChangedNotification, object: nil)
self.reachability = Reachability.reachabilityForInternetConnection()
self.reachability!.startNotifier()
}
func checkForReachability(notification: NSNotification) {
let remoteHostStatus = self.reachability!.currentReachabilityStatus()
if (remoteHostStatus.rawValue == NotReachable.rawValue) {
let myAlert = UIAlertController(title: "Alert", message: "Please check your internet connection.", preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title:"Try again.", style:UIAlertActionStyle.Default) {
action in
self.checkForReachability(notification)
}
myAlert.addAction(okAction)
self.window?.rootViewController?.presentViewController(myAlert, animated:true, completion:nil)
}
}
}

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

AppCenterPush does not register device and does not receive notification - Swift 4

I'm following microssoft's step-by-step to use AppCenterPush, however when trying to insert "MSPushDelegate.setDelegate (self)" Xcode returns me the following error "Type 'MSPushDelegate' has no member 'setDelegate'".
I think I can not register the device or receive notification because I can not associate MSPushDelegate.
My current code:
import UIKit
import UserNotifications
import AppCenter
import AppCenterAnalytics
import AppCenterCrashes
import AppCenterPush
#UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MSPushDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Clean notifications
application.applicationIconBadgeNumber = 0
application.cancelAllLocalNotifications()
//enable notification (used for local notifications)
let notificationSettings = UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
UIApplication.shared.registerUserNotificationSettings(notificationSettings)
UIApplication.shared.registerForRemoteNotifications()
// Notification by AppCenterPush
MSPush.setDelegate(self) // this line show the error: "Type 'MSPush' has no member 'setDelegate'"
MSAppCenter.setEnabled(true)
MSAppCenter.start("{MyAppSecret}", withServices: [
MSAnalytics.self,
MSCrashes.self,
MSPush.self
])
return true
}
My code to show the notification:
func push(_ push: MSPush!, didReceive pushNotification: MSPushNotification!) {
print("Working")
let title: String = pushNotification.title ?? ""
var message: String = pushNotification.message ?? ""
var customData: String = ""
for item in pushNotification.customData {
customData = ((customData.isEmpty) ? "" : "\(customData), ") + "\(item.key): \(item.value)"
}
if (UIApplication.shared.applicationState == .background) {
NSLog("Notification received in background, title: \"\(title)\", message: \"\(message)\", custom data: \"\(customData)\"");
} else {
message = message + ((customData.isEmpty) ? "" : "\n\(customData)")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .cancel))
// Show the alert controller.
self.window?.rootViewController?.present(alertController, animated: true)
}
}

How to display a specific ViewController in OneSignal Swift

I do app with OneSignal and Swift 3. I got push. How to display a specific ViewController with WebView in OneSignal when notification is clicked. In push in additional data with field "link" I got link, but can't display this link in my WebView.
I try use global variable tempURL to put url from additional data. But it not work.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
OneSignal.initWithLaunchOptions(launchOptions, appId: "MYID", handleNotificationAction: { (result) in
let payload = result?.notification.payload
print("This is Payload \(payload)")
var fullMessage = payload?.title
let messageTitle = "OneSignal Example"
if (result?.action.actionID) != nil {
let additionalData = payload?.additionalData
let url = additionalData?["link"] as! String?
tempURL = url!
fullMessage = fullMessage! + "\nPressed ButtonId:\(url)"
}
let alertController = UIAlertController(title: messageTitle, message: fullMessage, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
alertController.addAction(okAction)
alertController.show(alertController, sender: nil)
})
return true
}
Try to show:
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
let aViewController = ViewController()
aViewController.loadAddressURL(url: tempURL)
UIApplication.shared.keyWindow?.rootViewController?.present(aViewController, animated: true, completion:nil)
}
I have error:
fatal error: unexpectedly found nil while unwrapping an Optional value
first of all you can't pass data in your way. You should instantiate ViewController with StoryboardID. I explained how to use it with this link.
If you are pretty sure, your additionalData is not nil, you can pass your data with StoryboardID.

Open a ViewController from remote notification

I try to open a particular ViewController when my app catch a remote notification.
Let me show my project's architecture.
Here my storyboard :
When I receive a notification I want open a "SimplePostViewController", so this is my appDelegate :
var window: UIWindow?
var navigationVC: UINavigationController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
self.navigationVC = storyboard.instantiateViewControllerWithIdentifier("LastestPostsNavigationController") as? UINavigationController
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if let postId = userInfo["postId"] as? String {
print(postId)
let api = EVWordPressAPI(wordpressOauth2Settings: Wordpress.wordpressOauth2Settings, site: Wordpress.siteName)
api.postById(postId) { post in
if (post != nil) {
self.navigationVC!.pushViewController(SimplePostViewController(), animated: true)
} else {
print("An error occurred")
}
}
}
}
I save my UINavigationViewController when the app is launch and simply try to push a new SimplePostViewController when I receive a notification. But nothing happen.
I placed breakpoints and seen that my pushViewController method was reached, but not the ViewWillAppear of my SimplePostViewController.
I also used the "whats new" view add perform my segue but nothing happen too.
Solution :
for child in (self.rootViewController?.childViewControllers)! {
if child.restorationIdentifier == "LastestPostsNavigationController" {
let lastestPostsTableViewController = (child.childViewControllers[0]) as! LastestPostsTableViewController
let simplePostVC = (self.storyboard?.instantiateViewControllerWithIdentifier("PostViewController"))! as! PostViewController
simplePostVC.post = post
lastestPostsTableViewController.navigationController?.pushViewController(simplePostVC, animated: true)
}
}
I use :
child.childViewControllers[0]
because I've only one child in my example.
I created a sample project with a local notification instead of a remote notification for ease of showing the functionality but it should be as simple as setting the root view controller of the window in the app delegate didreceiveremote notification.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Subscribe for notifications - assume the user chose yes for now
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil))
return true
}
func applicationDidEnterBackground(application: UIApplication) {
//Crete a local notification
let notification = UILocalNotification()
notification.alertBody = "This is a fake notification"
notification.fireDate = NSDate(timeIntervalSinceNow: 2)
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
let sb = UIStoryboard(name: "Main", bundle: nil)
let otherVC = sb.instantiateViewControllerWithIdentifier("otherVC") as! OtherViewController
window?.rootViewController = otherVC;
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
//Your code here
}
`
You need to worry about managing your view hierarchy and sending anything to it that you need to send from the notification user data.
In my example, I create a local notification when you close the app that fires after a view seconds. If you then launch the app from the notification, it will open the "other view controller" which would be the "SimplePostViewController" in your case.
Also, be sure that you are registering for remote notifications in the didFinishLaunchWithOptions.
Github very simple sample : https://github.com/spt131/exampleNotificationResponse

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.