No interaction with Facebook iOS SDK dialog after switching to thread? - iphone

I'm playing around a little bit with the Facebook iOS SDK.
I have a TabBar App (with MainWindow.xib) and I successfully integrated the Facebook SDK.
The problem is that non of the Facebook pop up dialogs are responding to my user interactions.
For example. I want to post something in the wall. The Facebook SDK opens a dialog but if i try to interacte with the dialog it doesn't happen anything.
The log tells me: [Switching to process 2365 thread 0x12d07]
How can I fix it?
I'm using the simulator.
The important code int the AppDelegate looks like that, it's actually more or less the same like on developer.facebook.com:
Thank you a lot.
// AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate, FBSessionDelegate, FBDialogDelegate> {
Facebook *facebook;
}
#property (nonatomic, retain) Facebook *facebook;
#property (strong, nonatomic) IBOutlet UIWindow *window;
#property (strong, nonatomic) IBOutlet UITabBarController *tabBarController;
// AppDelegate.m
#implementation AppDelegate
#synthesize facebook;
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
facebook = [[Facebook alloc] initWithAppId:#"APP_ID" andDelegate:self];
if (![facebook isSessionValid]) {
[facebook authorize:nil];
}
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
#end
Kind regards.

You need a method that posts to a feed, like the one below
-(void)postToFeed
{
MyAppAppDelegate *sharedAppDelegate = (MyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
[sharedAppDelegate.facebook dialog:#"feed" andParams:params andDelegate:self];
}

I just hit this same problem. The problem for me was that my UIApplication keyWindow had userInteractionEnabled = NO. So not having that extra UIWindow present fixed it for me (more below).
I found this code in FBDialog.m
- (void)showWebView {
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) {
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
_modalBackgroundView.frame = window.frame;
[_modalBackgroundView addSubview:self];
[window addSubview:_modalBackgroundView];
....
so it's going to add the dialog to the keyWindow. I only had one window, so I thought. It turns out SVProgressHUD will create a new window with user interaction disabled and make it the key window (makes sense).
I'm guessing other HUD style things do this to. I was only showing the HUD while some prep work was done, so by the time I can show the dialog, I can remove it anyway. So that was my fix.
I dug this up by calling
NSLog(#"%#", [[UIApplication sharedApplication] windows]);
NSLog(#"%#", [UIApplication sharedApplication].keyWindow);
right before I was about to show the dialog and noticed
I had two UIWindow's
the key one's userInteractionEnabled was set to NO
Hope that helps.

Related

CLLocation Region Monitoring behaves differently in iOS 5.1 and iOS 6

UPDATE: I am looking for a workaround to this problem in iOS5.1. Currently, I have evidence that this issue in fact is known. However, I think it is related to an updated xcode rather than iOS5.1 actually region monitoring not working.
The simple code below behaves differently between iOS5 and iOS6. It works as expected in iOS6.
But in iOS5, the didEnterRegion callback is only triggered the first time the region is entered. If you exit the region, then re-enter the region, it will not be triggered. If you close and restart the app, entering the region will not trigger the callback.
The difference in behavior was seen on the iOS5 and iOS6 simulators. The broken iOS5 behavior was seen on an iPhone 4S with iOS5. Xcode 4.6 was used. CoreLocation framework was added properly, and locMan is a property of the AppDelegate. A clean new project was created for this test.
Can someone please find a workaround to this problem? The fix needs to use region monitoring, not active location updating.
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) CLLocationManager *locMan;
#end
// AppDelegate implementation file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
/// LocationManager
self.locMan = [[CLLocationManager alloc] init];
self.locMan.delegate = self;
CLLocationCoordinate2D coordinates = CLLocationCoordinate2DMake(40.0, 40.0);
CLLocationDistance distance = 100.0;
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:coordinates radius:distance identifier:#"hello"];
[self.locMan startMonitoringForRegion:region];
[self.window makeKeyAndVisible];
return YES;
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"didEnterRegion");
}
After leaving this question open for a week, I feel that I've enough evidence that region monitoring is broken in iOS5.1. Time to close out the question.

Trying to make my iphone app universal. Navigation Controller keeps saying Unbalanced calls

have been trying couple of hours now to make my iphone app universal. The mission was successful but have a strange problem. The navigation controller keeps pushing things without even pushing anything. The app doesn't crash but it gives me a message in the console
nested push animation can result in corrupted navigation bar
2012-02-06 10:52:07.701 ##$%^^$[54755:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2012-02-06 10:52:07.704 !##$%^$%#[54755:207] Unbalanced calls to begin/end appearance transitions for <searchEditViewController: 0xc652150>.
and here is how i've set app the whole thing :
![navigation screen shot][1]
here is my code in the AppDelegate_iphone.h
#import <UIKit/UIKit.h>
#import "iPhoneView.h"
#import "AboutUsViewController.h"
#import "FavoritesViewController.h"
#class iPhoneView;
#interface AppDelegate_iPhone : NSObject <UIApplicationDelegate> {
UITabBarController *tabBarController;
UINavigationController *homeNavigationController;
UINavigationController *favouritesNavigationController;
AboutUsViewController *aboutUsViewController;
iPhoneView * search;
FavoritesViewController *favoritesViewController;
UIWindow *window;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet iPhoneView *search;
#property (nonatomic, retain) FavoritesViewController *favoritesViewController;
#end
and here is on my AppDelegate.m file
#import "AppDelegate_iPhone.h"
#import "iPhoneView.h"
#implementation AppDelegate_iPhone
#synthesize window,search,favoritesViewController;
#pragma mark -
#pragma mark Application lifecycle
- (void)applicationDidFinishLaunching:(UIApplication *)application
{ tabBarController = [[UITabBarController alloc] init];
homeNavigationController = [[UINavigationController alloc] init];
search = [[iPhoneView alloc] init];
[homeNavigationController pushViewController:search animated:NO];
favouritesNavigationController = [[UINavigationController alloc] init];
favoritesViewController = [[FavoritesViewController alloc]init];
[favouritesNavigationController pushViewController:favoritesViewController animated:NO];
aboutUsViewController =[[AboutUsViewController alloc] init];
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:#"επικοινωνία" image:[UIImage imageNamed:#"aboutus"] tag:0];
aboutUsViewController.tabBarItem = item;
[item release];
UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:#"αγαπημένα" image:[UIImage imageNamed:#"favorites"] tag:0];
favouritesNavigationController.tabBarItem = item2;
[item2 release];
NSArray *tabBarControllerCollection = [NSArray arrayWithObjects:homeNavigationController,favouritesNavigationController,aboutUsViewController,nil];
[tabBarController setViewControllers:tabBarControllerCollection animated:NO];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
/*
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application {
/*
Called when the application is about to terminate.
See also applicationDidEnterBackground:.
*/
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
*/
}
- (void)dealloc {
[tabBarController release];
[search release];
[favoritesViewController release];
[favouritesNavigationController release];
[aboutUsViewController release];
[window release];
[super dealloc];
}
#end
OK solved had connected the button 2 times with the same action in IB. Took me 48hours to figure it out!

How to remove UINavigationViewController

I have created one navigationController in name_of_my_appAppDelegate.h...
After the use I want to remove it from the superview...
in my name_of_my_RootViewController I want to call it and remove.
How to call it?
In the NewsPadViewController, how to remove the NavigationController when I finished to use it?
#import <UIKit/UIKit.h>
#class NewsPadViewController;
#interface NewsPadAppDelegate : NSObject <UIApplicationDelegate>{
UIWindow *window;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#end
and this is the implementation
#import "NewsPadAppDelegate.h"
#import "NewsPadViewController.h"
#implementation NewsPadAppDelegate
#synthesize window;
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
- (void)dealloc
{
[navigationController release];
[window release];
[super dealloc];
}
#end
Check this out: UINavigationController Class Reference.
You probably want something like this:
[name_of_my_RootViewController popToRootViewControllerAnimated:YES];
Or:
[name_of_my_RootViewController.view removeFromSuperview];
Or:
for (UIView *v in self.view.subviews) {
if ([v isEqual:myView]) {
[myView removeFromSuperview];
}
}
Or:
[((NewsPadAppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController.view removeFromSuperview];
To remove the view controller you remove its view, like this:
[name_of_my_RootViewController.view removeFromSuperview];
Sounds like you should be presenting the UINavigationController modally in the first place. Set up a plain UIViewController called rootViewController and make that visible instead of the navigation controller, then call:
[rootViewController presentModalViewController:navigationController animated:YES];
And when you're done with it, hit a button on the navigation controller which calls:
[self dismissModalViewControllerAnimated:YES];
And you'll go back to the plain UIViewController where you can show the rest of your app.

fbDidLogin not called - iOS

I'm trying to implement facebook to my iOS app for a school project however I ran into a bit of a snag, namely the fbDidLogin method is not called.
I have created a sample object called FBFetcher as so:
#interface FBFetcher : NSObject <FBDialogDelegate,FBSessionDelegate,FBRequestDelegate> {
Facebook *facebook;
FBFetcher *facebookFetcher;
}
-(void)login;
#property (retain) Facebook *facebook;
#property (retain) FBFetcher *facebookFetcher;
#end
In the FBFetcher.m:
#implementation FBFetcher
#synthesize facebookFetcher,facebook;
-(void)login{
facebook = [[Facebook alloc] initWithAppId:#"...."];
NSArray *permissions = [[NSArray arrayWithObjects: #"offline_access",#"user_about_me", nil] retain];
[facebook authorize:permissions delegate:self];
}
-(void)fbDidLogin {
NSLog(#"Erfolgreich eingeloggt....");
}
#end
In my app delegate:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [[[controller facebookFetcher] facebook] handleOpenURL:url];
}
I have a separate view controller with n action tied to a UIButton:
facebookFetcher = [[FBFetcher alloc] init];
[facebookFetcher login];
I can access the login and authorization page, however the method fbDidLogin never gets called. Any suggestions?
The method never gets called because when you authorize, you are doing it in Safari. To take care of this, which I think is a bug from Facebook SDK by the way, open the facebook.m file and find the following line:
[self authorizeWithFBAppAuth:YES safariAuth:YES];
and change it to
[self authorizeWithFBAppAuth:NO safariAuth:NO];
This way you will never be sent to Safari, but everything will be done in a dialog.
Just test it and you'll see that the fbDidLogin method will get called.
Hope it will help
What about
- (void)fbDidNotLogin:(BOOL)cancelled
Does that get called?
Look for this function in Facebook.m. This is where Facebook calls your fbDidLogin function. First make sure this is being called, then debug into it. Make sure you've spelled/defined fbDidLogin correctly in your session delegate (no parameters). If not the respondsToSelector will fail and never call your delegate's function.
- (void)fbDialogLogin:(NSString *)token expirationDate:(NSDate *)expirationDate
{
self.accessToken = token;
self.expirationDate = expirationDate;
if ([self.sessionDelegate respondsToSelector:#selector(fbDidLogin)])
{
[_sessionDelegate fbDidLogin];
}
}

How to get started coding In-App Purchase

I am working on in-app purchase. In my application we added the following code in appdelegate:
#import "InappPurchaseAppDelegate.h"
#import "MainController.h"
#import "MKStoreManager.h"
#import "MKStoreObserver.h"
#implementation InappPurchaseAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[MKStoreManager sharedManager];
navigationController = [[UINavigationController alloc] init];
[window addSubview:navigationController.view];
MainController *frontController =[[MainController alloc] init];
[navigationController pushViewController:frontController animated:NO ];
[frontController release]; // Override point for customization after application launch
[window makeKeyAndVisible];
}
and added the following code in our controller:
#import "MainController.h"
#import "MKStoreManager.h"
#import "MKStoreObserver.h"
#import "InappPurchaseAppDelegate.h"
#implementation MainController
-(IBAction)InappPurchase:(id)sender
{
[[MKStoreManager sharedManager] buyFeatureA];
}
I also added storekit framework but when the button is clicked nothing happens.
All you need to know is here: http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Overview%20of%20the%20Store%20Kit%20API/OverviewoftheStoreKitAPI.html#//apple_ref/doc/uid/TP40008267-CH100-SW1
It shouldn't take you more than half a day to implement it (maybe a bit more if the content resides on your servers and is not already in the bundle).
The simplest explaination is that your button is not properly configured to send the action message. To test either set a breakpoint for the method or log it like:
-(IBAction)InappPurchase:(id)sender
{
NSLog(#"Buyid method called");
[[MKStoreManager sharedManager] buyFeatureA];
}
If the NSLog or breakpoint are never hit, you need to check the button in Interface Builder and make such it's action is set to the InappPurchase method.
If the InappPurchase method is being called by the button then the problem is in the MKStoreManger object.