Load xib file from framework - xcode

I'm creating some code which I've sorted into a framework - purely because I want to reuse this code elsewhere (other osx apps - not iOS).
Inside my Resources folder I created a xib file. One level higher in my root I have the corresponding Controller file.
If my client app is using storyboards - how would I go about loading this view? Note I did manage to access properties on the mentioned controller so I did all the hook up etc as described in Apple docs and elsewhere.
Thanks in advance!

You have to put the resources in a *.bundle, not a framework.
Just create a new target that's a bundle.
Then load the nibs with:
NSString *resourceBundlePath = [[NSBundle mainBundle] pathForResource:#"myBundle" ofType:#"bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
// load View Controller from that
UIViewController *vc = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:resourceBundle];

Solution: Here is a sample to load xib to create a view in the framework:
Create a new bundle (eg: MyBundle.bundle) and put your all resources (such as: xib, images, audio files, etc) into the new bundle.
Load xib:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString* path = [resourcePath
stringByAppendingPathComponent:#"MyBundle.bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:path];
if(bundle)
{
self.view = [[bundle loadNibNamed:#"MyXibNameWithoutSuffix" owner:nil options:nil] lastObject];
} else {
self.view = [[[NSBundle mainBundle]
loadNibNamed:#"MyXibNameWithoutSuffix" owner:nil options:nil] lastObject];
}
Load image:
UIImage* image = [UIImage imageNamed:#"MyBundle.bundle/MyImageName"];
if(nil == image) {
image = [UIImage imageNamed:#"MyImageName"];
}
If you're using cocopods, please make sure the s.resources has been
set in .podspec file.
s.resources = "MyBundle.bundle/**/*.{png,jpeg,jpg,storyboard,xib,xcassets,plist}"

Related

Creating a Cocoapod library and [UIImage imageNamed:] returns NULL

I have https://github.com/fulldecent/FDChessBoardView working great and am now starting the project again from scratch with pod lib create in order to make a Podspec.
There is one {'.h','.m'} file and some images. The images are in the file system in the provided Pod/Assets folder. The resources are noted in the podspec file with:
s.resource_bundles = {
'FDChessboardView' => ['Pod/Assets/*']
}
(I have also tried directly adding these files into the Development Pods/FDChessboardView/Resources group inside XCode.)
Inside the library implementation file I need to refer to these images. I have tried:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"FDChessboardView" ofType:#"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
NSString *imagePath = [bundle pathForResource:#"aa" ofType:#"png"];
UIImage* image = [UIImage imageWithContentsOfFile:imagePath];
Here the imagePath is set correctly. This file exists and file confirms it is a PNG:
[...]aa.png: PNG image data, 182 x 164, 8-bit/color RGBA, non-interlaced
However the UIImage is NULL.
I have also tried these:
image = [UIImage imageNamed:#"aa"];
UIImage *image = [UIImage imageNamed:#"FDChessboardView.bundle/aa.png"];
image = [UIImage imageNamed:#"aa" inBundle:bundle compatibleWithTraitCollection:nil];
All of them produce NULL.
Could anyone help point me in the correct direction for how to load theme image assets?
Thank you!
Will
Ok - I found a solution that works for me:
In the lib I am creating, I have the following class: AEBubbleField.h AEBubbleView.m
I also have an image in the Assets folder of the generated file structure called background.png. I want to use this in my lib files above so I add the following to the pod spec (to ensure the png is copied with my lib classes)
s.ios.resource_bundle = { 'AEBubbleField' => 'Pod/Assets/*.png' }
I can then access the image in the following manner:
NSBundle *bundle = [NSBundle bundleForClass:[self class]]; // Any class in the lib can be used here, I just went for the current class
UIImage *backgroundImage = [UIImage imageNamed:#"background.png" inBundle:bundle compatibleWithTraitCollection:nil];
This is the only way I can get the image and use it. All other methods I have tried simply return nil like the original question's.
this answer works for me.
https://stackoverflow.com/a/34324540/1897767
and, my swift code is:
class func loadImage(name: String) -> UIImage? {
let podBundle = NSBundle(forClass: MyClass.self)
if let url = podBundle.URLForResource("MyBundleName", withExtension: "bundle") {
let bundle = NSBundle(URL: url)
return UIImage(named: name, inBundle: bundle, compatibleWithTraitCollection: nil)
}
return nil
}
Rob's answer didn't work for me, I think because I didn't change the resource bundle setup from the default in pod lib create
s.resource_bundles = {
'PodCore' => ['Pod/Assets/*.png',
'Pod/Classes/**/*.xib',
'Pod/Classes/**/*.storyboard']
}
I was able to load images from that resource bundle, but had to define it explicitly.
NSString *bundleURL = [[NSBundle mainBundle] pathForResource:#"PodCore"
ofType:#"bundle"];
NSBundle *podBundle = [NSBundle bundleWithPath:bundleURL];
UIImage *image = [UIImage imageNamed:#"home_black.png"
inBundle:podBundle
compatibleWithTraitCollection:nil];
If you're using Swift 2 > you can access this way:
// should access the bundle for this class
let bundle = NSBundle(forClass: self.classForCoder)
// successfully loaded image
let myImageToUse = UIImage(named: "image", inBundle: bundle, compatibleWithTraitCollection: nil)

UIImage imageWithContentsOfFile: not working on iOS8

When I test my app on iOS8 beta3 and beta5, I found an bug that about [UIImage imageWithContentsOfFile:].
When image resources are stored in sub-bundle of a main bundle, it will return nil if we initialize UIImage via the following method:
NSString *testBundlePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"bundle”];
NSBundle *bundle = [NSBundle bundleWithPath:testBundlePath];
NSString *path = [bundle pathForResource:#"play.png" ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:path]; //iOS8 image = nil, iOS7 image != nil
But when the image resources are stored in main bundle, UIImage Initialization can be succeed through the following method:
NSString *path = [[NSBundle mainBundle] pathForResource:#"play.png" ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:path]; //iOS8 and iOS7 image != nil
We have found this problem under iOS8 beta3 and it still exists under iOS8 beta 5.
The Demo app directory structure was below:
XXX.app
|----test~ipad.bundle
|----play.png
|----test~iphone.bundle
|----play.png
|----play.png
|----play~iphone.png
|----play~ipad.png
......
Does anyone have the same problem? I think this is a bug on iOS8, Therefore, many apps have used bundle to organize resources, such as images. But now, this bug will make thousands of apps become ugly and hard to use. We really hope that Apple can fix this bug in the next version, otherwise, all of my app will have to developing an new version for this bug!
It's not actually broken, you're just sending it the wrong path.
I'm guessing that you are using the simulator, and have saved a file somewhere in your app and then made note of the full path to that file. However, when you rebuild your app the UUID for the installed app changes, and your saved path is no longer valid (even though the files are still there). You can see your current active path by checking [[NSFileManager defaultManager] currentDirectoryPath] Note that the value changes each time you rebuild and re-deploy your app.
To get to your actual file, you'll need to do something like this:
NSString *image = #"myImage.png";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cache = [paths objectAtIndex:0];
NSString *fullPath = [NSString stringWithFormat:#"%#/%#", cache, image];
UIImage *image = [UIImage imageWithContentsOfFile:fullPath];
pathForResource:ofType: only looks in the Resources folder (and localised folders). If you are placing files into dedicated folders in the bundle then you need to use pathForResource:ofType:inDirectory: and supply the directory name.
Apple has fixed this bug on iOS8.1,Cheers
just use
NSString *fullPath = [bundle pathForResource:name ofType:#"png"];
NSData *data = [NSData dataWithContentsOfFile:fullPath];
UIImage *image = [UIImage imageWithData:data];

Cannot open PDF file using UIWebView in iOS8beta5

I have working project in which i display pdf file in UIWebView
While testing my application in iOS8beta5 with XCode5, it did not work
In log it display failed to find PDF header : '%PDF' not found
I create sample application with below code which also have same problem
CODE :
self.myWebView.delegate = self;
NSString *path = [[NSBundle mainBundle] pathForResource:#"201" ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[self.myWebView loadRequest:request];
I read release note, Apple wrote that
Quicklook framework may did not display PDF file in some application
but they did not mention any thing about UIWebView,
Reference
NOTE :
This problem was not came in iOS8beta4.
Same problem is also occur in XCode6 + iOS8beta5.
I also check with different PDF files but have same problem.
QUESTION :
1] Is there any one had done fix for the above problem ?
If yes, please provide me some sample code.
I found a workaround for viewing the PDF in WebView
// Create pdf path & url
NSString *path = [[NSBundle mainBundle] pathForResource:#"201" ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
// Load pdf in WebView
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:targetURL];
[self.webView loadData:pdfData MIMEType:#"application/pdf" textEncodingName:#"utf-8" baseURL:nil];

MacOsX: ScreenSaver -- how to get the path to .saver bundle

I have a ScreenSaver project. In the Resources of this project presents the image file.
I'm trying to load it like this:
NSString* imageName = [[NSBundle mainBundle] pathForResource:#"DefaultImage" ofType:#"jpg"];
mpCurrentImage = [[NSImage alloc] initWithContentsOfFile:imageName];
But the path of mainBundle is
/Applications/System Preferences.app/Contents/Resources
How to get the path to the .saver bundle, to load the image from recourses?
You'd want to use
NSString* imageName = [[NSBundle bundleForClass:[self class]] pathForResource:#"DefaultImage" ofType:#"jpg"];
assuming that this code is in a class belonging to the bundle.

loadHTMLString baseURL:nil not working in iOS5

I got a problem with UIWebView. I want to render my own html code in UIWebView.
if I use the below code, it's working fine.
NSBundle *thisBundle = [NSBundle mainBundle];
NSString *path = [thisBundle pathForResource:#"foo" ofType:#"html"];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[self.webView loadHTMLString:#"foo.html" baseURL:baseURL];
I want to render the html with below code. But it's not working. foo.html contains exactly the same content with the NSString* one. Any hints? Thanks in advance. =)
NSString* one = #"<html><head><title></title></head><body><img src=\"image.jpg\"/></body></html>";
[self.webView loadHTMLString:one baseURL:nil] ;
I use this code that works perfectly :
NSString* htmlContent = #"<html><head><title></title></head><body><img src='image.jpg' /></body></html>";
[self.webView loadHTMLString:htmlContent baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
Bu sure that image.jpg is included into your project.
create JS file demo.js and add code
var hello = function(str){
      return str;
};
add UIWebView => To embed JavaScript in a dummy html file and load that into the UIWebView
[self.webView loadHTMLString:#"<script src=\"demo.js\"></script>"
              baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]]];
Here is the code to make JS call
NString *str=#"hi JavaScript";
NSString *function = [[NSString alloc] initWithFormat: #"hello(%#)", str];
NSString *result = [webView stringByEvaluatingJavaScriptFromString:function];
Now, there is one important safety tip to make this actually work: The UIWebView must actually be loaded a view. It doesn’t have to be visible, but in order for the WebKit engine to execute the JS, it must be on a view.

Resources