Problems building for both iOS4.3 and iOS5.0 - iphone

I'm running up against problems trying to incorporate some iOS5-specific libraries into an app targeted at both iOS5 and iOS4.3. I've gone through the following steps:
weakly-linked the Twitter framework by setting it as optional in 'Link Binary with Libraries"
added it as a framework for the iOS5.0 SDK in Other Linker Flags with `-framework Twitter.framework'
conditionally linked the framework in the class header:
#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
#import <Twitter/Twitter.h>
#import <Accounts/Accounts.h>
#endif
then in the method itself, I'm then checking whether the user's set up for Twitter:
if ([TWTweetComposeViewController class]) {
self.canTweet = [TWTweetComposeViewController canSendTweet];
}
This works beautifully on both the 5.0 and 4.3 simulators. However, I've got problems getting it to run on, or archive for, actual devices.
When I've got either a 3GS running 5.0, or a 4 running 5.0 attached, both show up twice in the Scheme dropdown. Selecting the top one, and attempting build or run the project fails with an Use of unidentified identifier 'TWTweetComposeViewController' error.
Using the second device entry, the build fails with a ld: framework not found Twitter.framework error.
I'm sure there's something I'm missing here, but I'm stumped. Can anyone advise?

If you are using a week linking then you have to check first availability of API using
NSClassFromString, respondsToSelector, instancesRespondToSelector etc.
So, change your if condition. First try to get your class object using above specified runtime function.
here is a link explaining in detail how to do such.
link

The code for presenting twitter controller
Before this you have to add the frameworks as optional and make the import in h file if iOS is min iOS 5
Class TWTweetComposeViewControllerClass = NSClassFromString(#"TWTweetComposeViewController");
if (TWTweetComposeViewControllerClass != nil) {
if([TWTweetComposeViewControllerClass respondsToSelector:#selector(canSendTweet)]) {
UIViewController *twitterViewController = [[TWTweetComposeViewControllerClass alloc] init];
[twitterViewController performSelector:#selector(setInitialText:)
withObject:NSLocalizedString(#"TwitterMessage", #"")];
[twitterViewController performSelector:#selector(addURL:)
withObject:url];
[twitterViewController performSelector:#selector(addImage:)
withObject:[UIImage imageNamed:#"yourImage.png"]];
[self.navigationController presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
}

Further digging into the error thrown back by the compiler suggested that it was ignoring the weak link flag. Although I've no idea how or why, it was fixed by a reinstallation of XCode.

if you link to 4.2 or later and deploy to 3.1 or later, you can use the new weak linking features to make this check simple.
you have to add Twitter frameworks as optional and then
Class TWTweetComposeViewControllerClass = NSClassFromString(#"TWTweetComposeViewController");
if (TWTweetComposeViewControllerClass != nil)
{
if([TWTweetComposeViewControllerClass respondsToSelector:#selector(canSendTweet)])
{
UIViewController *twitterViewController = [[TWTweetComposeViewControllerClass alloc] init];
[twitterViewController performSelector:#selector(setInitialText:)
withObject:NSLocalizedString(#"TwitterMessage", #"")];
[twitterViewController performSelector:#selector(addURL:)
withObject:url];
[twitterViewController performSelector:#selector(addImage:)
withObject:[UIImage imageNamed:#"yourImage.png"]];
[self.navigationController presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
}

Related

Use of undeclared identifier '_AppsFlyerdelegate'

I am not an iOS developer rather know bit of iOS and i am stuck at native side of iOS
So I was facing this issue on iOS
And I was trying this suggested answer
Here he says to add this and so I did
// AppsFlyer init here...
if(_AppsFlyerdelegate == nil){
_AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
}
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
[AppsFlyerLib shared].appsFlyerDevKey = #"YOUR_APPSFLYER_DEV_KEY"; // HACK: iOS SDK is faster than RN plugin
but I started getting these errors
Use of undeclared identifier '_AppsFlyerdelegate'
So I went to my pod file and added this (not sure if this sis correct)
pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'
config = use_native_modules!
use_react_native!(:path => config["reactNativePath"])
pod 'AppsFlyerFramework'
Did pod install, again ran the command but the error didn't went away? Any idea what I am doing wrong?
Also (not important) but can someone briefly explain me this code
if(_AppsFlyerdelegate == nil){
_AppsFlyerdelegate = [[RNAppsFlyer alloc] init];
}
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
[AppsFlyerLib shared].appsFlyerDevKey = #"YOUR_APPSFLYER_DEV_KEY"; // HACK: iOS SDK is faster than RN plugin
// React Native Bridge and Root View init here...
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc]
initWithBridge:bridge
moduleName:#"FiftyViewsUnderTheAppiumSea"
initialProperties:nil
];

App Crash due to FB sdk 3.2

I am using new FB IOS SDK and app crash and get below error
Assertion failure in -FBCacheIndex
_updateEntryInDatabaseForKey:entry:, /Users/chrisp/src/ios-sdk/src/FBCacheIndex.m Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: ''
* First throw call stack: (0x334072a3 0x3b0a197f 0x3340715d 0x33cdcb13 0x10b3b1 0x10b635 0x10a7bf 0x3b4b911f 0x3b4b899b 0x3b4b8895
0x3b4c7215 0x3b4c73b9 0x3b4eda11 0x3b4ed8a4)
I have made google and found solution like -lsqlite3.0 in other linker flag and add -lsqlite3 framework, FBsession missing. and i have done all but still i am getting same issue.
My code as below:
in FBClass.m which is NSObject type
-(void) getFriendListForInvitation
{
# try {
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Invite Friends";
self.friendPickerController.delegate = self;
[self.friendPickerController clearSelection];
[self.friendPickerController loadData];
self.friendPickerController.itemPicturesEnabled = TRUE;
}
else{
[self.friendPickerController clearSelection];
[self.friendPickerController updateView];
}
self.friendPickerController.allowsMultipleSelection = FALSE;
// iOS 5.0+ apps should use [UIViewController presentViewController:animated:completion:]
// rather than this deprecated method, but we want our samples to run on iOS 4.x as well.
if([[[UIDevice currentDevice] systemVersion] intValue] >= 5.0)
[[[appdelegate.navigationController viewControllers] lastObject] presentViewController:self.friendPickerController animated:TRUE completion:nil];
else
[[[appdelegate.navigationController viewControllers] lastObject] presentModalViewController:self.friendPickerController animated:YES];
}
#catch (NSException *exception) {
NSLog(#"%#",[exception description]);
}
}
Please help me to solve this issue.....
thanks
Did you manage to solve the issue? I suffer from the same problem.
I determined that this exception is caused by the missing file cache.db in the directory facebook is addressing to. You can check that with the help of the simulator. The directory of the missing simulator file is:
/Users/<user name>/Library/Application Support/iPhone Simulator/6.1/Applications/<app id>/Library/Caches/DataDiskCache
Yet I do not know why the file is missing.
EDIT:
The only thing I came up with was to clear the session data from the app with simple two lines of code:
FBSession.activeSession = nil;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"FBAccessTokenInformationKey"];
Unfortunately this solution never actually closes the session but at least it is providing the proper workflow of the app.

Game Center with iOS 5 SDK - leaderboardDelegate = self not working

I am still using iOS 5 SDK and Xcode 4.2 (Snow Leopard). I am adding Game Center to my game and while it passed authentication I get an ARC error whenever I try to show a leaderboard with this code (from Apple):
- (void) showLeaderboard: (NSString*) leaderboardID
{
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil)
{
**leaderboardController.leaderboardDelegate = self;**
leaderboardController.timeScope = GKLeaderboardTimeScopeToday;
leaderboardController.category = leaderboardID;
[self presentViewController: leaderboardController animated: YES completion:nil];
}
}
I get this error:
Passing "ViewController *const__strong' to parameter of incompatible type 'id <GKLeaderboardViewControllerDelegate>"
Is there any other solution than using iOS 6 SDK on lion?
Thanks!
Ah,
Found a similar problem, using id(self) fixed it;
Handling app delegates and switching between views
Should I delete this question>

What will happen to users running a lower version of IOS if new code is called?

I am fairly new to iOS Development and I've always wondered if a user running my application on iOS 4 were to try and run this code:
//POST TWEET//
- (void)showTweetSheet
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
tweetSheet.completionHandler = ^(TWTweetComposeViewControllerResult result) {
switch(result) {
case TWTweetComposeViewControllerResultCancelled:
break;
case TWTweetComposeViewControllerResultDone:
break;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Tweet Sheet has been dismissed.");
}];
});
};
[tweetSheet setInitialText:#"Check out this cool picture I found on #Pickr_"];
// Add an URL to the Tweet. You can add multiple URLs.
if (![tweetSheet addURL:[NSURL URLWithString:ImageHost]]){
NSLog(#"Unable to add the URL!");
}
[self presentViewController:tweetSheet animated:YES completion:^{
NSLog(#"Tweet sheet has been presented.");
}];
}
What would happen? Would the application just terminate with an error or will the code just not run? And how do I properly implement features that are OS specific? Would I just use something like this:
NSString *DeviceVersion = [[UIDevice currentDevice] systemVersion];
int DeviceVersionInt = [DeviceVersion intValue];
if (DeviceVersionInt > 5)
{
//do something.
}
else
{
//don't do a thing.
}
It will crash on iOS 4 if you write iOS5 features without checking if they are available or not. Try to implement Twitter like this
Class twClass = NSClassFromString(#"TWTweetComposeViewController");
if (!twClass) // Framework not available, older iOS
{
//use iOS4 SDK to implement Twitter framework
}
else {
//use Apple provided default Twitter framework
}
Make sure you have added Twitter Framework with weak link.
Id imagine that it would work the same as with any other api. If you link against a function which is not in a previous version, the program will crash on an attempt to call the function. Therefore, version switches are used, as you demonstrated, to avoid crashes.
The app would crash. If you want to implement features based on iOS, you can use a variety of methods. See this question.

Universal iOS app crashing on iPhone/iTouch 3.1.3 due to UIPopoverController

I just updated my app so that it's a universal app. In doing so I added support for UIPopoverController in a certain place. Now the app seems to be crashing on 3.1.3 iPhone/iTouch devices:
OS Version: iPhone OS 3.1.3 (7E18)
Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x00000001, 0xe7ffdefe
Crashed Thread: 0
Dyld Error Message:
Symbol not found: _OBJC_CLASS_$_UIPopoverController
What I don't get is that I'm only trying to call UIPopoverController if the hardware is an iPad:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:btc];
CGSize popoverSize = { 300.0, 500.0 };
popover.delegate = self;
popover.popoverContentSize = popoverSize;
self.bmPopover = popover;
[popover release];
[self.bmPopover presentPopoverFromBarButtonItem:self.bmBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
[self presentModalViewController:nav animated:YES];
}
I do have an iVar and a property of type UIPopoverController declared but I wouldn't have expected this to cause an issue at runtime if I didn't actually try to call methods in the class.
What am I supposed to do to make sure that the system doesn't try to link with UIPopoverController at runtime when this isn't supported?
For Universal app you should not only check if this is ipad or does this class exists but you should link UIKit as Weak reference a not default ( strong ), to do this:
get to target info
select general
in linked libraries change UIKit required to UIKit weak
Have fun making universal apps :]
Even though this code would most likely never run on the iPhone, it will still be linked and thus you are receiving the error. Before instantiating, you need to check if the class exists. You can modify your code above to the following which will fix it.
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Class UIPopoverControllerClass = NSClassFromString(#"UIPopoverController");
if (UIPopoverControllerClass != nil) {
UIPopoverController *popover = [[UIPopoverControllerClass alloc] initWithContentViewController:btc];
CGSize popoverSize = { 300.0, 500.0 };
popover.delegate = self;
popover.popoverContentSize = popoverSize;
self.bmPopover = popover;
[popover release];
[self.bmPopover presentPopoverFromBarButtonItem:self.bmBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
} else {
[self presentModalViewController:nav animated:YES];
}
Also, you could weak link against the UIKit framework, which would also solve the problem. I prefer the code solution as it is more safe.
You need to stop the compiler errors by referencing the class from a string. This should be used in tandem with UI_USER_INTERFACE_IDIOM() and will compile on an SDK that does not know about UIPopoverController. Here is an example:
Class popClass = NSClassFromString(#"UIPopoverController");
if(popClass) {
id infoPop = [[popClass alloc] initWithContentViewController:popViewController];
[infoPop presentPopoverFromRect:CGRectMake(20, 70, 10, 10) inView:self.view permittedArrowDirections:4 animated:YES];
}
The easy answer:
In your Xcode project, Select the top level project icon. Do a Get Info, go to the BUILD panel. set Configurations to All Configurations, set Show: to ** All Settings**
Set the iOS Deployment Target to iOS 3.1.
Recompile. Your program is failing because the minimum OS is set too high, so the loader can't resolve the symbol UIPopoverController. The change I just walked you through makes that symbol weak: it will resolve to NULL, but at least your program will load.
Are you loading a NIB file that implicitly creates a UIPopoverController? That's another way to crash.
I found it useful to add this, so that I could use UI_USER_INTERFACE_IDIOM() on pre-3.2 systems.
#ifndef __IPHONE_3_2 // if iPhoneOS is 3.2 or greater then __IPHONE_3_2 will be defined
typedef enum {
UIUserInterfaceIdiomPhone, // iPhone and iPod touch style UI
UIUserInterfaceIdiomPad, // iPad style UI
} UIUserInterfaceIdiom;
#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone
#endif // ifndef __IPHONE_3_2