Purpose of a static library - iphone

I want to create an application core that connects to a webservice, downloads the data, parses it and then returns it to a view controller. This core would ideally handle requests from multiple controllers and abstract away a lot of repetitive code. Also, I want to potentially use this core for a mac os x application. Would these tasks be a good idea for a static library? Also, how do I add a static library to my iPhone App? Once the static library is added, how do I reference it (i.e. import statements, etc..)?

I want to create an application core that connects to a webservice, downloads the data, parses it and then returns it to a view controller. This core would ideally handle requests from multiple controllers and abstract away a lot of repetitive code. Also, I want to potentially use this core for a mac os x application. Would these tasks be a good idea for a static library?
Yes.
Also, how do I add a static library to my iPhone App?
Add the static library's target to your project, then add its build product to your iPhone app's target. When you start work on your Mac OS X app, add the library build product to that target as well.
Once the static library is added, how do I reference it (i.e. import statements, etc..)?
#import is a preprocessor directive; you use it on a header file during the preprocessing stage of the compile-source-files phase.
Compiling the source files produces object files, which the linker will fuse (link) together in the next phase. This phase also includes the linker linking in any static libraries.
You must have the library build product (from the library target) added in the Link Binaries phase of the application target in order to have the linker link the library into your application.

There's no really good reason I can think of to create a static library unless you want to distribute it without distributing source. You have to re-compile for each platform, so you might as well just add the library .h and .m files from a common location (e.g. don't copy the file into the projects when adding them. The "Add Existing File..." selection will allow you to deselect the checkbox labeled "Copy items into destination group's folder (if needed)" when you add). Then, any changes you make to the library files will be updated in both projects. Building a static library just adds another layer of complexity (additional targets, etc.) that is unnecessary (IMHO, sorry to disagree Peter ;-) .
Best Regards.

Related

including a header from a project into a static library

I have a subproject (static library) inside my project.
As this static library may be used by a bunch of app, I have this config.h file on my project that contains the app configuration. The static library must read it.
The problem is that adding
#import "config.h"
on the static library fails, because the file cannot be found.
I could add an absolute path to my project root on the search headers, but I want to make this not hard coded because this static library will be used by other projects. Another problem is that I cannot use relative links like ../.., for example, because the static library is on another volume.
Including $(SRCROOT) on the search paths of the static library will give me the root for that library not for the project using it, that is what I want.
How do I solve that?
Just pay attention to my question. I am inside a static library that is used by a project. Config.h is out there in the project. I want to import that config.h on my static library.
If there is an easy way to do that, please tell me.
I have uploaded a sample project to here and here, so you can see my pain.
thanks
One way, somewhat of a hack, is to add a Run Script to each App's Build Phase, as the first item, and have it copy Config.h to some known place - /tmp/Config.h, and your included library will look for it there. Since the file is copied on every build, it will always be proper.
EDIT1: So not pretty, but you can add a Run Build Script to just under the Dependencies in the library. Just add one and leave the checkbox set to show environmental variables. You can see this one set:
FILE_LIST=/Volumes/Data/Users/dhoerl/Library/Developer/Xcode/DerivedData/MyProject-fdzaatzqtmrnzubseakedvxmsgul/Build/Intermediates/MyStaticLibrary.build/Debug-iphoneos/MyStaticLibrary.build/Objects/LinkFileList
What you can see is that several of these have as the prefix the current project folder:
/Volumes/Data/Users/dhoerl/Library/Developer/Xcode/DerivedData/MyProject-
You can write some script there to get the prefix, then append the local Config.h file path, and now you have a fully qualified path to the Config.h header, which you can then copy to a known location in the library. I'm going to post on the xcode forum as there may be a better solution - there use to be in Xcode 3. I'll update this if I get anything substantive back.
EDIT2: Try This:
1) Click on the library, click on Build Phases, add a Run Script Build phase by tapping bottom right '+' button
2) Drag it so its the second item in the list (below Target Dependencies)
3) Change the Shell to "/bin/ksh"
4) Paste this in, after editing it to have the proper files/paths:
# Get the Project Name (assumes upper/lower/numbers only in name)
PROJ=$(echo $BUILD_DIR | sed -En -e 's/(\/.*\/)([A-Za-z0-9]+)-([a-z]+\/Build\/Products)/\2/p')
# Use this variable to construct a full path
FULL_PATH="/Volumes/Data/Users/dhoerl/Downloads/nightmare/"$PROJ"/"$PROJ"/HelloWorldLayer.h"
echo FULL_PATH equals $FULL_PATH
# Make Sure MyStaticLibrary is correct
echo PROJ_DIR equals "$PROJECT_DIR/MyStaticLibrary"
cp -f "$FULL_PATH" "$PROJECT_DIR/MyStaticLibrary"
5) This assumes that you put the library anywhere you want, but each App project has to havethe same parent folder (not much of a restriction - what I did in the past).
PS: When I do this kind of thing, I usually don't include an actual file of the app, but create a header for a class that is not instantiated in the library. Lets call this Foo. So in your library, you have Foo.h, and it has lots of methods that return info - the number of widgets, the location of some special folder, plists, arrays, dictionaries, whatever. The idea is the library knows how to get whatever it needs through this interface (class singleton, or just a class with class methods. YMMV.
PSS: anyone else reading this, it pays to create demo projects.
I'd go a different route. Make this config.h file part of the static library using compiler symbols in it to switch features. Then in your projects define those symbols depending on what features you need.

