Facebook iOS SDK 3.0 - session not open - objective-c

I am using the latest Facebook iOS SDK 3.0
I need a help in in the login process:
First I declare this property in AppDelegate.h:
#property (nonatomic, strong) FBSession *session;
and in ViewController class I get this to use it in the code as this:
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
[delegate.session someproperty];
I also have this method in ViewController that get called from viewDidLoad:
-(void)login
{
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
[delegate.session accessToken];
NSLog(#"%d",delegate.session.isOpen);
if (!delegate.session.isOpen)
{
delegate.session = [[FBSession alloc] init];
if (delegate.session.state == FBSessionStateCreatedTokenLoaded)
{
[delegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error)
{
NSLog(#"%d", delegate.session.isOpen); // First Line //////////////////
}];
}
NSLog(#"%#", delegate.session.description); // Second Line //////////////////
}
}
After the facebook app get authorized the firs NSLog print zero, and the second NSLog indicate that the session state is FBSessionStateCreated not FBSessionStateOpen?
this is the output for the second NSLog:
2012-08-16 18:37:24.327 Facebook3[2418:f803] <FBSession: 0x6890ff0, state: FBSessionStateCreated, loginHandler: 0x0, appID: 193716877424306, urlSchemeSuffix: , tokenCachingStrategy:<FBSessionTokenCachingStrategy: 0x6890f20>, expirationDate: (null), refreshDate: (null), attemptedRefreshDate: 0001-12-30 00:00:00 +0000, permissions:()>
What I am missing here.
Note : in the app setting at https://developers.facebook.com I configure the app as this:
1- Configured for iOS SSO: Enabled
2- iOS Native Deep Linking: Enabled
3- iOS Bundle ID : com.mycompany.appname

i used this framework for my project. it works properly.
this is my related code
-(IBAction)logIn:(id)sender;
{
AppDelegate *appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (!FBSession.activeSession.isOpen) {
[appdelegate sessionOpener];
}
else {
[self loginHelp];
}
and my sessionOpener function is;
-(void) sessionOpener
{
[FBSession sessionOpenWithPermissions:nil
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// session might now be open.
if (!error) {
[self.viewController loginHelp];
}
}];
NSLog(#"%d", FBSession.activeSession.isOpen);
NSLog(#"%#", FBSession.activeSession.description );
}
it works for me. may be helpful to you.
and my console print is:
1
2012-08-16 22:24:55.899 TaraftarlikOyunu[838:c07] <FBSession: 0xd2512c0, state: FBSessionStateOpen, loginHandler: 0xd250240, appID: 433294056715040, urlSchemeSuffix: , tokenCachingStrategy:<FBSessionTokenCachingStrategy: 0xd24fda0>, expirationDate: 2012-10-15 19:02:34 +0000, refreshDate: 2012-08-16 19:05:03 +0000, attemptedRefreshDate: 0001-12-30 00:00:00 +0000, permissions:(
)>

I had the same problem as you and I had mixed between using FBSession and instance of FBSession when calling handleOpenURL. I changed from
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
[FBSession.activeSession facebookSession handleOpenURL:url];
}
to this
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
[session facebookSession handleOpenURL:url];
}

Related

iOS13 application openUrl? (Obj-C)

How do you import files to your app on ios13?
Previously I could download a txt file in Safari and chose Copy to (app) and I would catch this in the app delegate open Url delegate. Doesn't work anymore.
The Copy To is still there in Safari, but it just dismissed Safari and nothing happens.
-- Edit:
Sorry, I was a bit unclear.
Previously, when downloading a file through another app (like Safari), the user could select to open this file in my app by tapping "Copy To (app)".
I would then catch this copy request through the appdelegate:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
[...]
}
This delegate is not called in iOS13, only iOS12 and below.
I have tried finding a way to catch the "Copy to" request from other apps to no avail. There seems to be a new way of handling these things through a SceneDelegate?
In projects having SceneDelegate.swift file, should implement scene:openURLContext method.
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
print(#function)
print(URLContexts)
}
Output:
scene(_:openURLContexts:)
[
<UIOpenURLContext: 0x282fbca20;
URL: file:///private/var/mobile/Containers/Data/Application/A644621B-BD6C-443B-A9D1-A212EA59EE2E/Documents/Inbox/file.pdf;
options: <UISceneOpenURLOptions: 0x2823112c0;
sourceApp: (null);
annotation: (null);
openInPlace: NO>>
]
Reference: Migration from AppDelegate to SceneDelegate
Version for Objective C.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
[[CommonController sharedInstance] handleExternalUrl: url];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
NSLog(#"application openURL: %#", url);
return [[CommonController sharedInstance] handleExternalUrl: url];
}
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)){
NSSet *c = connectionOptions.URLContexts;
if(c && [c count] > 0)
{
NSURL *url = ((UIOpenURLContext*)[[c allObjects] firstObject]).URL;
[[CommonController sharedInstance] handleExternalUrl: url];
}
}
- (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet<UIOpenURLContext *> *)URLContexts
API_AVAILABLE(ios(13.0)){
NSURL *url = [[URLContexts allObjects] firstObject].URL;
[[CommonController sharedInstance] handleExternalUrl: url];
}

objective C FCM how to get remote message when app in background

my code can get remote notification and remote message, the last problem is can not getting remote message when app in background ( just open app then got it)
When i push remote notification and app in background, it's seem notification message show like expect, click to this notification then it bring me to my app. I dont know why remote message does not have some behavior like that( I using postman and "https://fcm.googleapis.com/fcm/send" to send remote message)
. Plz someone help me
Here is my code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register for remote notifications
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
// iOS 7.1 or earlier. Disable the deprecation warnings.
UIRemoteNotificationType allNotificationTypes =
(UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge);
[application registerForRemoteNotificationTypes:allNotificationTypes];
} else {
// iOS 8 or later
// [START register_for_notifications]
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
// iOS 10 or later
UNAuthorizationOptions authOptions =
UNAuthorizationOptionAlert
| UNAuthorizationOptionSound
| UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:authOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
}
];
// For iOS 10 display notification (sent via APNS)
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
// For iOS 10 data message (sent via FCM)
[[FIRMessaging messaging] setRemoteMessageDelegate:self];
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
// [END register_for_notifications]
}
// [START configure_firebase]
[FIRApp configure];
// [END configure_firebase]
// Add observer for InstanceID token refresh callback.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(tokenRefreshNotification:)
name:kFIRInstanceIDTokenRefreshNotification object:nil];
return YES;
}
// [START receive_message]
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// Print message ID.
NSLog(#"didReceiveRemoteNotification1 ID: %#", userInfo[#"gcm.message_id"]);
// Print full message.
NSLog(#"didReceiveRemoteNotification1 %#", userInfo);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// Print message ID.
NSLog(#"didReceiveRemoteNotification2 ID: %#", userInfo[#"gcm.message_id"]);
// Print full message.
NSLog(#"didReceiveRemoteNotification2 %#", userInfo);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
// Print message ID.
NSDictionary *userInfo = notification.request.content.userInfo;
NSLog(#"willPresentNotification: %#", userInfo[#"gcm.message_id"]);
// Print full message.
NSLog(#"willPresentNotification %#", userInfo);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
NSLog(#"didReceiveNotificationResponse: %#", userInfo);
}
- (void)applicationReceivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
NSLog(#"%#", [remoteMessage appData]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert" message:[NSString stringWithFormat:#"%#", [remoteMessage appData]] delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alert show];
}
- (void)tokenRefreshNotification:(NSNotification *)notification {
NSString *refreshedToken = [[FIRInstanceID instanceID] token];
NSLog(#"InstanceID token: %#", refreshedToken);
[self connectToFcm];
}
- (void)connectToFcm {
[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(#"Unable to connect to FCM. %#", error);
} else {
NSLog(#"Connected to FCM.");
}
}];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Unable to register for remote notifications: %#", error);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"APNs token retrieved: %#", deviceToken);
[[FIRMessaging messaging] setAPNSToken:deviceToken];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self connectToFcm];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[FIRMessaging messaging] disconnect];
NSLog(#"Disconnected from FCM");
}
For other people who face same problem.
Finally after a lot of searching, i found the solution, very simple, u need to follow the content of firebase app message to make it readable by push notification service. U can see here
and here
this is sample to make it show to device when in background mode :)
{
"condition": "'condition1' in topics && 'condition2' in topics",
"notification": {
"category": "notification_category",
"title_loc_key": "notification_title",
"body_loc_key": "notification_body",
"badge": 1
},
"data": {
"data_type": "notification_data_type",
"data_id": "111111",
"data_detail": "FOO",
"data_detail_body": "BAR"
}
}
Now everything work like expect, then the second job is just modify message content like whatever u want :)

NSURLSessionDataTask in appdelegate

I would call a NSURLSessionDataTask in appDelegate when the app is open from mail, so in this function
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
I tried but doesn't work, why??
I need to get a query from this function
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSURLComponents *components = [[NSURLComponents alloc] init];
components.query = [url query];
BOOL confirmRegistration = NO;
NSString *userToken;
for (NSURLQueryItem *queryItem in components.queryItems) {
if ([queryItem.name isEqualToString:#"userToken"])
{
userToken = queryItem.value;
}
else if ([queryItem.name isEqualToString:#"registrationType"])
{
if ([queryItem.value isEqualToString:#"confirmRegistration"])
{
confirmRegistration = YES;
}
}
}
//la app รจ stata aperta con la mail di conferma registrazione
if (confirmRegistration)
{
NSDictionary* userInfo = #{#"userToken": userToken};
[[NSNotificationCenter defaultCenter] postNotificationName:#"confirmRegistration" object:nil userInfo:userInfo];
}
return YES;
}
Thank you
When Application is opened from anywhere, the application:didFinishLaunchingWithOptions: is called.
There you check the launchingOptions to see what triggered the opening for application.
For instance, if application is opened using push notifications. You do something like below.
if let userInfo = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject : AnyObject] {
self.application(application, didReceiveRemoteNotification: userInfo)
}
You can check the keys which you get when you open the application from Mail.
UPDATE
There are keys like UIApplicationLaunchOptionsSourceApplicationKey and UIApplicationLaunchOptionsURLKey which you can print or compare to what triggered the application launch and then start your work.
When you open your application from Mail then print the following and use it to compare and start your work.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
print(launchOptions?[UIApplicationLaunchOptionsSourceApplicationKey])
print(launchOptions?[UIApplicationLaunchOptionsURLKey])
return true
}

Push Not Coming in Production

I am not getting push in production Mode . while it work fine in developer mode.Here is my code I am newer in iOS and i am first time implementation APN. Please help. I am stuck in lot of time.
if (iOSversion >=8) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication]registerForRemoteNotifications];
}
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)tokenss
{
NSUInteger rntypes;
NSString *device=[[UIDevice currentDevice]systemVersion];
int ar=[device intValue];
if (ar>=8) {
rntypes = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
}
NSString *deviceToken =[self stringWithDeviceToken:tokenss];
NSLog(#"Device token: %#", deviceToken);
callBackToken =deviceToken;
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
NSString *errorString = [NSString stringWithFormat: #"Error: %#", err];
NSLog(#"%#",errorString);
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:#"declineAction"]){
}
else if ([identifier isEqualToString:#"answerAction"]){
}
}
Such problems are due to current Provisioning Profile does not contain APNS information, as the Provisioning Profile is created BEFORE creating the APNS certificate.
Therefore, to solve the problem, create a new Provisioning Profile & select the Provisioning Profile in Xcode will clear the error.
Also, when you add push, I believe you have updated the certificates in keychain too.

Push notification delegate method issue

I am new to Objective C. In my app i need to implement push notification, i have created new app ID and i have created new provisioning profile also. i have finished all the steps mentioned in this link
i have declared this delegate function in my appDelegate .m file.
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *deviceTokens = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
deviceTokens = [deviceTokens stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"registered device token %#", deviceTokens);
self.deviceToken = deviceTokens;
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: #"Error: %#", err];
NSLog(#"String %#",str);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
for (id key in userInfo) {
NSLog(#"key: %#, value: %#", key, [userInfo objectForKey:key]);
}
}
But this delegate functions are not called. please help me to fix this issue.
In your AppDelegated didfinishLaunching with options write the following line
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
Add this code to your application didFinishLaunchingWithOptions method, inside your app delegate
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
//We check because ios7 cannot respond to this method and there will be a crash..
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
[application registerForRemoteNotifications];
}
else {
//This will work on ios7 devices and below
UIRemoteNotificationType types = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:types];
[application registerForRemoteNotifications];
}
return YES;
Use new delegate method
Swift:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)