2

I am actually using Amazon Web Services SNS to send push notifications in my IOS application. When clicking on the push notification while the application is running in the background the url(sent by the push notification) is open correctly in the WebView(WKWebView). The only issue I am getting is that, the url does not open in the WebView when the application is closed. How can I solve this issue?

Here is the following code:

App Delegate:

func application(application: UIApplication,didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

       UIApplication.sharedApplication().applicationIconBadgeNumber = 0

       NSNotificationCenter.defaultCenter().postNotificationName("ReceivedPushNotification", object: userInfo)

}

ViewController:

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.receivedUrlFromPushNotification(_:)), name: "ReceivedPushNotification", object: nil)

}

func receivedUrlFromPushNotification(notification: NSNotification){

    let JSONData = notification.object!["aps"] as! NSDictionary
    let dictionary: NSDictionary = JSONData
    let v = dictionary.allValues[2] as! String
    let url = "http://\(v)"
    self.webView!.loadRequest(NSURLRequest(URL: NSURL(string:url)!))
}

JSON code send in the push notification:

{
"APNS_SANDBOX":"{\"aps\":{\"alert\":\"test\",\"badge\":1,\"sound\":\"default\",\"url\":\"www.example_samplelink.com\"}}"
}
Raktim Biswas
  • 4,011
  • 5
  • 27
  • 32
