[Solved] Background Processing in Swift


Despite getting downvoted, I still think my solution may be useful to someone new to notifications in iOS development. I switched from local notifications to push notifications setting my remote flask application to handle all the background processing and notification sending with firebase:

  1. Follow this tutorial to set your app for receiving push notifications: https://www.youtube.com/watch?v=34kvGKdPN2k

  2. Create a flask application on your remote server and deploy it. If you don’t have a remote server, I used a 5€/month ubuntu server from https://www.digitalocean.com . then you can follow exactly the instructions here to create and deploy your flask application: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04 (those instructions works on whatever ubuntu server and they have other tutorials for different OS).

  3. Configure flask with your firebase as a server: https://firebase.google.com/docs/admin/setup

DISCLAIMER: you should’t proceed if you haven’t follow successfully the previous steps.

  1. Now if you are new to Flask, it handle HTTP requests pretty neatly and it’s very intuitive.

    4.1. Open your flask application for editing nano myproject.py or vim myproject.py etc.

    4.2 Add import requests and from pyfcm import FCMNotification in your imports and this right after the imports: push_service = FCMNotification(api_key=SERVER_KEY) where SERVER_KEY is your server key from firebase in your project settings.

    4.3 Add the following code (every bit of this code in ALL CAPS is something you can change):

@app.route('/MY_REQUEST_NAME')
def MY_FUNCTION():
    # MY_ARGUMENT in this case will be the iOS device token
    MY_ARGUMENT = str(request.args.get('MY_ARGUMENT'))
    # do calculations
    result = push_service.notify_single_device(registration_id=MY_ARGUMENT, message_title=MESSAGE, message_body=BODY)
    return MY_RESULTS
    # if you're goal is just sending notification you don't really need a return statement

4.4 Save and exit then in your server activate your virtual environment source myprojectenv/bin/activate and type pip install requests pyfcm

Flask application will trigger the function we just wrote when you type in your browser: http://your_domain.com/my_request_name?my_argument=my_argument_value or you can use your server public IP address instead of the domain if you don’t have one.

  1. If you don’t have an SSL certificate (you’re using http instead of https), you have to go back to Xcode and add the following in your Info.plist:

App Transport Security Settings

  1. Go to your AppDelegate and modify the following function to store the device fcm_token somewhere. I personally used the defaults.standard:
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
      print("Firebase registration token: \(fcmToken)")

      // Save Token:
      UserDefaults.standard.set(fcmToken, forKey: "FCM_TOKEN")

      NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
      // TODO: If necessary send token to application server.
      // Note: This callback is fired at each app startup and whenever a new token is generated.
    }
  1. Finally, in Xcode you can call your http request like this:
let token = UserDefaults.standard.string(forKey: "FCM_TOKEN")!
        let url : URL = URL(string: "http://your_domain.com/my_request_name?my_argument=\(token)")!
        let task = URLSession.shared.dataTask(with: url)
        task.resume()

3

solved Background Processing in Swift