Making a HTTP POST Request in Swift 2

2019-02-19 02:46发布

问题:

On Google's Firebase website, in order to send downstream messages, I have to do an HTTP Post request. This is what it says to do:

Sending downstream messages from the server:

To address or "target" a downstream message, the app server sets to with the receiving client app's registration token. You can send notification messages with predefined fields, or custom data messages; see Notifications and data in the message payload for details on payload support. Examples in this page show how to send data messages in HTTP and XMPP protocols.

HTTP POST Request

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
   "score": "5x1",
   "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

How do I do this in Swift 2?

回答1:

People down-voted this question, and it's a shame. I've been researching this topic for over 4 months now, and no other stackoverflow question/answer has helped me.

Anyway, I've found the solution, specific to Google's Firebase Cloud downstream messaging. This sends a message to the Google server that pushes notifications to all users via a HTTP POST request.

Before doing any of the code below, be sure to follow the steps to setting up an iOS client for Firebase, installing all the correct pods and getting your certificates, provisioning profile, etc. here.

View Controller:

override func viewDidLoad() {
    super.viewDidLoad()

    let url = NSURL(string: "https://fcm.googleapis.com/fcm/send")
    let postParams: [String : AnyObject] = ["to": "<Your registration token>", "notification": ["body": "This is the body.", "title": "This is the title."]]

    let request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    request.setValue("key=<Your Firebase Server Key>", forHTTPHeaderField: "Authorization")

    do 
    {
        request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(postParams, options: NSJSONWritingOptions())
        print("My paramaters: \(postParams)")
    }
    catch
    {
        print("Caught an error: \(error)")
    }

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in 

        if let realResponse = response as? NSHTTPURLResponse
        {
            if realResponse.statusCode != 200
            {
                print("Not a 200 response")
            }
        }

        if let postString = NSString(data: data!, encoding: NSUTF8StringEncoding) as? String
        {
            print("POST: \(postString)")
        }
    }

    task.resume()
}

App Delegate:

var window: UIWindow?

func displayAlert(title: String, message: String) {

    let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
    alert.addAction(UIAlertAction(title: "Okay", style: .Default, handler: nil))
    self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    FIRApp.configure()

    let notificationTypes: UIUserNotificationType = [.Alert, .Badge, .Sound]
    let pushNotifSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)

    application.registerUserNotificationSettings(pushNotifSettings)
    application.registerForRemoteNotifications()

    return true
}

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

    print("Device Token = \(deviceToken)")
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
    print("Registration token: \(FIRInstanceID.instanceID().token()!)")
}

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {

    print(error)
}

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

    // For push notifications sent from within the Firebase console
    if userInfo["google.c.a.c_l"] != nil
    {
        if let title = userInfo["google.c.a.c_l"] as? String
        {
            if let body = userInfo["aps"]!["alert"] as? String
            {
                self.displayAlert(title, message: body)
            }
         }
     }
     // For push notifications sent from within the app via HTTP POST Request
     else
     {
        if let title = userInfo["aps"]!["alert"]!!["title"] as? String
        {
            if let body = userInfo["aps"]!["alert"]!!["body"] as? String
            {
                self.displayAlert(title, message: body)
            }
        }
     }
}

func applicationDidEnterBackground(application: UIApplication) {

    FIRMessaging.messaging().disconnect()
    print("Disconnected from FCM")
}

If anybody has any questions, please feel free to ask! I also know how to send to topics.

Thanks!



回答2:

Solution Update

Swift 4 + further insight on how to tweak the FCM in Swift

Locate your server key at Project Settings > Cloud Messaging > Server Key

func swiftHttpPostRequest(){ 


let serverKey = <Server Key> // AAAA8c3j2...
let partnerToken = <Receiver Token> // eXDw9S52XWoAPA91....  
let topic = "/topics/<your topic here>"  // replace it with partnerToken if you want to send a topic 
let url = NSURL(string: "https://fcm.googleapis.com/fcm/send") 

let postParams = [
                   "to": partnerToken,
                   "notification": [
                   "body": "This is the body.",
                   "title": "This is the title.",
                   "sound" : true, // or specify audio name to play
                   "click_action" : "