S.D
  • 93
  • 1
  • 1
  • 11
  • can you add a handler in the appdeligate file to so when the app revives a notification it brings the app into the foreground and then load up the web view with the url? I am betting that it only opens because your loading it into a web view and not just opening it into a web browser. So the app has to be running in order for the web view to load up and run. – MNM May 31 '16 at 07:00
  • Once the application is active, the url obtained from the push notification loads correctly in the webView. Actually it's not working when the application is closed. Is there a way of doing this? – S.D May 31 '16 at 18:43
  • take a look at this http://stackoverflow.com/questions/13447923/launch-closed-ios-app-from-local-notification – MNM Jun 01 '16 at 00:05
  • But from what I can gather push notifications are not received by the app but by the os. I think there is a way for the os to send a message to your app to bring it to the foreground. But the only way I know right now is by clicking the notification which will launch the didFinishLaunchingWithOption method – MNM Jun 01 '16 at 00:08
  • I had a look at [stackoverflow.com/questions/13447923/...](http://stackoverflow.com/questions/13447923/launch-closed-ios-app-from-local-notification), but it didn't work. Thanks for your help! – S.D Jun 02 '16 at 06:44
  • From what I gathered, the phone has to be plugged in to a power source. It has to do with the apple way of doing things in their power save mode. Try turing off the power save mode of your phone and try again. – MNM Jun 02 '16 at 06:47
  • it weird the link opened up for me even the one you posted – MNM Jun 02 '16 at 06:47
  • I've used this piece of code in **didFinishLaunchingWithOptions** : **if (launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary) != nil { print("Application Open with Push Notification!") }** It detects correctly when the app is launched with the push notification. But when i'm passing the url, it's not working. – S.D Jun 02 '16 at 07:08
  • There we go I added some stuff that should work for you down below. This is how I am doing it right now and it works when the app is off, in the background, or even running – MNM Jun 02 '16 at 08:43

1 Answers1

2

Add this to your didFinishLaunchWithOptions:

   //handel push note if app is closed
    //Sends it to the regular handler for push notifcaiton
    //didrecivepushnotificaiton
    if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary
    {
        self.application(application, didReceiveRemoteNotification: remoteNotification as [NSObject : AnyObject])
    }


    if launchOptions != nil
    {
        print(launchOptions)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier(myPage)
        window?.rootViewController = vc
    }

Where myPage is a string and it is the Tag/Storyboardid of the view you want to open that has a web view init.

And then add this method like this

func application( application: UIApplication,
                  didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

    if var alertDict = userInfo["aps"] as? Dictionary<String, String> {
        let url = alertDict["url"]!
        //store the url for the push control view
        loginInformation.setObject(url, forKey: "URL")
        self.loginInformation.synchronize()

    }else{print("No go")}
    application.applicationIconBadgeNumber = 0
    //post notification.
    NSNotificationCenter.defaultCenter().postNotificationName("PushReceived", object: nil, userInfo: userInfo)

}

Where loginInformation is a NSDefault thingy. Then in the web view you have in the view controller that you linked up earlier you can pass the store value of the url you want into the variable for the url for the web view. You might have to tinker with this a bit for it to work. But this does work. Just needs a bit of set up

This will work when you pass this json to the system. This is exactly how I am doing it.

[aps: {
alert = "Hello from APNs Tester.";
badge = 1;
url = "http://www.google.com";
}]

Hope this helps

And here is the viewcontrller class that you need to use

class PushNotificationController: UIViewController {

var defualtUrl : String = "http://www.IStare@Butts.com"
var storedUrl : String = ""
var useUrl : String = ""
let loginInformation = NSUserDefaults.standardUserDefaults()

override func viewDidLoad() {
    super.viewDidLoad()

    //add observer for load request in webview when receive remote notification.
    NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(PushNotificationController.PushReceiver(_:)), name: "PushReceived", object: nil)
    /*
    if let alertDict = userInfo["aps"] as? Dictionary<String, String> {
        print("URL :", alertDict["url"]!)
    }else{print("No go")}
    */

    if loginInformation.objectForKey("URL") != nil
    {
        storedUrl = loginInformation.objectForKey("URL") as! String
        print("Stored url: " + storedUrl )
        if storedUrl.isEmpty
        {
            useUrl = defualtUrl
        }else{
            useUrl = storedUrl
        }
    }else
    {
        useUrl = defualtUrl
    }


    print("URL Using: " + useUrl)
    let myUrl = NSURL (string: useUrl);
    let requestObj = NSURLRequest(URL: myUrl!);
    pushNotePlayer.loadRequest(requestObj)

    //after it is loaded reset it to the defualt url if there is no other thing next time
    loginInformation.setObject(defualtUrl, forKey: "URL")
    self.loginInformation.synchronize()

}
@IBOutlet weak var pushNotePlayer: UIWebView!

//When post notification then below method is called.
func PushReceiver(notifi: NSNotification)
{
    let dicNotifi: [NSObject : AnyObject] = notifi.userInfo!
    NSLog("notificiation Info %@ \n", dicNotifi)
}

}
MNM
  • 2,673
  • 6
  • 38
  • 73
  • If this isn't clear enough please tell me I wrote it in a hurry as I was leaving my work :) – MNM Jun 02 '16 at 08:49
  • I've used the code above and when I'm clicking on the push notification,only the home page is loading in the webView. It gives the same result even if the application is off or active in the background. The only difference in the code is that i'm using (**var webView: WKWebView?**). – S.D Jun 02 '16 at 11:59
  • This is the result obtained when clicking on the push notification : (**No go**) – S.D Jun 02 '16 at 12:03
  • The No Go means that there is no URL in the Dictionary. Are you using the pn that I supplied? Also can you print out what you a receiving from the push notification like this print(userinfo) from the didrecivenote method – MNM Jun 03 '16 at 01:16
  • This is the JSON code I sent in the push notification : **{ "APNS_SANDBOX":"{\"aps\":{\"alert\":\"test\",\"badge\":1,\"sound\":\"default\",\"url\":\"www.example_samplelink.com\"}}" }** ... and in the notification info I can see all the results. – S.D Jun 03 '16 at 04:23
  • its a invalid json try validating it in here and then send it https://jsonformatter.curiousconcept.com – MNM Jun 03 '16 at 04:57
  • This is the format given by the JSON message generator in Amazon SNS. If I use a different one, it gives me an error. – S.D Jun 06 '16 at 10:05
  • Try this i cleaned up your json so now its valid. – MNM Jun 07 '16 at 00:06
  • { "APNS_SANDBOX":{"aps":{"alert":"test","badge":1,"sound":"default","url":"www.example_samplelink.com"}} } – MNM Jun 07 '16 at 00:06
  • also you will have to adjust my above code to work with the APNS_SANDBOX because you added another layer to the json – MNM Jun 07 '16 at 00:06
  • this part mainly if var alertDict = userInfo["aps"] as? Dictionary { – MNM Jun 07 '16 at 00:23
  • The JSON code you gave is not valid in Amazon sns. The only valid one: { "APNS_SANDBOX":"{\"aps\":{\"alert\":\"test\",\"badge\":1,\"sound\":\"default\",\‌​"url\":\"www.example_samplelink.com\"}}" } – S.D Jun 07 '16 at 11:35
  • but its a valid json? It worked with the above code. Did Amazon sns give you a api to use to parse this? – MNM Jun 08 '16 at 00:01
  • I think you have to deal with Amazon on a different level. You can't just simple parse it because its not valid json from what I see. Take a look at this and give it a shot https://github.com/awslabs/aws-sdk-ios-samples/tree/master/SNS-MobileAnalytics-Sample/Swift – MNM Jun 08 '16 at 00:05
  • When I generate a message in the JSON message generator on Amazon SNS, it gives me the JSON format that i'm using! Therefore it should be a valid one. – S.D Jun 09 '16 at 08:33
  • Is there a way to load a url in the webView inside this “if” condition? **if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary { self.application(application, didReceiveRemoteNotification: remoteNotification as [NSObject : AnyObject]) }** – S.D Jun 09 '16 at 08:33
  • I say just print out the launchOptions and there maybe your url in there. If that happens then you can just grab the url like this let url = alertDict["url"]! – MNM Jun 09 '16 at 08:36
  • I've tried to print out the launchOptions, but the value returned is nil. I've also tried to load a url manually using this method: **NSNotificationCenter.defaultCenter().postNotificationName("sendURL", object:nil)** it's not working! – S.D Jun 14 '16 at 07:32