Parse Push Notifications - Swift Installation Not Working - swift

I am trying to get Parse push notifications working on my app (all swift) but while trying to implement, I get the error 'PFInstallation' does not have a member named 'saveInBackground'
Here is my code.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("APP ID HIDDEN", clientKey: "CLIENT ID HIDDEN")
// let notificationTypes:UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound
//let notificationSettings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
var notificationType: UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound
var settings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationType, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
//UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
// Override point for customization after application launch.
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings!) {
UIApplication.sharedApplication().registerForRemoteNotifications()
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
var currentInstallation: PFInstallation = PFInstallation()
currentInstallation.setDeviceTokenFromData(deviceToken)
currentInstallation.saveInBackground()
println("got device id! \(deviceToken)")
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
println(error.localizedDescription)
println("could not register: \(error)")
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
}
When I change the currentInstallation.saveInBackground to currentInstallation.saveEvenutally() , the code compiles fine..
But when trying to successfully sign up for push notifications, an error pops up in the console saying Error: deviceType must be specified in this operation (Code: 135, Version: 1.4.2)
I have spent hours trying to figure this out, no dice, any help is appreciate.

To anyone else who has this error, make sure you import the Bolts framework into your Bridging Header file
Which isn't outlined in their crap docs.
That fixes the issue.
Below is the code.
#import <Parse/Parse.h>
#import <Bolts/Bolts.h>
Just add that to your bridging header then you are good to go. Thanks

A valid PFInstallation can only be instantiated via [PFInstallation currentInstallation] because the required identifier fields are readonly. (source)
So instead of:
var currentInstallation: PFInstallation = PFInstallation()
Try:
var currentInstallation = PFInstallation.currentInstallation()

Just write import Bolts in you AppDelegate.swift file

In addition to importing Bolts, I fixed the same error in my app by changing the function to
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// Store the deviceToken in the current Installation and save it to Parse
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
From the Parse guide on Push Notifications (as opposed to quickstart guide): https://parse.com/docs/ios/guide#push-notifications

Related

SwiftUI swizzling disabled by default, phone auth not working

I am building a screen with phone number login. I checked over and over again and the project is newly created, however, I am getting this log:
7.2.0 - [Firebase/Auth][I-AUT000015] The UIApplicationDelegate must handle remote notification for phone number authentication to work.
If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotificaton: method.
I did read in the documentation about swizzling and I don't know why it seems to be disabled, I did not disabled it. I have added GoogleServices-Info.plist into the app, I added in firebase panel the app apn auth key.
My entry point in the app looks like this:
#main
struct partidulverdeApp: App {
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
MainView()
.onOpenURL { url in
Auth.auth().canHandle(url.absoluteURL)
}
}
}
}
My URL Types property has an entry with the RESERVED_CLIENT_ID
I am very desperate about this problem. Any idea is highly appreciated.
Edit1:
I did read the documentation and tried to handle notification with swizzling disabled, but I get the same error:
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didReceiveRemoteNotification notification: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if Auth.auth().canHandleNotification(notification) {
completionHandler(.noData)
return
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("Your code here")
return true
}
}
#main
struct partidulverdeApp: App {
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
MainView()
.onOpenURL { url in
Auth.auth().canHandle(url.absoluteURL)
}
}
}
}
Here's how to implement Phone Number Auth using the new SwiftUI 2 life cycle:
Create a Firebase project and set up PhoneNumber Auth
Add your iOS app to the Firebase project, download and add GoogleService-Info.plist to your project
In Xcode, select the application target and enable the following capabilities:
Push notifications
Background modes > Remote notifications
Create and register an APNS authentication key on the Apple developer portal
Upload the key to Firebase (under Project Settings > Cloud messaging in the Firebase Console)
Add the Firebase project's reversed client ID to your app's URL schemes
In your Info.plist, set FirebaseAppDelegateProxyEnabled to NO
Implement the AppDelegate as follows:
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
print("SwiftUI_2_Lifecycle_PhoneNumber_AuthApp application is starting up. ApplicationDelegate didFinishLaunchingWithOptions.")
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("\(#function)")
Auth.auth().setAPNSToken(deviceToken, type: .sandbox)
}
func application(_ application: UIApplication, didReceiveRemoteNotification notification: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print("\(#function)")
if Auth.auth().canHandleNotification(notification) {
completionHandler(.noData)
return
}
}
func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
print("\(#function)")
if Auth.auth().canHandle(url) {
return true
}
return false
}
}
#main
struct SwiftUI_2_Lifecycle_PhoneNumber_AuthApp: App {
#UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
print("Received URL: \(url)")
Auth.auth().canHandle(url) // <- just for information purposes
}
}
}
}
For further reading, I suggest these two articles I wrote:
Firebase and the new SwiftUI 2 Application Life Cycle
The Ultimate Guide to the SwiftUI 2 Application Life Cycle

