get VOIP Token on ios10 - ios10

I can't have the voip token with this function
func registerVoipNotifications() {
let mainQueue = dispatch_get_main_queue()
let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
voipRegistry.delegate = self
voipRegistry.desiredPushTypes = [PKPushTypeVoIP]
}
and
func pushRegistry(registry: PKPushRegistry,
didUpdatePushCredentials credentials: PKPushCredentials,
forType type: String) {
//print out the VoIP token. We will use this to test the nofications.
let voipToken = credentials.token
self.getSipSetting("\(voipToken)")
}
but i can't enter in 'didUpdatePushCredentials'.
With ios9, i don't have this problem.
Do you have an idea ?

Have you enabled the Push notifications in your project Capabilities?
have you added the SSL certificates (Apple Push Notification service SSL Certificates) in your app id configuration?

Related

Google Classroom API integration with swift

I want to link my iOS app with Google Classroom on swift. My current goal is to be able to get a list of all the courses I am enrolled in.
Here is the code I am currently using
func googleClassroomList() {
//let sharedInstance = GIDSignIn.sharedInstance()
//let handler = sharedInstance
googleClassroomService.apiKey = "AIzaSyBOGamjhRuu45T2jT7Qa3LmtntSwgIxeqo"
let query = GTLRClassroomQuery_CoursesList.query()
query.pageSize = 1000
let classQuery = googleClassroomService.executeQuery(query, completionHandler: { ticket , fileList, error in
if error != nil {
let message = "Error: \(error?.localizedDescription ?? "")"
print(message)
} else {
if let list = fileList as? GTLRClassroomQuery_CoursesList {
self.fileList = list
print("List: \(list)")
}
else {
print("Error: response is not a file list")
}
}
}
)
}
Here is the error message:
Error: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
I don't understand where I attach the OAuth access token, I tried putting it under apiKey but I don't really understand what I am supposed to do. For reference, I am using this auth scope. "https://www.googleapis.com/auth/classroom.courses"
First you have to sign-in using Google, and Google will manage the OAuth 2.0 token for you.
Here you have the instructions:
https://developers.google.com/identity/sign-in/ios/sign-in?ver=swift
Also make sure to set the service.authorizer property when you are actually signed in:
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
guard let user = user else {
return
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.setLoggedOut(loggedOut: false)
self.myClassroom.service.authorizer = user.authentication.fetcherAuthorizer()
self.showClassroomClasses()
}

watchOS, not receiving remote notifications

I am developing app on WatchOS 6 but I cannot receive remote notification
Here is my registration code for push notifications in ExtensionDelegate I am getting valid device token.
extension ExtensionDelegate {
func setupRemoteNotifications() {
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
print("[WATCH PUSH NOTIFICATIONS] Permission granted: \(granted)")
guard granted else {
DispatchQueue.main.async {
self.showNotificationsNotGrantedAlert()
return
}
return
}
self.getNotificationSettings()
}
}
private func getNotificationSettings() {
UNUserNotificationCenter.current().getNotificationSettings { settings in
print("[WATCH PUSH NOTIFICATIONS] Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else { return }
DispatchQueue.main.async {
WKExtension.shared().registerForRemoteNotifications()
self.onRemoteNotificationRegistration()
}
}
}
private func onRemoteNotificationRegistration() { }
func didRegisterForRemoteNotifications(withDeviceToken deviceToken: Data) {
// Convert token to string
let deviceTokenString = deviceToken.map { data in String(format: "%02.2hhx", data) }.joined()
print("[WATCH PUSH NOTIFICACTIONS] Device Token: \(deviceTokenString)")
UserSettings.shared.deviceToken = deviceTokenString
}
func didFailToRegisterForRemoteNotificationsWithError(_ error: Error) {
print("[WATCH PUSH NOTIFICATIONS] Failed to register device: \(error)")
UserSettings.shared.deviceToken = nil
}
func didReceiveRemoteNotification(_ userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (WKBackgroundFetchResult) -> Void) {
print("[WATCH PUSH NOTIFICATIONS] Push notification received: \(userInfo)")
let aps = userInfo["aps"] as! [String: AnyObject]
completionHandler(.noData)
}
}
extension ExtensionDelegate: UNUserNotificationCenterDelegate {
// show notification also when in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
print("[WATCH PUSH NOTIFICATION] Will present notification...")
let categoryIdentifier = notification.request.content.categoryIdentifier
let category = NotificationCategory(rawValue: categoryIdentifier)
if category == NotificationCategory.NotificationCategory {
} else if category == NotificationCategory.ActivityCategory {
}
completionHandler([.alert, .badge, .sound])
}
// called when tapped onto notification banner
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("[WATCH PUSH NOTIFICATION] Did receive notification response")
let userInfo = response.notification.request.content.userInfo as! [String: AnyObject]
let aps = userInfo["aps"] as! [String: AnyObject]
let categoryIdentifier = response.notification.request.content.categoryIdentifier
let category = NotificationCategory(rawValue: categoryIdentifier)
if category == NotificationCategory.NotificationCategory {
} else if category == NotificationCategory.ActivityCategory {
}
handleNotificationAction(response.actionIdentifier)
openNotification(userInfo: userInfo)
completionHandler()
}
}
extension ExtensionDelegate {
private func handleNotificationAction(_ actionIdentifier: String) {
let action = NotificationAction(rawValue: actionIdentifier)
if action == NotificationAction.Call {
print("Action: Call handled!")
} else if action == NotificationAction.Email {
print("Action: Email handled!")
} else if action == NotificationAction.Message {
print("Action: Message handled!")
}
}
private func openNotification(userInfo: [String: AnyObject]) {
// let something = userInfo["something"] ...
}
}
extension ExtensionDelegate {
private func showNotificationsNotGrantedAlert() {
let settingsActionTitle = NSLocalizedString("Settings", comment: "")
let cancelActionTitle = NSLocalizedString("Cancel", comment: "")
let message = NSLocalizedString("You need to grant a permission from notification settings.", comment: "")
let title = NSLocalizedString("Push Notifications Off", comment: "")
let settingsAction = WKAlertAction(title: settingsActionTitle, style: .default) {
print("[WATCH PUSH NOTIFICATIONS] Go to Notification Settings")
}
let cancelAction = WKAlertAction(title: cancelActionTitle, style: .cancel) {
print("[WATCH PUSH NOTIFICATIONS] Cancel to go to Notification Settings")
}
WKExtension.shared().rootInterfaceController?.presentAlert(withTitle: title, message: message, preferredStyle: .alert, actions: [settingsAction, cancelAction])
}
}
I've added Push notification Entitlement in WatchExtensions
I am sending notification from Push Notification Tester app using valid TeamId, P8 cert, P8 key, bundle Id -> where I am getting success.
I am sending default test notification nothing special
{
"aps": {
"alert": {
"title": "Silver Salmon Creek",
"body": "You are within 5 miles of Silver Salmon Creek."
},
"category": "Notification"
}
}
I have similar code for iOS and there notification are delivered correctly on iPhone.
UPDATE
I've tested a little bit more
And I have application added to my iPhone app
but iPhone app is for iOS 13
and Watch app is for WatchOS 6
So as I understand this WatchOS app can be install as standalone application.
I have checked "Support running without iOS App installation"
So as I understand my server should send this notification to both
Watch device Token and iOS device token. And there APNS/iOS/watchOS take the decision if there is duplicated notification where to deliver this notification i.e. to iPhone / watchOS.
If there is only watchOS app I think it will be delivered to watch Device token
If there is both watch/iOS app then it will send to iOS and then device whether user is using iPhone/Watch in given moment and deliver it to currently used device.
So now if I send notification to iPhone device token with iOS bundle identifier, and have locked iPhone and watch on wrist I am getting notification on my WatchOS and even can look at long notifications with dynamic content.
But when I've uninstall iOS version of application, and send notification with iPhone or watch device token and appropriate bundle id iOS/watchOS then for standalone app I am not getting this notification delivered again.
I encountered a similar issue, be sure your p8 Bundle ID is using the explicit WatchkitApp ID and not the Extension's ID.
Once I dropped the .watchkitextension and uninstalled (the app), reinstalled, reregistered the device, it worked.
I found the issue. It was related with the way Push Notification is send from the server using node-apns. I also have old Push Notification Tester app. 3.0 version of node-apns is required. there is additonal Header field send to APNS server
apns-push-type

