NSInternalInconsistencyException - Could not load NIB in bundle: - iphone

I am trying to bundle all my .xib resources into a "ViewController.bundle" to ship along with "MyLibrary.framework". If I just place all the .xib files in the framework project, everything is working fine, but if I put them inside "ViewController.bundle", everything break apart
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Could not load NIB in bundle:
'NSBundle </Users/administrator/Library/Application Support/iPhone Simulator/5.0/
Applications/8AD68FD1-158E-4926-AE03-8FEF870E7012/ios.app/ViewController.bundle>
(not yet loaded)' with name 'FirstViewController_iPhone''
*** First throw call stack:
(0x160e052 0x1071d0a 0x15b6a78 0x15b69e9 0x3ff838 0x2a6e2c 0x2a73a9 0x2a75cb 0x2c2b89 0x2c29bd
0x2c0f8a 0x2c0d7e 0x2c0a22 0x2bfd88 0x5e3ac 0x2df8 0x2e34 0x160fec9 0x1e45c2 0x1e455a 0x289b76
0x28a03f 0x2892fe 0x209a30 0x209c56 0x1f0384 0x1e3aa9 0x1eedfa9 0x15e21c5 0x1547022 0x154590a
0x1544db4 0x1544ccb 0x1eec879 0x1eec93e 0x1e1a9b 0x2452 0x2385)
I have tried various ways:
1. Creating the "ViewController.bundle" in Finder, place all the .xib there, and drag to xcode
2. Create a new Target for the framework project, choose "Bundle" under "Framework & Library" in "OS X" section (Note: it has to be OSX since I am using xcode 4.6 which do not have "Bundle" under its "Framework & Library" - it used to have, and I used to create bundle that contains .png resources using this wizard)
Under both circumstances, I have made sure that the "ViewController.bundle" exist in "Build Phase" >> "Copy Bundle Resources" in my target app.
I also tried including "ViewController.bundle" under "Target Dependencies" of my Framework project, but all my efforts resulted in the same crash.
I also tried various ways to load the .xib, to no avail. However, the following code that load a .png resource from the same "ViewController.bundle" works perfectly:
// Loading .png resource works perfectly
// UIImage* closeImage = [UIImage imageNamed:#"ViewController.bundle/first.png"];
// NSString *szBundlePath = [[NSBundle mainBundle] pathForResource:#"ViewController" ofType:#"Bundle"];
// UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"showView" message:szBundlePath delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil];
// UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(220, 10, 40, 40)];
// [imageView setImage:closeImage];
// [alertView addSubview:imageView];
// [alertView show];
// return;
Using the same code to load the xib failed:
NSBundle *bViewController = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"ViewController" withExtension:#"bundle"]];
if ( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ) {
self.m_pFirstViewController = [[[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:bViewController] autorelease];
self.m_pSecondViewController = [[[SecondViewController alloc] initWithNibName:#"SecondViewController_iPhone" bundle:bViewController] autorelease];
} else {
self.m_pFirstViewController = [[[FirstViewController alloc] initWithNibName:#"ViewController.bundle/FirstViewController_iPad" bundle:nil] autorelease];
self.m_pSecondViewController = [[[SecondViewController alloc] initWithNibName:#"ViewController.bundle/SecondViewController_iPad" bundle:nil] autorelease];
}
/** It crash in this line!! Note however, both m_pFirstViewController and m_pSecondViewController is allocated and not nil */
self.viewControllers = #[self.m_pFirstViewController, self.m_pSecondViewController];
/** never reach here already crash */
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:self animated:YES completion:^{
NSLog( #"presented!" );
}];
I have spent the last 8 hours debugging this, googling and tried various suggestions from SO, but to no avail... any help is greatly appreciated! Thanks!

The 2nd way that I tried is the closest... Then modify the OSX bundle to iOS bundle in the Build Settings. Apparently, there are several steps that I missed. I followed the tutorial and sample project by Matt Galloway here:
http://www.galloway.me.uk/tutorials/ios-library-with-resources/
and now everything works as intended.
Thanks everyone for your help!

Related

#if TARGET_OS_IPHONE with iPhone and iPad

i have a problem, i want add different import file for iPhone and iPad, but for iPad doesnt' work, this is how i do:
#if TARGET_OS_IPHONE
#import "MyView_iPhone.h"
#elif TARGET_OS_IPAD
#import "MyView_iPad.h"
#endif
when in the code then i write for example:
MyView_iPhone *iphone = [MyView_iPhone alloc] init];
works, but:
MyView_iPad *iphone = [MyView_iPad alloc] init];
doens't work, give me an error, because doens't see the MyView_iPad.h, how i can do?
this is the error:
Unknown receiver 'MyView_iPad'; did you mean 'MyView_iPhone'?
<TargetConditionals.h> does not actually define a TARGET_OS_IPAD. You can't know at compile time whether you're executing for iphone or ipad! That is something you should check at runtime, importing both views and doing something like:
UIView *iphone;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
iphone = [[MyView_iPad alloc] init];
}
else{
iphone = [[MyView_iPhone alloc] init];
}

Apple Mach-O Linker error (APActivityIcon)

I've a problem! Sorry I'm new to programming and I dont know what to do. I implemented some code, to customize my ActivitiViewController. I created a new class, which I linked to my code:
- (IBAction)share:(id)sender
{
Class avcClass = NSClassFromString(#"UIActivityViewController");
if (avcClass) {
APActivityProvider *ActivityProvider = [[APActivityProvider alloc] init];
UIImage *ImageAtt = [UIImage imageNamed:#"MyApp Icon 512x512.png"];
NSArray *Items = #[ActivityProvider, ImageAtt];
APActivityIcon *ca = [[APActivityIcon alloc] init];
NSArray *Acts = #[ca];
UIActivityViewController *ActivityView = [[UIActivityViewController alloc]
initWithActivityItems:Items
applicationActivities:Acts];
[ActivityView setExcludedActivityTypes:
#[UIActivityTypeAssignToContact,
UIActivityTypeCopyToPasteboard,
UIActivityTypePrint,
UIActivityTypeSaveToCameraRoll,
UIActivityTypePostToWeibo]];
[self presentViewController:ActivityView animated:YES completion:nil];
[ActivityView setCompletionHandler:^(NSString *act, BOOL done)
{
NSString *ServiceMsg = nil;
if ( [act isEqualToString:UIActivityTypeMail] ) ServiceMsg = #"Mail sended!";
if ( [act isEqualToString:UIActivityTypePostToTwitter] ) ServiceMsg = #"Post on twitter, ok!";
if ( [act isEqualToString:UIActivityTypePostToFacebook] ) ServiceMsg = #"Post on facebook, ok!";
if ( [act isEqualToString:UIActivityTypeMessage] ) ServiceMsg = #"SMS sended!";
if ( done )
{
UIAlertView *Alert = [[UIAlertView alloc] initWithTitle:ServiceMsg message:#"" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil];
[Alert show];
}}];
.........However, I run the code, but I still get an error! My two files I created are named APActivityProvider. So now I get that error and dont know how to treat this. Whats the error of my architecture?
Any tipps, suggestions or solutions?
Thanks
Simple 4 Steps to follow :)
Step 1: Click on Project's name
Step 2: Click on Projects Name under Targets and select Build Phases Tab
Step 3: Check the compile source files list and add the missing files name by pressing the + button at the bottom
Step 4: Enter the file name and it will show the file in the search list, just Add it and you are done :)
**
Hope this will help :) Happy Coding
APActivityIcon.m is probably not being compiled with your app, when it probably should be.
If it's part of a library, then you will have to configure that library as a dependency in Xcode, then link your app to that static library.
You need to check if target architectures in linked libraries project details have every architecture of main target.
In other words, go to your project build settings, check Architectures line (by default you'll have armv7 and arv7s now) then iterate through every project of included libraries and check if they have the same.
If it is the problem with your architecture you can solve it by check on settings BuildActiveArchitectureOnly in your project as well as target build settings.
Refer this. Hope this helps. Happy Coding :)

Problems building for both iOS4.3 and iOS5.0

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];
}
}

Why is my AdMob code leaking in my iphone app?

I have included AdMob in my iphone app. I have the following code in my viewDidLoad method:
bannerView_ = [[GADBannerView alloc]
initWithFrame:CGRectMake(0.0,
0.0,
320,
50)];
// Specify the ad's "unit identifier." This is your AdMob Publisher ID.
bannerView_.adUnitID = ADMOB_BANNER_UNIT_ID;
// Let the runtime know which UIViewController to restore after taking
// the user wherever the ad goes and add it to the view hierarchy.
bannerView_.rootViewController = self;
[self.view addSubview:bannerView_];
// Initiate a generic request to load it with an ad.
GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
[bannerView_ loadRequest:r];
[r release];
This leaks. When I comment out the second last line ( [bannerView_ loadRequest:r]; ), the leak disappears. The only thing I changed in this code from the example provided by Google was to introduce the variable r so I could put AdMob in testing mode. In the code supplied by Google, bannerView_ is released by viewDidUnload. I looked for the loadRequest method but all I found was a definition in the GADBannerView.h file. As far as I can tell, there is no GADBannerView.m file, which seems weird in itself. Anyway, any tips would be much appreciated.
Thanks,
John
Why don't you use this AdMediator - it is very simple to configure and you don't have to worry about AdMob and iAds (if you want to use it) :
will swap in AdMob ads if no iAds are
available.
Are you releasing bannerView_ in your dealloc method or somewhere else appropriate ?
Instead of:
GADRequest *r = [[GADRequest alloc] init];
You could try:
GADRequest *r = [GADRequest request];

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