Use of unresolved identifier 'url'

I'm completely new to API's, and am following this tutorial on appcoda
https://www.appcoda.com/dropbox-api-tutorial/
It's been going very smoothly, but I've run into a problem, and given that I'm a novice, I don't have the first clue with how to fix it.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let appKey = "n00nzv68gtxk6c9" // Set your own app key value here.
let appSecret = "itumv0icksr7yj6" // Set your own app secret value here.
let dropboxSession = DBSession(appKey: appKey, appSecret: appSecret, root: kDBRootDropbox)
DBSession.setShared(dropboxSession)
return true
if DBSession.sharedSession().handleOpenURL(url) {
if DBSession.shared().isLinked() {
NotificationCenter.defaultCenter.postNotificationName("didLinkToDropboxAccountNotification", object: nil)
return true
}
}
return false
}
The problem is in the line
if DBSession.sharedSession().handleOpenURL(url) {
where I get the error
Use of unresolved identifier 'url'
What do I need to do?
Per the tutorial, you need to use the correct delegate method within AppDelegate.swift
// handle custom application schemes
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
if DBSession.sharedSession().handleOpenURL(url) {
print("Url defined as \( url)")
}
}

PFFacebookUtils.logInInBackgroundWithReadPermissions block returns user = nil and error = nil

I have an iOS 9 app (Xcode 7.1, Swift 2.0) with the following pods, using the latest versions at the time of this post:
pod 'Parse' (using latest version 1.12.0)
pod 'ParseFacebookUtilsV4' (using latest version 1.11.0)
I am attempting to run the following code:
let permissions = ["public_profile", "email"]
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissions) {
(user, error) in
// Both user and error are nil here
}
But I always get a nil user and a nil error. The login worked a couple months ago, but all of a sudden (I believe after a pod update), the login stopped working.
I have added all the proper plist entries as described on the Facebook developers site, and I have added all the appropriate functions in the app delegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions)
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String
return FBSDKApplicationDelegate.sharedInstance().application(app, openURL: url, sourceApplication: sourceApplication, annotation: nil)
}
func applicationDidBecomeActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
in AppDelegate, under didFinishLaunchingWithOptions initialize Parse before initializing PFFacebookUtils. I was making the same mistake

Parse Register for Push Notification - Crash if user not signed in

So i have push notifications setup and as part of the did register for push notifications i need to add the current user to the installation table. This works fine up untill there is no user signed in.
This is my code
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let types:UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setObject(PFUser.currentUser()!, forKey: "user")
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)
}
}
I need a way of registering the user with the installation table without it crashing if there is no user on, i would do a simple check to see if there is a user signed in and then run the code if there is a user, but then if someone sent a notification to them they wouldnt get it because their PFUser.currentUser() has not been added. Thanks in advance
Have you tried looking into Anonymous users (http://blog.parse.com/announcements/protect-user-data-with-new-parse-features/)? This allows you to create a PFUser for a logged out user.
This way, you can still save PFUser reference on the current installation via a PFUser.currentUser() call, but the user does not have to sign up.

Xcode6 Swift add Remote Push Notifications and send from PHP

I want to send Push Notifications via a PHP script to all app users. About Google Unfortunately there are no tutorials for Push Notifications with Swift. Parse.com I do not want to use. Can anyone help me please?
OK now it works ! (:
Create Certificate for APN:
raywenderlich.com
Swift Code:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
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(deviceToken)
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
println(error)
}
find the deviceToken in the Xcode Console
PHP Script
use the PHP Script from here raywenderlich.com (scroll down)
run the PHP Script and viola (: