Facebook - problems with "august_2012" platform migration - facebook

I am getting this warning message in an iOS app using FB auth:
ERROR:This endpoint has been deprecated.To temporarily reenable it,you may disable the "august_2012" platform migration. It will be disable permanently on August 1,2012.
The issue is to disable that migration for now. But, it was already disabled, so not sure how to fix this quickly - as opposed to updating the app and pushing it back out to the store which we will do.

I solved it by using the newest ShareKit Version (0.2.1), which I downloaded from GitHut but the same version is also avaliable on getsharekit.com/install.
Next i added the folder "ShareKit" located in "Classes" by drag&dropping in my XCode project (as usual).
For safety reasons, the previouse configuration file has been changed into a class. Set the configuration data for the sharingservices (FB, Twitter,...) in the class "DefaultSHKConfigurator.m". (Btw. I subclassed the DefaultSHKConfigurator so i still have the original structure)
To setup FB, change the settings:
- (NSString*)facebookAppId {
return #"..."; //app-id from facebook (create fb-app first, if not already done)
}
- (NSString*)facebookLocalAppId {
return #"";
}
Than in the application:didFinishLaunchingWithOptions: Method, set the ShareKonfiguration.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
DefaultSHKConfigurator *configurator = [[DefaultSHKConfigurator alloc] init];
[SHKConfiguration sharedInstanceWithConfigurator:configurator];
[configurator release];
//init the rest
..
}
After that, add an URL Scheme (in XCode 4.x select your project, select one target, click "Add"->"Add URL Type") and set the URL Scheme to "fb+your fb-app id" (mine looked like "fb35486..").
To let FB open your app and the user is immeditly able to post content, add
- (void) openFBWithURL:(NSURL*) URL {
if (URL != nil) {
NSString* scheme = [URL scheme];
NSString* prefix = [NSString stringWithFormat:#"fb%#", SHKCONFIG(facebookAppId)];
if ([scheme hasPrefix:prefix]) {
[SHKFacebook handleOpenURL:URL];
}
}
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
[self openFBWithURL:url];
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
[self openFBWithURL:url];
return YES;
}
Than it should be setup and ready for use.

Related

Duplicate declaration of method 'application:didRegisterUserNotificationSettings:'

I am working on "react-native-firebase": "^5.5.6", and "react-native-push-notification": "^3.1.9", using react native and I am stuck with error Duplicate declaration of method 'application:didRegisterUserNotificationSettings:' on appDelegate.m
I have tried various solutions found over web and If I comment one of the method, I got error "native module cannot be null"
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings {
[[RNFirebaseMessaging instance]
didRegisterUserNotificationSettings:notificationSettings];
}
// Required to register for notifications
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings
{
[RCTPushNotificationManager
didRegisterUserNotificationSettings:notificationSettings];
}
I need both the methods in my code without any error. I can use if else or other solutions as well but as I am new to this technology, therefore any help will be appreciated.
Thanks in advance!
I would not recommend mixing features however try this:
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings {
[[RNFirebaseMessaging instance]
didRegisterUserNotificationSettings:notificationSettings];
[RCTPushNotificationManager
didRegisterUserNotificationSettings:notificationSettings];
}
So you initialize both, in the same method. Again, not sure why you need both and you should try to keep only one.

How to take the text string from the push notifications?

I have an Iphone application in which i am recieving push notifications from the server.Now i am going to a view controller to show the message.Where that same message is loaded in a tableview .so thats not a problem.Now i am recieving two kinds of messages,one is a link and another is the message as earlier.if it is a link i want to open it in saffari,not need to go to tableview as usual.Can anybody help me to achieve this?
When You click on the push notification then you get a dictionary in the function - didReceiveRemoteNotification:
try this code:-
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"remote notification: %#",[userInfo description]);
if (userInfo)
{
if ([[userInfo allKeys] containsObject:#"aps"])
{
if([[[userInfo objectForKey:#"aps"] allKeys] containsObject:#"alert"])
{
if([[[userInfo objectForKey:#"aps"] allKeys] containsObject:#"alert"])
{
NSString *urlString = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
NSURL *url = [NSURL URLWithString:urlString];
if(url)
{
[[UIApplication sharedApplication]openURL:url]; // open in the safari...
}
else
{
// use the message in table view
}
}
}
}
}
}
The push notification is tied to your application, so in short its not possible to have a push notification from you application open safari directly. However, one workaround might go something like this:
user responds to notification (ie swipes to open it on the lock screen)
your app opens, and the data from the notification is passed into your applications
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method. You could then interrogate the the data passed in as so
NSDictionary *dictionary = [launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
// If dictionary is not nil, then your app is launched due to a push notification
if (dictionary != nil) {
NSDictionary *payload = [tmpDic objectForKey:#"aps"];
}
Once you've got your payload, look at the contents, and if it is a URL, call the safari URL scheme, passing in the URL. Like so
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: <URL from payload>]];
This will help you achieve what you want to do, but it may mean the user briefly sees your app first before the os will switch them into safari.
A side note, why would you want to do this? Your users should not be launching a random URL from a notification, and I don't think Apple would like that too much. Prehaps they should be seeing some information about the URL first in your app, and then choosing whether they would like to open it in safari?

Handling MKDirectionsRequest with iOS6 even when your app is compatible with iOS5

I want to make our app compatible with iOS6's MKDirectionsRequest (Transit Directions method). Apple states the best way to do this is:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([MKDirectionsRequest isDirectionsRequestURL:url]){
}
}
However, what is the best way to ensure this code is only run when the app is running in iOS6, and not iOS5? The app HAS to be compatible with iOS5 as well, but I MKDirectionsRequest is an iOS6.
I can't use compiler directives like:
#ifdefine iOS5
or anything.
Is this the best way?
BOOL atLeastIOS6 = [[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0;
and then:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if (atLeastIOS6)
{
if ([MKDirectionsRequest isDirectionsRequestURL:url]){
}
}
}
I just want to make sure I don't crash on iOS5 when checking for openURLs
Don't rely on iOS version. Check if the class exists by using NSClassFromString:
Class directionsRequestClass = NSClassFromString(#"MKDirectionsRequest");
if (directionsRequestClass)
// it exists, so you can use it
else
// doesn't exist, do something else
You can test if the class MKDirectionsRequest is available:
if ([MKDirectionsRequest class]) {
...
}
I have seen numerous posts that discouraged using the system version string. It might have to do with trickiness converting 6.0.1 to a float, but not sure.
The preferred method seems to be to test a selector that appeared in a specific version. As such, I use these two methods to test for iOS 5 or 6 respectively.
+ (BOOL)isOS5Capable {
return ( [UINavigationBar respondsToSelector:#selector(appearance)] );
}
+ (BOOL)isOS6Capable {
return ( [UIView respondsToSelector:#selector(requiresConstraintBasedLayout)] );
}
If you look through the headers in the Apple frameworks, you will see that there are quite a few NS_AVAILABLE macros that specify what version the selector appeared. To create this function for iOS 6, I hunted around for a few minutes to find a static method to simplify the check (so I wouldn't have to allocate a class). By following this practice, you should be able to ensure that your app is version safe for future updates.

How to create a custom alarm which can be set for random days in a week without using local notifications?

I have studied some of the following questions, that are::
1.) How to set alarm for selected days in iphone?
2.) iPhone alarm using repeated local notifications
3.) How to set the alarm in iPhone and save in local notification?
but they all are using local notifications. I am facing problem with local notification as I have to use three buttons on an Alarm View which are: Snooze, Ignore and Okay. I have to perform custom actions on each button click.
Please help me with this stuff.
Suggestions accepted.
Thanks in advance.
Kuldeep.
In you app delegate...
- (void) presentWidget: (NSString*)theDisplayedText {
BOOL widgetIspresent = [WidgetVC widgetIsCurrentlyPresented];
if (!widgetIspresent) {
WidgetVC *widgetVC = [[WidgetVC alloc] initWithNibName:#"WidgetVC" userInfoString:theDisplayedText bundle:nil];
widgetVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
widgetVC.userInfoStr = theDisplayedText;
[mainScreenManager presentViewController:widgetVC animated:YES completion:nil];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSLog(#"Recieved Notification didFinishLaunchingWithOptions %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
//here we have to handle whatever notification was pressed - that might also be an old aready passed one
//this all is checked when the widget opens - it will show if the notification is OK or too old
[self presentWidget: theDisplaytext ];
} else {
//so we started the app normally, not via local notification
[self presentWidget];
}
return YES;
}
// Handle the notificaton when the app is running
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotif {
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification didReceiveLocalNotification %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
[self presentWidget: theDisplaytext];
}
You need a way to start the UIViewController for the widget, I just created a mainScreenManager helper.
So on the widgetVC you have your "Snooze" and "OK" while the "Ignore" is just the ignoring of the notification itself.
Hope this gets you on an usable track...
ps I ported my app from Android to iPhone, that's why I used the name "widgetVC" for this screen. On Android it is implemented as a widget. Hope no iPhone lover feels offended :-)

How can my iPhone Objective-C code get notified of Javascript errors in a UIWebView?

I need to have my iPhone Objective-C code catch Javascript errors in a UIWebView. That includes uncaught exceptions, syntax errors when loading files, undefined variable references, etc.
This is for a development environment, so it doesn't need to be SDK-kosher. In fact, it only really needs to work on the simulator.
I've already found used some of the hidden WebKit tricks to e.g. expose Obj-C objects to JS and to intercept alert popups, but this one is still eluding me.
[NOTE: after posting this I did find one way using a debugging delegate. Is there a way with lower overhead, using the error console / web inspector?]
I have now found one way using the script debugger hooks in WebView (note, NOT UIWebView). I first had to subclass UIWebView and add a method like this:
- (void)webView:(id)webView windowScriptObjectAvailable:(id)newWindowScriptObject {
// save these goodies
windowScriptObject = newWindowScriptObject;
privateWebView = webView;
if (scriptDebuggingEnabled) {
[webView setScriptDebugDelegate:[[YourScriptDebugDelegate alloc] init]];
}
}
Next you should create a YourScriptDebugDelegate class that contains methods like these:
// in YourScriptDebugDelegate
- (void)webView:(WebView *)webView didParseSource:(NSString *)source
baseLineNumber:(unsigned)lineNumber
fromURL:(NSURL *)url
sourceId:(int)sid
forWebFrame:(WebFrame *)webFrame
{
NSLog(#"NSDD: called didParseSource: sid=%d, url=%#", sid, url);
}
// some source failed to parse
- (void)webView:(WebView *)webView failedToParseSource:(NSString *)source
baseLineNumber:(unsigned)lineNumber
fromURL:(NSURL *)url
withError:(NSError *)error
forWebFrame:(WebFrame *)webFrame
{
NSLog(#"NSDD: called failedToParseSource: url=%# line=%d error=%#\nsource=%#", url, lineNumber, error, source);
}
- (void)webView:(WebView *)webView exceptionWasRaised:(WebScriptCallFrame *)frame
sourceId:(int)sid
line:(int)lineno
forWebFrame:(WebFrame *)webFrame
{
NSLog(#"NSDD: exception: sid=%d line=%d function=%#, caller=%#, exception=%#",
sid, lineno, [frame functionName], [frame caller], [frame exception]);
}
There is probably a large runtime impact for this, as the debug delegate can also supply methods to be called for entering and exiting a stack frame, and for executing each line of code.
See http://www.koders.com/noncode/fid7DE7ECEB052C3531743728D41A233A951C79E0AE.aspx for the Objective-C++ definition of WebScriptDebugDelegate.
Those other methods:
// just entered a stack frame (i.e. called a function, or started global scope)
- (void)webView:(WebView *)webView didEnterCallFrame:(WebScriptCallFrame *)frame
sourceId:(int)sid
line:(int)lineno
forWebFrame:(WebFrame *)webFrame;
// about to execute some code
- (void)webView:(WebView *)webView willExecuteStatement:(WebScriptCallFrame *)frame
sourceId:(int)sid
line:(int)lineno
forWebFrame:(WebFrame *)webFrame;
// about to leave a stack frame (i.e. return from a function)
- (void)webView:(WebView *)webView willLeaveCallFrame:(WebScriptCallFrame *)frame
sourceId:(int)sid
line:(int)lineno
forWebFrame:(WebFrame *)webFrame;
Note that this is all hidden away in a private framework, so don't try to put this in code you submit to the App Store, and be prepared for some hackery to get it to work.
I created a nice little drop-in category that you can add to your project...
It is based on Robert Sanders solution. Kudos.
You can dowload it here:
UIWebView+Debug
This should make it a lot easier to debug you UIWebView :)
I used the great solution proposed from Robert Sanders: How can my iPhone Objective-C code get notified of Javascript errors in a UIWebView?
That hook for webkit works fine also on iPhone. Instead of standard UIWebView I allocated derived MyUIWebView. I needed also to define hidden classes inside MyWebScriptObjectDelegate.h:
#class WebView;
#class WebFrame;
#class WebScriptCallFrame;
Within the ios sdk 4.1 the function:
- (void)webView:(id)webView windowScriptObjectAvailable:(id)newWindowScriptObject
is deprecated and instead of it I used the function:
- (void)webView:(id)sender didClearWindowObject:(id)windowObject forFrame:(WebFrame*)frame
Also, I get some annoying warnings like "NSObject may not respond -windowScriptObject" because the class interface is hidden. I ignore them and it works nice.
One way that works during development if you have Safari v 6+ (I'm uncertain what iOS version you need) is to use the Safari development tools and hook into the UIWebView through it.
In Safari: Enable the Develop Menu (Preferences > Advanced > Show Develop menu in menu bar)
Plug your phone into the computer via the cable.
List item
Load up the app (either through xcode or just launch it) and go to the screen you want to debug.
Back in Safari, open the Develop menu, look for the name of your device in that menu (mine is called iPhone 5), should be right under User Agent.
Select it and you should see a drop down of the web views currently visible in your app.
If you have more than one webview on the screen you can try to tell them apart by rolling over the name of the app in the develop menu. The corresponding UIWebView will turn blue.
Select the name of the app, the develop window opens and you can inspect the console. You can even issue JS commands through it.
Straight Forward Way: Put this code on top of your controller/view that is using the UIWebView
#ifdef DEBUG
#interface DebugWebDelegate : NSObject
#end
#implementation DebugWebDelegate
#class WebView;
#class WebScriptCallFrame;
#class WebFrame;
- (void)webView:(WebView *)webView exceptionWasRaised:(WebScriptCallFrame *)frame
sourceId:(int)sid
line:(int)lineno
forWebFrame:(WebFrame *)webFrame
{
NSLog(#"NSDD: exception: sid=%d line=%d function=%#, caller=%#, exception=%#",
sid, lineno, [frame functionName], [frame caller], [frame exception]);
}
#end
#interface DebugWebView : UIWebView
id windowScriptObject;
id privateWebView;
#end
#implementation DebugWebView
- (void)webView:(id)sender didClearWindowObject:(id)windowObject forFrame:(WebFrame*)frame
{
[sender setScriptDebugDelegate:[[DebugWebDelegate alloc] init]];
}
#end
#endif
And then instantiate it like this:
#ifdef DEBUG
myWebview = [[DebugWebView alloc] initWithFrame:frame];
#else
myWebview = [[UIWebView alloc] initWithFrame:frame];
#endif
Using #ifdef DEBUG ensures that it doesn't go in the release build, but I would also recommend commenting it out when you're not using it since it has a performance impact. Credit goes to Robert Sanders and Prcela for the original code
Also if using ARC you may need to add "-fno-objc-arc" to prevent some build errors.
I have created an SDK kosher error reporter that includes:
The error message
The name of the file the error happens in
The line number the error happens on
The JavaScript callstack including parameters passed
It is part of the QuickConnectiPhone framework available from the sourceForge project
There is even an example application that shows how to send an error message to the Xcode terminal.
All you need to do is to surround your JavaScript code, including function definitions, etc. with try catch. It should look like this.
try{
//put your code here
}
catch(err){
logError(err);
}
It doesn't work really well with compilation errors but works with all others. Even anonymous functions.
The development blog is here
is here and includes links to the wiki, sourceForge, the google group, and twitter. Maybe this would help you out.
I have done this in firmware 1.x but not 2.x.
Here is the code I used in 1.x, it should at least help you on your way.
// Dismiss Javascript alerts and telephone confirms
/*- (void)alertSheet:(UIAlertSheet*)sheet buttonClicked:(int)button
{
if (button == 1)
{
[sheet setContext: nil];
}
[sheet dismiss];
}*/
// Javascript errors and logs
- (void) webView: (WebView*)webView addMessageToConsole: (NSDictionary*)dictionary
{
NSLog(#"Javascript log: %#", dictionary);
}
// Javascript alerts
- (void) webView: (WebView*)webView runJavaScriptAlertPanelWithMessage: (NSString*) message initiatedByFrame: (WebFrame*) frame
{
NSLog(#"Javascript Alert: %#", message);
UIAlertSheet *alertSheet = [[UIAlertSheet alloc] init];
[alertSheet setTitle: #"Javascript Alert"];
[alertSheet addButtonWithTitle: #"OK"];
[alertSheet setBodyText:message];
[alertSheet setDelegate: self];
[alertSheet setContext: self];
[alertSheet popupAlertAnimated:YES];
}
See exception handling in iOS7:
http://www.bignerdranch.com/blog/javascriptcore-example/
[context setExceptionHandler:^(JSContext *context, JSValue *value) {
NSLog(#"%#", value);
}];
First setup WebViewJavascriptBridge ,
then override console.error function.
In javascript
window.originConsoleError = console.error;
console.error = (msg) => {
window.originConsoleError(msg);
bridge.callHandler("sendConsoleLogToNative", {
action:action,
message:message
}, null)
};
In Objective-C
[self.bridge registerHandler:#"sendConsoleLogToNative" handler:^(id data, WVJBResponseCallback responseCallback) {
NSString *action = data[#"action"];
NSString *msg = data[#"message"];
if (isStringValid(action)){
if ([#"console.error" isEqualToString:action]){
NSLog(#"JS error :%#",msg);
}
}
}];
A simpler solution for some cases might be to just add Firebug Lite to the Web page.