how to integrate Callkit with Agora VOiP in swift 4 iOS?

I want to integrate apple Callkit with Agora VOiP in swift 4 iOS.
Please give any suggestions How can I do that.
To integrate voip, you will have to use both, callKit and PushKit.
CallKit will be used to show native call screen and handlers during in call transition while Pushkit will be used to invoke app, when app is killed.
Its easy to integrate:-
Enable background modes in info.plist and check option "App provides Voice over IP services".
Import Callkit in the viewcontroller viewdidload/ any init method of anyclass you would use to Implement CXProviderDelegate functions. Through this you will configure call objects, when to report in comming call, accept actions, reject action etc.
Implement the following functions:
func providerDidReset(_ provider: CXProvider) {
}
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
action.fulfill()
}
func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
action.fulfill()
}
Now import Pushkit and implement PKPushRegistryDelegate functions.
a.)Configure pushkit like this
let registry = PKPushRegistry(queue: nil)
registry.delegate = self
registry.desiredPushTypes = [PKPushType.voIP]
b.) implement pushkit token function. You may have to update to server for delivering voip push notifications
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
print(pushCredentials.token.map { String(format: "%02.2hhx", $0) }.joined())
}
c. Now when you receive incomming notification, implement this fuction
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: #escaping () -> Void) {
let config = CXProviderConfiguration(localizedName: "App name")
config.iconTemplateImageData = UIImagePNGRepresentation(UIImage(named: "any image name")!)
config.supportsVideo = true;
let provider = CXProvider(configuration: config)
provider.setDelegate(self, queue: nil)
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .generic, value: "Caller name")
update.hasVideo = true
provider.reportNewIncomingCall(with: UUID(), update: update, completion: { error in })
}
Go to developer portal and generate VoIP Services certificate and install it.
Enable push notifications under Capabilities.
This was a basic code over view. You will have to add cases to simulating incomming call and other customizations. I hope this will help you to move further.

How to use Google idToken, accessToken from my hosted server into my app?

Forgive me for my English!
I am using google Rest API client and GIDSignIn to sign in google account for my app.
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().scopes = scopes
GIDSignIn.sharedInstance().signIn()
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
showAlert(title: "Authentication Error", message: error.localizedDescription)
self.service.authorizer = nil
} else {
self.service.authorizer = user.authentication.fetcherAuthorizer()
print("Successs")
}
}
Successfully signed in after using this.
But I want to use idToken and accessToken into my app getting from my hosted server.
By using those token I want to fetch google calendar events.
Please help how can I use tokens which are getting from my hosted server into my iOS app.
Thanks.

get the token from wkwebview after login in ios swift

I am loading a url in wkwebview for login. After successful login it will redirect it to inner page, from there when click a button it will redirect to another page where token is generated. After token is generated how to push that to swift application. I need to take that token for further use in my app. Please help with a complete solution
This is my code
override func loadView()
{
super.loadView()
let url = URL(string: "urlString")
let request = URLRequest(url:url!)
let config = WKWebViewConfiguration()
self.webView = WKWebView(frame: self.view.bounds, configuration: config)
webView?.load(request)
self.view.addSubview(webView!)
}
How to proceed further to get the token
add message name in your user content controller in your config
config.userContentController.add(self, name: "setToken")
add following extenstion in your view controller
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
if (message.name == "setToken"){
if let token = message.body as? String{
print(token)
}
}
print("Received message from native: \(message)")
}
}
pass your token from js
window.webkit.messageHandlers.setToken.postMessage(TOKEN_STRING);