I know that the openParentApplication api in watch kit extension can open the host app in the background but not in the foreground.
I also tried using openUrl() api of NSExtensionContext as below:
NSExtensionContext *ctx = [[NSExtensionContext alloc] init];
NSURL *url = [NSURL URLWithString:#"myScheme://today"];
[ctx openURL:url completionHandler:^(BOOL success) {
NSLog(#"fun=%s after completion. success=%d", __func__, success);
}];
[ctx completeRequestReturningItems:ctx.inputItems completionHandler:nil];
Here too the host app is not launched. Am I missing something? or is it not possible to
launch the host app from watch kit extension?
As of Beta 3 of iOS 8.2 it is currently not possible to open iOS app to foreground.
As you said openParentApplication can open app in background. Unfortunately there is no sign of API to open app on iPhone.
Multiple posts on Apple Dev Forums mentioned that it's not possible
https://devforums.apple.com/message/1076125#1076125
Correct, a notification can still declare a background action that the iPhone app will handle, so in that sense it can launch the iPhone app. But the iPhone app cannot be brought to the foreground by a WatchKit app.
And other post
https://devforums.apple.com/message/1082620#1082620
On a device, it[Watch app] will not - bring your iOS app to the foreground.
I'm hopeful that Apple will provide API for launching the parent app from a watch app in a future beta, but for now I've managed to achieve it by doing the following...
Call openParentApplication:reply: as normal:
- (void)openPhoneApp {
[WKInterfaceController openParentApplication:[NSDictionary new] reply:nil];
}
Implement application:handleWatchKitExtensionRequest:reply: in your AppDelegate, and launch itself using a custom URL scheme:
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"myappscheme://open"]];
}
If you need to open your parent app in the foreground, use Handoff!
https://developer.apple.com/handoff/
Example:
Somewhere shared for both:
static let sharedUserActivityType = "com.yourcompany.yourapp.youraction"
static let sharedIdentifierKey = "identifier"
on your Watch:
updateUserActivity(sharedUserActivityType, userInfo: [sharedIdentifierKey : 123456], webpageURL: nil)
on your iPhone in App Delegate:
func application(application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
if (userActivityType == sharedUserActivityType) {
return true
}
return false
}
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]!) -> Void) -> Bool {
if (userActivity.activityType == sharedUserActivityType) {
if let userInfo = userActivity.userInfo as? [String : AnyObject] {
if let identifier = userInfo[sharedIdentifierKey] as? Int {
//Do something
let alert = UIAlertView(title: "Handoff", message: "Handoff has been triggered for identifier \(identifier)" , delegate: nil, cancelButtonTitle: "Thanks for the info!")
alert.show()
return true
}
}
}
return false
}
And finally (this step is important!!!): In your Info.plist(s)
Related
What I am trying currently is to play a message when app receives remote notification while in the background (or likely woken up from a suspended state).
The sound is not playing at all after the app is woken from a suspended mode.
When application is in the foreground, a sound is played immediately after didReceiveRemoteNotification: method is called.
What would be an appropriate way to have sounds played immediately when didReceiveRemoteNotification: method is called while app is woken up from a suspended mode?
Here is the some code (speech manager class):
-(void)textToSpeechWithMessage:(NSString*)message andLanguageCode:(NSString*)languageCode{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
DLog(#"Activating audio session");
if (![audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:&error]) {
DLog(#"Unable to set audio session category: %#", error);
}
BOOL result = [audioSession setActive:YES error:&error];
if (!result) {
DLog(#"Error activating audio session: %#", error);
}else{
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:message];
[utterance setRate:0.5f];
[utterance setVolume:0.8f];
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:languageCode];
[self.synthesizer speakUtterance:utterance];
}
}
-(void)textToSpeechWithMessage:(NSString*)message{
[self textToSpeechWithMessage:message andLanguageCode:[[NSLocale preferredLanguages] objectAtIndex:0]];
}
And later on in AppDelegate:
[[MCSpeechManager sharedInstance] textToSpeechWithMessage:messageText];
I have enabled Audio,AirPlay and Picture in Picture option in Capabilities->Background Modes section.
EDIT:
Maybe I should start a background task and run expiration handler if needed? I guess that might work, but also I would like to hear the common way of solving this kind of situations.
Also with this code I get next error when I receive a notification in the background:
Error activating audio session: Error Domain=NSOSStatusErrorDomain
Code=561015905 "(null)"
Code 561015905 applies to:
AVAudioSessionErrorCodeCannotStartPlaying = '!pla', /* 0x21706C61,
561015905
And it is described as:
This error type can occur if the app’s Information property list does
not permit audio use, or if the app is in the background and using a
category which does not allow background audio.
but I am getting the same error with other categories (AVAudioSessionCategoryAmbient and AVAudioSessionCategorySoloAmbient)
As I cannot reproduce the error you are describing, let me offer a few pointers, and some code.
Are you building/testing/running against the latest SDK? There have been significant changes around the notification mechanism in iOS X
I must assume that the invocation to didReceiveRemoteNotification must occur in response to a user action from said notification, as tapping on the notification message for example.
There is no need to set any of the background modes save App downloads content in response to push notifications.
If all of the above statements are true, the present answer will focus on what happens when a notification arrives.
Device receives notification
User taps on message
App launches
didReceiveRemoteNotification is invoked
At step 4, textToSpeechWithMessage works as expected:
func application(_ application: UIApplication,
didReceiveRemoteNotification
userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler:
#escaping (UIBackgroundFetchResult) -> Void) {
textToSpeechWithMessage(message: "Speak up", "en-US")
}
For simplicity, I am using OneSignal to hook up notifications:
import OneSignal
...
_ = OneSignal.init(launchOptions: launchOptions,
appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
// or
_ = OneSignal.init(launchOptions: launchOptions,
appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
{
(s:String?, t:[AnyHashable : Any]?, u:Bool) in
self.textToSpeechWithMessage(message: "OneDignal", "en-US")
}
textToSpeechWithMessage is mostly untouched, here it is in Swift 3 for completeness:
import AVFoundation
...
let synthesizer = AVSpeechSynthesizer()
func textToSpeechWithMessage(message:String, _ languageCode:String)
{
let audioSession = AVAudioSession.sharedInstance()
print("Activating audio session")
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord,
with: [AVAudioSessionCategoryOptions.defaultToSpeaker,
AVAudioSessionCategoryOptions.mixWithOthers]
)
try audioSession.setActive(true)
let utterance = AVSpeechUtterance(string:message)
utterance.rate = 0.5
utterance.volume = 0.8
utterance.voice = AVSpeechSynthesisVoice(language: languageCode)
self.synthesizer.speak(utterance)
} catch {
print("Unable to set audio session category: %#", error);
}
}
Please implement
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
method. You'll get callback in background to play audio.
I need to register the user into the installation class in Parse after they login/register, but it does not register. There is no error printed, and when I breakpoint in the appdeleagate nothing happens.
viewDidLoad of viewcontroller after login/register
override func viewDidLoad() {
super.viewDidLoad()
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Sound, .Badge], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
AppDelegate
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation["user"] = PFUser.currentUser()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in
if (error == nil){
print("saved installation")
}else{
print("error \(error)")
}
})
}
To register to receive push notifications via Apple Push Service you have to call a registerForRemoteNotifications() method of UIApplication.
If registration succeeds, the app calls your app delegate object’s application:didRegisterForRemoteNotificationsWithDeviceToken: method and passes it a device token.
You should pass this token along to the server you use to generate push notifications for the device. If registration fails, the app calls its app delegate’s application:didFailToRegisterForRemoteNotificationsWithError: method instead.
you can refer this Appcoda's beginner guide for push notifiction
Update :
#pragma mark - push notificaiton
-(void)registerToReceivePushNotification {
// Register for push notifications
UIApplication* application =[UIApplication sharedApplication];
[application registerForRemoteNotificationTypes:
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound];
}
nd the two application delegate callbacks are in app delegate
// handle user accepted push notification, update parse
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken {
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:newDeviceToken];
// enable future push to deviceId
NSUUID *identifierForVendor = [[UIDevice currentDevice] identifierForVendor];
NSString* deviceId = [identifierForVendor UUIDString];
[currentInstallation setObject:deviceId forKey:#"deviceId"];
[currentInstallation saveInBackground];
}
// handle push notification arrives when app is open
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
}
You can do the registration call at any time - and it is a good idea to only do so when you know in the app you would like the user to receive push notifications.
The two application delegate callbacks have to be in your app delegate though, as you register for notification types on the application delegate and you only have one. I would suggest making an application delegate method to call that then does the registration, you could call it from your view controller through [[UIApplication sharedApplication] delegate] (cast the result of that call to your application delegate class).
code is in objective-c convert it in swift.
hope this will help :)
I am beginner write about IOS push with swift. It works when app is running in foreground but not work while app in background or close.
By the way, I can receive alert message by APNS.newPayload().alertBody when app is in background or close.
Thank u much for help.
Below is my server and ios code.
iOScode
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Recived: \(userInfo)")
var receiveMsg = userInfo["key1"] as! String
print("receiveMsg = \(receiveMsg)")
}
Server Code
ApnsService service =
APNS.newService()
.withCert("ooxx.p12","")
.withSandboxDestination()
.build();
String payload = APNS.newPayload().customField("key1", "M;senderGCMID5;senderUserID5;userName5;userMessage5").build();
String token = "token";
service.push(token, payload);
I have read some question about this topic, but I can not solve this problem.
I have tried the other function in iOS code like below, and it doesn't work.
APNS push working in foreground but not background
I don't know how to implement. Can u teach me ? thanks much
func application
(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
var receiveMsg = userInfo["key1"] as! String
print("receiveMsg = \(receiveMsg)")
}
thank pralthom for helping, I sovle the problem by setting content value = 1.
reference APN background refresh, setting up AppDelegate.m
I implemented the push notifications in Objective-C. I don't have the code in swift, but I guess it's very similar...
You have to register for push notification in the AppDelegate.
Add the following code in the didFinishLaunchingWithOptions delegate:
// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
// Register for Push Notifications before iOS 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
}
Then you have to add the following delegates also in the AppDelegate
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"DEBUG" message:[NSString stringWithFormat:#"Are you sure to use the right provisionning ? %#", error.localizedDescription] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
}
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//Do whatever you want with the push received
It works in background and also when the app is killed. The app status is different for the OS if the app is killed.
There is one more delegate to add: didRegisterForRemoteNotificationsWithDevicetoken.
After you call the registerForRemoteNotifications method of the UIApplication object, the app calls this method when device registration completes successfully. In your implementation of this method, connect with your push notification server and give the token to it. APNs pushes notifications only to the device represented by the token.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *formattedToken = [[[deviceToken description]
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]]
stringByReplacingOccurrencesOfString:#" "
withString:#""];
[[NSUserDefaults standardUserDefaults] setObject:formattedToken forKey:#"DEVICE_IDENTIFIER"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Send the device identifier to your server
I think you didn't register the device and that's the reason the push comes only when the app is in foreground.
When you test your push notification, you should reset the push notification settings of your iPhone. You can find how to do this in the following post: Reset push notification settings for app
I have an Xcode project in Swift with the following targets:
iOS App
WatchKit Extension / WatchKit App
"Common" Project, used by the "main" project and by the extension
In the common project I have the following code:
public class func scheduleNotification(seconds: Int) {
var notification = UILocalNotification()
notification.fireDate = NSDate().dateByAddingTimeInterval(NSTimeInterval(seconds))
notification.alertBody = "item"
notification.alertAction = "open"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["UUID": "XX", ]
notification.category = "CATEGORY"
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
I'm able to call this method AND fire a notification from the iOS APP:
#IBAction func XXX(sender: AnyObject) {
NotificationHelper.scheduleNotification(100)
}
But the same code executed from the WatchKit Extension doesn't fire any notification. The method IS called but then nothing happens on the iPhone or on the Apple Watch, no notifications are fired.
Can someone help me?
How can I schedule notification from the WatchKit Extension logic?
App extensions are not allowed to access sharedApplication. I'm guessing that sharedApplication is returning nil in your case, which would explain why the notification is not scheduled.
I'd suggest using something like openParentApplication:reply: to open your host iOS app in the background and schedule the notification from there.
I suppose you do NOT yet have the real device, but are using the simulator? Then you will probably not be able to send notifications to the Watch at all. This is because Apple has not (yet) added this feature to XCode.
To view and test your notification interface on the watch simulator, use a payload file as described here (paragraph "Specifying a Notification Payload for Testing"):
https://developer.apple.com/library/ios/documentation/General/Conceptual/WatchKitProgrammingGuide/ConfiguringYourXcodeProject.html
And do not have much confidence in a change of that coming soon/anymore. As it is described somewhere in the Watch Documentation, iOS will decide itself where to send your notification, anyway (when you finally made it to the hardware release...)
First of all run iOS app from WatchKit app:
NSDictionary *userInfo = #{#"text":#"Hello world!",
#"delay":#10.0};
[WKInterfaceController openParentApplication:userInfo reply:^(NSDictionary *replyInfo, NSError *error) {
// Completion
}];
Then handle on iOS device:
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
UIBackgroundTaskIdentifier tid = [application beginBackgroundTaskWithExpirationHandler:nil];
UILocalNotification *note = [[UILocalNotification alloc] init];
note.alertBody = userInfo[#"text"];
note.fireDate = [NSDate dateWithTimeIntervalSinceNow:[userInfo[#"delay"] doubleValue]];
note.timeZone = [NSTimeZone systemTimeZone];
note.userInfo = userInfo;
[application scheduleLocalNotification:note];
reply(nil); // Completion callback
[application endBackgroundTask:tid];
}
And of course do not forget to register iOS app for notifications:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil]];
return YES;
}
Problem:
Using the FB SDK and the method openActiveSessionWithReadPermissions, the completion handler doesn't appear to get called when the app is reopened from Facebook web or Facebook app and I get this error output:
FBSDKLog: FBSession INVALID transition from FBSessionStateCreated to FBSessionStateClosed
FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening
Context
Using Facebook SDK 3.2.1
App is built for iOS 5.0+
Using xCode 4.6.1
Testing on Simulator iOS 5.1
Testing on iPhone 4S, running iOS 6.1.2 (not using 6.0 social framework as want to test implementation for 5.0+)
Updating an app that was originally built for iOS 3.0 and using an old version of sharekit, but has now been updated for ARC and the share kit implementation I believe has all been commented out - hoping the issue is not a conflict with a old share kit function, can't fin any within the code
Steps taken to resolve
Searched throughout Stack Overflow, found similar issues mentioned but not a solution
ios6 facebook integration login always FBSessionStateClosedLoginFailed never opens (i already have bool:application implemented)
Facebook iOS SDK 3.0 - session not open
Facebook SDK 3.1 - Error validating access token
Have the correct app bundle in the FB settings panel
Have the correct Facebook app ID is the plist
Have FB logging turned on FBSettings setLoggingBehavior
Specifics:
These are the steps I took to implement Facebook connectivity within the app.
The first step I took was walking through the Facebook tutorial at: https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/. I got the first part, the authentication part working as expected (I built a separate app as instructed by the tutorial.)
I then took the same steps within the tutorial in the app I'm updating, this did not work
I then followed the instructions on https://developers.facebook.com/docs/howtos/login-with-facebook-using-ios-sdk/ (which are very similar to the tutorial)
Again I ran into issues
Then spent a lot of time searching for solution, could not find one
Highlevel steps in code:
I have my FB methods set up in AppDelegate
In a specific view controller I have a button that calls the openSessionWithAllowLoginUI method to start the login process
Code
AppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// set up facebook logging
[FBSettings setLoggingBehavior:[NSSet setWithObjects:FBLoggingBehaviorFBRequests, FBLoggingBehaviorFBURLConnections, FBLoggingBehaviorAccessTokens, FBLoggingBehaviorSessionStateTransitions, nil]];
// Call the ACAccountStore method renewCredentialsForAccount, which will update the OS's understanding of the token state
ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) &&
(accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){
NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
id account;
if (fbAccounts && [fbAccounts count] > 0 &&
(account = [fbAccounts objectAtIndex:0])){
[accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
//we don't actually need to inspect renewResult or error.
if (error){
}
}];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// We need to properly handle activation of the application with regards to Facebook Login
// (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
NSLog(#"Calling app did become active");
[FBSession.activeSession handleDidBecomeActive];
}
/*
* Callback for session changes.
*/
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
NSLog(#"Session State Changed");
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
NSLog(#"User session found");
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter]
postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
/*
* Opens a Facebook session and optionally shows the login UX.
*/
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSLog(#"Openning session with Facebook");
return [FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self sessionStateChanged:session
state:state
error:error];
}];
}
/*
* If we have a valid session at the time of openURL call, we handle
* Facebook transitions by passing the url argument to handleOpenURL
*/
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
NSLog(#"Calling open URL");
return [FBSession.activeSession handleOpenURL:url];
}
- (void) closeSession {
NSLog(#"Clossing Facebook Sessions");
[FBSession.activeSession closeAndClearTokenInformation];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
NSLog(#"handleOpenUrl Called");
return [FBSession.activeSession handleOpenURL:url];
}
View Controller with button
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// Register for Facebook change notification
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
}
- (IBAction)login:(id)sender {
ATIAppDelegate *myAppDelegate = (ATIAppDelegate *)[[UIApplication sharedApplication]delegate];
[myAppDelegate openSessionWithAllowLoginUI:YES];
}
What I think the issue could be?
It seems like it may be something with the tokens?
Or maybe the notification center?
Note that during testing I've been going and revoking access of the Facebook app to my account and then trying to login again to the app, I see these has caused issues with other users
Okay I figured it out - the issue was nothing to do with FB itself, the app (I'm working on updating someone else's code) had a setting in the .plist - 'Application does not run in background' set to true.
Meaning that once the app was relaunched from the Facebook app or Facebook mobile site it wasn't prepared to handle the next step.
If you don't want the app to run in the background, you can bind to the FBSDKApplicationDelegate in your AppDelegate like so:
import UIKit
import FBSDKLoginKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func applicationWillResignActive(_ application: UIApplication) {
FBSDKAppEvents.activateApp()
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
}
https://forums.developer.apple.com/thread/50332
http://ashishkakkad.com/tag/fbsdkapplicationdelegate/