Creating an IPA, "contains multiple products"

I am working on an email client based on ReMail. Basically, I reused the ReMail project so that the MailCore etc dependencies would be all set up out of the box so I could build a new app on top of them. I'm trying to give the app to some beta testers via ad hoc, but when I try to create an IPA, I receive this error:
xxxx does not contain a single–bundle application or contains multiple products. Please select another archive, or adjust your scheme to create a single–bundle application.
I have set Skip Install to YES for all dependencies, and moved all files under Copy Header to the "project" section, but I am still unable to build a single APP file.
I don't know if this is significant, but when I open up the xcarchive file, within the products directory, I find a the APP file under Applications, and then a file structure mirroring the absolute path to the header files for MailCore.
Any ideas as to what might be going on? I'm very near the tearing-out-chunks-of-hair-in-frustration stage, and I don't think the unnaturally bald crazy person look would suit me.
Thanks!
Try removing the “Copy Headers” phase entirely. It's only supposed to be used for frameworks, not static libraries. The Xcode static library template that includes a “Copy Headers” phase is wrong.
Check out the “Working with Schemes and Projects in Xcode” video from WWDC 2012, starting at 45m10s.

How to build a static library of an existing project in objective-c (.a file)?

I want to make .a file means static library of my project which I have made. How can I achieve this. Please provide me the the best solution, tutorial or any other links.
Thanks in advance
http://mobileorchard.com/sharing-compiled-code-building-static-libraries-in-xcode-for-the-iphone/ has a good tutorial.
Here are the basic steps:
Understand that XIB/NIB/Storyboard files have to be included separately from the library
Add a new target that is a static library
In the build settings for that library, include all of the .h and .m files that are relevant. For example, if your app uses a set of classes to access data and another set to view that data, you may want to just include the files relevant to accessing data.
Build. Use the script provided at Build fat static library (device + simulator) using Xcode and SDK 4+ so that you can use it for iPhone simulator + device.
Include your library + headers + any resources in relevant project.
With xcode4.2, easiest way is to new project, iOS/Framework & Library, CocoaTouch Static Library, and add all you files existed.
Here is the easiest tutorial with which i have built a static library in iphone. After building a static library you will import a .a library file and the header file .h in your new project and use them. Here is the tutorial link for making static library.

Do Objective-C unit test resources add to overall file size

I'm quite new to unit testing and I was wondering whether resources specific to the unit test add the the overall size of the app once it is built for the app store?
For example, I'm using set images for testing image manipulation. Will these add to the size of the built app?
They will not if you do not add them to the to the applications main target but the test target.
I assume you are using two targets.
Explanation:
When an application is build, all sources are compiled to objects and linked to each other to form an executable. Parameters are passed to make the application work on the correct platform.
Resources are not part of that. They are added to a folder in the application.
(A .app file is actually a directory, you can see this by right clicking it and select 'Show Package Content')
Files which are not added to your applications target will not be placed in this folder.
So your safe.
Hope this helps you.
I was wondering whether resources specific to the unit test add the
the overall size of the app
They won't if you don't include them in the app target. You'll generally have a separate target for your unit tests, and any resources needed for the tests but not for the app itself, such as test data, should be part of the test target and not part of the app target. You can use the Target Membership pane in Xcode's file inspector (in the Utilities) to set which targets a given file belongs to.

create our own frame work in iphone

There are lots of the frameworks available for different purposes, but I want to create framework library for my some of my classes -- in that all the .m files are loaded in single .a file and it's used with the list of header files.
Can any one tell me how to create a framework?
This webpage should give you the necessary information when creating your own framework.
http://accu.org/index.php/journals/1594
Hope this helps!
You can create a "Cocoa Touch Static Library" project in Xcode.