framework_ios_2

Universal Framework iPhone iOS (2.0)

Hello my friends,

Due to some bugs and questions with the old tutorial, I’m creating this new one, much more simpler and less bugs than the another one. I’ll not post the old link here because everything you need to know you can find right here.

Nowadays, exist few alternatives to create a Framework to iOS, changing the default Xcode Script, which could not be a good choice if you want to publish the APPs constructed with your custom Framework. I’ll treat here about how to construct an Universal Framework to iOS, using the default tools from Xcode.

Let’s start!


Here is a little list of contents to orient your reading:

List of Contents to this Tutorial

You can download the project I used in this article:

Download Xcode project files to iPhone
Download now
Xcode project files to Framework-iOS
403kb


FAQ

top
First off, I want to make sure you understand what this Framework to iOS can do, this can safe your time reading this article:

  1. Can I use this Framework as a Bundle to store my files, XIBs, images?
    A: Yes, you can and now it’s very very easy to retrieve your files.
  2. Can I use this Framework to import other Frameworks, like import UIKit, CoreGraphics, OpenGL?
    A: No. There is no way to do that. Your code in this custom Framework can import classes from other frameworks normally, but it is just a reference, classes from another framework will not be compiled at this time. So you must import the referenced Framework on the new project as well.
  3. Will be my code visible to others?
    A: No. This Framework will export a compiled binary, so anyone can see inside it. You can make the same for some other files, like XIBs.
  4. Why I need this?
    A: This is for developers/teams that want to share their codes without shows the entire code (.m/.c/.cpp files). Besides this is for who want to organize compiled code + resources (images, videos, sounds, XIBs, plist, etc) into one single place. And this is also for that teams that want to work together above the same base (framework).


Framework on iOS? Really?

top
Ok buddies, let’s make something clear, many people had said:”iOS doesn’t support custom Frameworks!”, “Custom Framework is not allowed at iOS!”, “Doesn’t exist custom Framework on iOS!” and many other discouraging things like these. Look, I’ve made many frameworks and worked with many others, I don’t believe that is really impossible to use a Framework on iOS. According to my experience and knowledge about Frameworks, it’s absolutely feasible a custom Framework on iOS Devices. If we think more about this issue we can find an elegant solution, right? First, let’s understand what a Framework really is, here is the definition of framework by Apple’s eyes:

A framework is a hierarchical directory that encapsulates shared resources, such as a dynamic shared library, nib files, image files, localized strings, header files, and reference documentation in a single package.

Doesn’t make many sense something with this description not be allowed in iOS, thinking in architecture and structure. Apple also says:

A framework is also a bundle and its contents can be accessed using Core Foundation Bundle Services or the Cocoa NSBundle class. However, unlike most bundles, a framework bundle does not appear in the Finder as an opaque file. A framework bundle is a standard directory that the user can navigate.

Good, now thinking about iOS security, performance and size, the only thing in a Framework definition which doesn’t fit in iOS technology is the “dynamic shared library”. The words “dynamic” and “shared” are not welcome in the iOS architecture. So the Apple allows us to work and distribute something called “Static Library“. I don’t like it! It’s not so easy as a Cocoa Framework, if a developer got your Static Library, he needs to set a header path too, or import the header files… it’s not useful, that’s a shit!

Well, so a Framework concept is absolutely compatible with iOS, except by the “dynamic shared library”, on the other hand Apple says that a “static library” is OK for iOS. So if we replace the “dynamic shared libraries” by a “static library” we could construct a Custom Framework to iOS, right?

Right!!!!

This is exactly what we’ll make in this article, let’s construct a Framework with Static Library, by the way, an Universal Framework.


Understanding Universal, Dynamic and Static concepts

top
Simple answer:

  • Universal: Which works perfect on all architectures. iOS devices uses armv6 and armv7, iOS simulator on MacOS X uses i386.
  • Dynamic: The compiler doesn’t include the target files directly. The classes/libraries are already pre-compiled (binary format) and lies on the system path. Besides, the dynamic libraries can be shared by many applications. This is exactly what Cocoa Framework is.
  • Static: It represents that classes/libraries which is compiled by the compiler at the build phase. These files can’t be shared by other applications and relies on application path.

Simple as that. If you need more informations about Dynamic VS Static libraries, try this Apple’s Documentation.

No more concepts, hands at work!


Constructing a Framework Project

top

1. Create the Project:

top
I want to show you step by step of the entire process, so let’s start with the most basic, create an iOS project. You can choose one application template in Xcode, this is not really important, but remember to choose one template which could test your Framework code before export it.

Create an application project.

Create an application project.


2. Framework Classes:

top

Create your framework classes.

Create your framework classes.

Remember to create an “import header” to make everything simpler and organized to the user of your framework. Remember to write this header file with a framework notation, just as shown in the image bellow. Also remember to create your classes taking care to hide the classes which should not be visible to the other developers (users of your framework). We will set the public and private headers soon, but it’s very important to you protect the “core” classes, I mean, that classes which you don’t want to make visible to other developers.

For those private classes, you could import their header inside the “.m” (or .mm, .cpp, etc) file of a public class, by doing this you protect the header of private classes. Well, I know you probably already know that, I’m saying just to reinforce.

Remember that organization is 90% of a good framework, so try follow all the Apple advices to create your classes names, methods, properties, functions, etc.


Creating the Framework

top

3. Create a Framework Target:

top
OK, let’s create a target to compile our framework. Click on the icon of your project in the project navigator at the left and hit the button “Add Target”. A new window will come up. Now is our first trick. Instead to create a “Cocoa Touch Static Library” or a “Cocoa Framework” we will create a “Bundle” target.

A Bundle? Really? Yes! I can explain. A “Cocoa Framework” target can’t be compiled to armv6/armv7 and Xcode doesn’t allow us to use “Static Libraries” in a “Cocoa Framework”, so we can’t use this target. On the other hand, we can’t use “Cocoa Touch Static Library” either, because it doesn’t use the framework structure that we want.

Now, the Bundle target could be the best choice. It can hold any file we want, we can compile source code inside it and… we can turn it into a framework. To say the truth, almost all “Framework & Library” targets could be turned into a framework too, even the “Cocoa Touch Static Library”, throughout this article you probably will figure out how. For now, let’s create a Bundle target.

Create a Bundle target rather than Cocoa Touch Static Library.

Create a Bundle target rather than Cocoa Touch Static Library.


4. Bundle Setup:

top
It’s time to make all the necessary changes to the Bundle target. Different than the old tutorial. You don’t need to clean up anything. Just know that everything else will be ignored (linked frameworks .plist files, .pch etc…).

I’m sure you already know this, but just to reinforce, here is the Build Setting screen, you can find it by clicking on the project icon in the left project navigator and then clicking in the “Build Setting” tab.

You must make a special Build Setting to turn a Bundle into a framework.

You must make a special Build Setting to turn a Bundle into a framework.

Here is our second great trick, or should be better to say “tricks”. Let’s change the “Build Setting” following this list:

  • Base SDK: Latest iOS (iOS X.X) (in the X.X will appear the number of the lastest iOS SDK installed on your machine).
  • Architectures: $(ARCHS_STANDARD_32_BIT) armv6 (it’s very important to be exactly this value including the space before “armv6″) This setting is valid to Xcode 4.2, if you are using an old version, use the “Standard (armv6 armv7)” option. (the values for this property depend on the value of the item bellow, so set that first).
  • Build Active Architecture Only: NO (otherwise we can’t compile to armv6 and armv7 at the same time).
  • Valid Architecture: $(ARCHS_STANDARD_32_BIT) (it’s very important to be exactly this value). If your Xcode is showing two lines with armv6 and armv7, delete then and insert this value in one single line.
  • Dead Code Stripping: NO.
  • Link With Standard Libraries: NO.
  • Mach-O Type: Relocatable Object File. This is the most important change. Here, we instruct the compiler to treat the Bundle as a relocatable file, by doing this, we can turn it into a framework with the wrapper setting.
  • Other Linker Flags: This setting is not mandatory, but if you are planning to use any kind of C++ code (.cpp or .mm) on this framework, Chris Moore (on the comments) advises to use the “-lstdc++” option. In this case could be a good idea to use “-ObjC” too, to avoid conflicts in old compilers.
  • Wrapper Extension: framework. Here we change the Bundle to a Framework. To Xcode, frameworks is just a folder with the extension .framework, which has inside one or more compiled binary sources, resources and some folders, a folder, usually called Headers, contains all the public headers.
  • Generate Debug Symbols: NO (this is a very important setting, otherwise the framework will not work on other computers/profiles).
  • Precompile Prefix Header: NO.
  • Prefix Header: “”. (Leave it blank).

IMPORTANT: Since the Xcode 4.x the architectures armv6 has no longer support. So, to create a real Universal Framework we must make a small “hack”:

  1. After change the settings above close the Xcode, find the .xcodeproj (the project file) in Finder and then “Show Package Contents”.
  2. Open the file “project.pbxproj” into a text editor.
  3. Delete all the lines with VALID_ARCHS = “$(ARCHS_STANDARD_32_BIT)”.


5. Adding code and resources to the Bundle (Framework)

top
It’s time to place the content in our framework and define the public headers. To do that, with the Bundle target selected, click on the “Build Phase” tab. At bottom, hit the button “Add Phase” and then “Add Copy Headers“.

Open the recently created “Copy Headers” section and separate your public headers from the private or project headers. The difference here is:

  • Public: Headers that other developers must know in order to work with your framework. In the final framework product, these headers will be visible even to Xcode.
  • Private: Headers that is not necessary to other developers, but is good for consult or for reference. These headers will not be visible to Xcode, but will be in the framework folder.
  • Project: Headers that the other developers nor Xcode have access. In reality these headers will not be placed in the final product, this is just to instruct the compiler to create your custom framework.

Now, open the “Compile Source” section and put there all your .m, .c, .mm, .cpp or any other compilable source file.

If your framework include not compilable files, like images, sounds and other resources, you can place them in the “Copy Bundle Resources” section. Later, when we generate the final framework, all your resources will be placed in a folder called “Resources”, but you can change it. That folder is very important, because it will be part of the path to retrieve your resources from the framework product.

Tip: To add many files at once, click on the “+” button and write the files’ extension on the search field. For example “.m”, “.c”, “.cpp”, “.h”, etc. This can save a lot of time.

This is how your “Build Phase” will looks like:

Define your compilable source and the headers.

Define your compilable source and the headers.


Building the Universal Framework

top

6. Creating Universal Target:

top
To join both architectures products into one, we must to use the Lipo Tool. It’s a tool which comes with iOS SDK, just to know, it is in “/Platforms/iPhoneOS.platform/Developer/usr/bin”, its file name is “lipo”. But we don’t need to know this path, Xcode can deal with it to us.

Add a new target, hit the “Add Target” button, just as you did with Bundle Target. At this time a good choice is the “Aggregate” target. It doesn’t create any product directly, its purposes is just to aggregate another targets and/or run some scripts, exactly what we want! To use the Lipo Tool we’ll need to create a “Run Script” at the “Build Phase“.

Use the "Aggregate" target to construct a run script.

Use the "Aggregate" target to construct a run script.


7. Lipo Tool Script:

top
This will be our greatest trick. The following script will make everything we need. It will compile the Framework Target to iOS Device and Simulator at once, will merge them with Lipo tool and will organize a good Framework Bundle structure.

Copy and paste this on your “Run Script” phase:

Xcode Script to Lipo Tool
# Sets the target folders and the final framework product.
FMK_NAME=FI
FMK_VERSION=A

# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework

# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework

# Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator

# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi

# Creates and renews the final product folder.
mkdir -p "${INSTALL_DIR}"
mkdir -p "${INSTALL_DIR}/Versions"
mkdir -p "${INSTALL_DIR}/Versions/${FMK_VERSION}"
mkdir -p "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources"
mkdir -p "${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers"

# Creates the internal links.
# It MUST uses relative path, otherwise will not work when the folder is copied/moved.
ln -s "${FMK_VERSION}" "${INSTALL_DIR}/Versions/Current"
ln -s "Versions/Current/Headers" "${INSTALL_DIR}/Headers"
ln -s "Versions/Current/Resources" "${INSTALL_DIR}/Resources"
ln -s "Versions/Current/${FMK_NAME}" "${INSTALL_DIR}/${FMK_NAME}"

# Copies the headers and resources files to the final product folder.
cp -R "${DEVICE_DIR}/Headers/" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/"

# Removes the binary and header from the resources folder.
rm -r "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/Headers" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/${FMK_NAME}"

# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}"

rm -r "${WRK_DIR}"

Now build the Aggregate target. Doesn’t matter you build for iOS Device or Simulator, this script will create a working folder, compile the framework target twice in there (device + simulator) and will output a folder called “Products” located in the project root folder. There is your Universal Framework to iOS!

Congratulations!


Importing your Universal Framework

top

8. Importing:

top
To test your Universal Framework, create a new Xcode project, select the Application target and go to “Build Phase” tab. Open the section “Link Binary With Libraries” and hit the “+” to add a new Framework. Click the “Add Other…” button and select your Universal Framework. Remember, you must to select the “.framework” folder. Remember to import your Framework Principal Header as a framework notation. Xcode will use your public headers in the Code Completion.

Let’s understand what happens until here:
When we set the “Mach-O Type” to “Relocatable Object File” the Xcode understand that everything related to that package will be like a “Binary Archive” like a ZIP. But that archive must be compiled again in new projects.

Then, when we create a Framework Bundle structure, Xcode understand that everything inside it is organized in folders like “Headers” and . But, as any other external bundle, to retrieve the resources you must load the external bundle. To iOS this could be an annoying step, however our Framework structure can help. Just Click and Drag on your Framework icon from “Project Navigator” to the “Copy Bundle Resources“. By doing this all the resources in your Framework will be copied to your Application Main Bundle.

Now, to retrieve the resources, make use of the main bundle, just as you are used to:

Framework Bundle
[[NSBundle mainBundle] pathForResource:@"FI.framework/Resources/FileName"
                                ofType:@"fileExtension"];


Conclusion

top
Well done, my friends! As we are used, let’s make a final review and take care with some possible problems.

  • In a common Xcode project, create a Bundle target.
  • Make the necessary setup, place your sources, headers and resources in it.
  • Create an Aggreate target and place a Run Script in it.

One last advice: Take care with your classes structure. If you set, for example, the ClassB.h as a Project or Private header, but in your code you import it into a Public header, this will cause conflicts.

And one last tip: Notice in the sample project I removed the scheme for the “Bundle Target”. We don’t need that scheme any more, because the new script will manage the compilation to us.

That’s all, buddies.
Enjoy your Framework to iOS!

Thanks for reading,
See you soon!

167 thoughts on “Universal Framework iPhone iOS (2.0)

  1. Pingback: Creating Universal Framework to iPhone iOS

  2. Morris

    Diney nice work. I was able to get your first version to work. I was going through this version, in step 4, I was unable to find “Generate Debug Symbols” in the build settings. I am using Xcode 4.0.2.

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      Thanks,

      “Generate Debug Symbols” is under “ – Code Generation”, that means, if you are using LLVM compiler 2.0 it will be under “LLVM compiler 2.0 – Code Generation”.

      You can also insert “generate debug symbols” in the search box.

      Reply
      1. Morris

        Interesting when I was doing this the first time I used the search box, looking for various forms of Generate Debug Symbols, but nothing showed up. After building it once, I was able to find it. Might be the same issue that editing “Architectures” has if you have not already edited “Base SDK” first.

        BTW you might want to switch the order of those two, it works much better that way.

        Reply
  3. Morris

    I was unable to get the build script to work. Note I did went through the tutorial and did not download the project.

    It is pretty obvious that it is a debug/release issue. Since this version does not use schemes, I was wondering how to tell the compile to build release not debug. This might have to do with the previous post.

    Xcode reported:

    cp: build/Release-iphoneos/CPTUI.framework/Headers/: No such file or directory

    cp: build/Release-iphoneos/CPTUI.framework/: No such file or directory

    rm: /Users/mmorris/devl/objc/CPT/CPTUI/Products/CPTUI.framework/Versions/A/Resources/Headers: No such file or directory

    rm: /Users/mmorris/devl/objc/CPT/CPTUI/Products/CPTUI.framework/Versions/A/Resources/CPTUI: No such file or directory

    Reply
    1. Diney Bomfim Post author

      Well, when you set “Generate Debug Symbols” to NO this issue should be solved.

      Besides, you can change “${CONFIGURATION}” key-word to “Release”. This will solve the problem securely.

      Reply
      1. Morris

        Just noticed that you updated your script by changing “${CONFIGURATION}” to “Release”

        xcodebuild -configuration “${CONFIGURATION}” -target “${FMK_NAME}” -sdk iphoneos
        xcodebuild -configuration “${CONFIGURATION}” -target “${FMK_NAME}” -sdk iphonesimulator

        to:

        xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphoneos
        xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphonesimulator

        ——————————————————–

        Do you know how to set ${CONFIGURATION} from Xcode? If so you could have made the following changes:

        DEVICE_DIR=${WRK_DIR}/${CONFIGURATION}-iphoneos/${FMK_NAME}.framework
        SIMULATOR_DIR=${WRK_DIR}/${CONFIGURATION}-iphonesimulator/${FMK_NAME}.framework

        # Building both architectures.
        xcodebuild -configuration “${CONFIGURATION}” -target “${FMK_NAME}” -sdk iphoneos
        xcodebuild -configuration “${CONFIGURATION}” -target “${FMK_NAME}” -sdk iphonesimulator

        ——————————————————–

        The question is probably mute because we don’t gain anything from have a Debug version.

        Reply
        1. Diney Bomfim Post author

          hehehe

          You answered your question by yourself.

          There is no point on creating a Debug Framework. This is why we turned off “Generate Debug Symbols”.
          ;)

          Reply
  4. Morris

    Statement 1 in the FAQ

    Can I use this Framework as a Bundle to store my files, XIBs, images?
    A: Yes, you can and now it’s very very easy to retrieve your files.

    Caused me some confusion which I notice others shared in the first version.

    My framework is a UI framework which has images in it for buttons. The framework directly uses the images. I believe this is different than what you are stating that you can create a framework with images that external code can use.

    I was able to include images into my framework that my framework uses by using:

    /usr/bin/xxd -i image.png image.png.h

    and

    #import “image.png.h”

    UIImage *image = [[UIImage imageWithData: [NSData dataWithBytesNoCopy: image_png length: image_png_len]] retain];

    [image releas];

    Reply
  5. Morris

    Okay all is working. Again well done Diney. Only change that I made to the script was to keep all of the intermediate files together.

    from:

    WRK_DIR=build

    xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphoneos
    xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphonesimulator

    to:

    WRK_DIR=${SYMROOT}/${TARGET_NAME}

    xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphoneos SYMROOT=”${WRK_DIR}”
    xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphonesimulator SYMROOT=”${WRK_DIR}”

    Reply
  6. James

    Followed step by step and downloaded sample code (several times) under XCode 4.0.2. But when I import the general header file, it always fails, ie:

    #import

    Produces the error:

    FI.h: No such file or directory

    Otherwise, your sample and my application attempts all seem to compile and produce the expected output, but cannot include it in any of my projects successfully.

    Reply
    1. Diney Bomfim Post author

      Hi james,

      Remember to check the box of “Add to target” when importing new files, otherwise Xcode can’t link the file with the target.
      Secondly, remember you must import any other framework referenced by your code.

      Reply
  7. xinquan

    it’s great idea.. I created the framework and all looks great. I changed the install location to ~/Library/Frameworks in the shell script

    but when I imported the framework to another project

    the linker fails with

    ld: framework not found xxxx
    Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang failed with exit code 1

    Reply
      1. charles

        Great job man….created the Framework but

        I tried everything out and even downloaded the demo but wont work in Xcode 4.2.3

        still getting

        ld: framework not found FRapp
        Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang failed with exit code 1
        :(

        Reply
  8. Pingback: Is a Dynamically Linked Framework possible on iOS? | Technical support, Computer, programming issue, issue tracking, quality assurance

  9. Ryan

    I’m very pleased with you tutorial, but I’m having a hard time with something and thought you or someone else might be able to help. I’m trying to include a third party library and make calls to that library within the framework project and then use the framework in my main project. First I’d like to know if this is possible as I haven’t been successful, and two if it is possible how to best accomplish it. I have heard that dynamically linked libraries is not allowed, but aside from Apple’s rule, is it possible to link libraries within frameworks in xcode? I appreciate anyone’s input. Thanks!

    Reply
    1. Diney Bomfim Post author

      Hi my friend,

      Let’s go to your questions:
      1 – You can link another frameworks and libs in your “custom framework” code, however you must to import the same framework/lib in your main project because you can’t use dynamical links in iOS.

      2 – It’s not just an Apple’s rule. The iOS works with sandbox concept, which each APP has its own sandbox. One sandbox can’t share any kind of code with another one and you can’t install anything directly in the device’s “hard drive”. This is why you can’t use dynamical frameworks/libs on iOS, there is no “shared sandbox” on iOS. Some guys, hackers like the Jailbreak’s creators, have broken this sandbox security, however this “jail-break” is specific for each device. So to use a kind of dylib on iOS you must break the device’s security and break the Xcode’s compiler (some text files of configuration).

      Sincerely, in my opinion… Don’t try it… it’s so much work for nothing. Try to think inside the Apple’s path, follow the device’s rules and you can make great things. Remember that there are reason for that kind of security, when you break it, your APP becomes more vulnerable.

      Reply
  10. Pingback: Créer un framework pour iOS | Coding artist

  11. Morris

    Life was good until I made a change to one of my classes (project structure has not changed) and I now I get the following error when I try to link with the framework for a device target (the simulator target links without issue).

    Assertion failed: (atom->fixupCount() == 1), function targetCString, file /SourceCache/ld64/ld64-123.3/src/ld/parsers/macho_relocatable_file.cpp, line 4831.
    0 0×13886 __assert_rtn + 86
    1 0x2dfd8 mach_o::relocatable::PointerToCStringSection::targetCString(mach_o::relocatable::Atom const*, ld::IndirectBindingTable const&) const + 280
    2 0x2b27c mach_o::relocatable::PointerToCStringSection::contentHash(mach_o::relocatable::Atom const*, ld::IndirectBindingTable const&) const + 76
    3 0x2c57f mach_o::relocatable::Atom::contentHash(ld::IndirectBindingTable const&) const + 47
    4 0xae870 ld::tool::SymbolTable::findSlotForReferences(ld::Atom const*, ld::Atom const**) + 704
    5 0xb21dc ld::tool::Resolver::convertReferencesToIndirect(ld::Atom const&) + 268
    6 0xb33f2 ld::tool::Resolver::doAtom(ld::Atom const&) + 642
    7 0x21f7c mach_o::relocatable::File::forEachAtom(ld::File::AtomHandler&) const + 60
    8 0xaa29e ld::tool::InputFiles::forEachInitialAtom(ld::File::AtomHandler&) const + 46
    9 0xb5924 ld::tool::Resolver::resolve() + 84
    10 0x14ff7 main + 871
    11 0x1d95 start + 53
    collect2: ld returned 1 exit status
    Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2 failed with exit code 1

    Reply
    1. Diney Bomfim Post author

      Well buddy…

      By the error, seems your code in that class is not well written, actually, a C code.

      I’ve saw this error before, but it just happen when you broke the C pattern, like when you try to initialize a static variable with a default value. When the compiler exit with code 1, this is always a code problem.

      Do you have a test target in you framework project? It’s very important that you have one. Before to compile your framework, make sure your code is running OK .

      Reply
  12. Morris

    to clarify … The change was in a class in the framework. Neither the framework or app project structures have changed. The error occurred when linking the app.

    Reply
  13. Wayne Hartman

    Excellent tutorial! I have been able to get classes instantiated, as well as get images and other resources OK. The one issue I have is that I load XIBs that have references to images, for example, and the cannot load:

    Could not load the “66-microphone.png” image referenced from a nib in the bundle with identifier “com.waynehartman.FrameworkConsumer”.

    How do I specify in the XIB that it should load that image resource from its own bundle, and not that of the Main Bundle? I’d really prefer to avoid having to create the XIB in each project, or have an extra copy of its images imported into my consuming project. Any ideas would be welcome.

    Reply
    1. Wayne Hartman

      So I was able to get it to work if I referenced the resource inside the XIB using the resource path prefix that you mention at the end of the article, but then I cannot view the images in IB. Any other workaround that you can suggest?

      Reply
  14. karthik

    warning: (i386) /Users/dnssnd/Documents/CAFE/CAFELibrary/build/CAFELibrary.build/Release-iphonesimulator/lib.build/Objects-normal/i386/SampleA.o unable to open object file

    Reply
  15. karthik

    warning: (i386) /Users/dnssnd/Documents/CAFE/CAFELibrary/build/CAFELibrary.build/Release-iphonesimulator/lib.build/Objects-normal/i386/SampleA.o unable to open object file

    I followed your instruction i got the above error

    Reply
  16. karthik

    Found it out !!!!
    we have to include #import

    sampleframework is name of the framework
    classname is the name of the class

    Thank you so much Diney Bomfim Finally learnt to build a framework properly

    Reply
  17. Morris

    I have an issue with Xcode 4.2 and the framework recipe. The issue is the result of Xcode 4.2 and its default behavior to only build for armv7 and not armv6 & armv7.

    I assume the framework’s build settings need to be changed

    Architectures: i386 armv6 armv7
    Valid Architecture: $(ARCHS_STANDARD_32_BIT)

    However the frame work only has armv7 and i386

    I tried:
    Architectures: i386 armv6 armv7
    Valid Architecture: armv6 armv7

    Architectures: i386 armv6 armv7
    Valid Architecture: i386 armv6 armv7

    And both fail to build.

    Reply
    1. Diney Bomfim Post author

      Hi Morris,

      I had the same issue here… very simple to solve:

      just add a line with the “armv6″ option bellow the “$(ARCHS_STANDARD_32_BIT)” on the “Architectures” option.

      Reply
      1. Morris

        Tried that …
        Architectures: $(ARCHS_STANDARD_32_BIT) armv6 (selected other added a line with $(ARCHS_STANDARD_32_BIT) and a line with armv6)

        Valid Architecture: $(ARCHS_STANDARD_32_BIT)

        nm -a CPTUI.framework/CPTUI | grep arch
        CPTUI.framework/CPTUI (for architecture armv7):
        CPTUI.framework/CPTUI (for architecture i386):

        Reply
        1. Diney Bomfim Post author

          in Valid Architectures u don’t need to use $(ARCHS_STANDARD_32_BIT) anymore.

          Just one line with armv6 and another one with armv7.

          Make sure the “Build Active Architecture Only” is set to NO.

          Compiler LLVM GCC 4.2 or Apple LLVM 3.0

          Reply
          1. Morris

            Architectures:
            $(ARCHS_STANDARD_32_BIT)
            armv6

            Valid Architecture:
            armv6
            armv7

            Build Active Architecture Only: No

            ————————————————-
            === BUILD NATIVE TARGET CPTUI OF PROJECT CPTUI WITH CONFIGURATION Release ===

            Check dependencies

            [BEROR]No architectures to compile for (ARCHS=i386, VALID_ARCHS=armv6 armv7).

            ** BUILD FAILED **

            So … I made one change …

            Valid Architecture:
            i386
            armv6
            armv7

            ————————————————-
            builds but …

            I do not see any thing for armv6 in the Log Navigator and …

            nm -a CPTUI.framework/CPTUI | grep arch
            CPTUI.framework/CPTUI (for architecture armv7):
            CPTUI.framework/CPTUI (for architecture i386):

          2. Morris

            Ignore the other post at this level as I made a mistake. This is the correct one …

            Architectures:
            $(ARCHS_STANDARD_32_BIT)
            armv6

            Valid Architecture:
            armv6
            armv7

            Build Active Architecture Only: No
            ————————————————-

            === BUILD NATIVE TARGET CPTUI OF PROJECT CPTUI WITH CONFIGURATION Release ===

            Check dependencies

            2011-10-14 14:47:50.910 xcodebuild[2397:3f03] error: Error Domain=NSPOSIXErrorDomain Code=2 UserInfo=0x200772ca0 “Non-zero exit code 255 returned from shell command: /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -v -E -dM -arch armv6 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -x objective-c -c /dev/null 2>&1″

            2011-10-14 14:47:50.914 xcodebuild[2397:3f03] Warning: Couldn’t discover the ‘llvm-gcc-4.2′ compiler’s built-in search paths and preprocessor definitions for language dialect ‘objective-c’.

            Compiler: /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2

            Reason: /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -v -E -dM -arch armv6 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -x objective-c -c /dev/null 2>&1

            CompileC /Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/Objects-normal/armv6/CPTDatePickerInputView.o CPTUI/Source/CPTDatePickerInputView.m normal armv6 objective-c com.apple.compilers.llvmgcc42

            cd /Users/mmorris/devl/objc/CPT/CPTUI

            setenv LANG en_US.US-ASCII

            setenv PATH “/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin”

            /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -x objective-c -arch armv6 -fmessage-length=0 -pipe -std=gnu99 -Wno-trigraphs -fpascal-strings -Os -Wreturn-type -Wunused-variable -Wshorten-64-to-32 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -fexceptions -mmacosx-version-min=10.6 -fobjc-abi-version=2 -fobjc-legacy-dispatch -D__IPHONE_OS_VERSION_MIN_REQUIRED=40200 -iquote /Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/CPTUI-generated-files.hmap -I/Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/CPTUI-own-target-headers.hmap -I/Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/CPTUI-all-target-headers.hmap -iquote /Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/CPTUI-project-headers.hmap -I/Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/Release-iphonesimulator/include -I/Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/DerivedSources/armv6 -I/Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/DerivedSources -F/Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/Release-iphonesimulator -F/Users/mmorris/devl/objc/CPT/CPTUI/lib -c /Users/mmorris/devl/objc/CPT/CPTUI/CPTUI/Source/CPTDatePickerInputView.m -o /Users/mmorris/Library/Developer/Xcode/DerivedData/CPTUI-ezjrxybxyybadxguvscgaqtaelju/Build/Products/Universal/CPTUI.build/Release-iphonesimulator/CPTUI.build/Objects-normal/armv6/CPTDatePickerInputView.o

            Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 failed with exit code 255

          3. Morris

            and those errors came from the

            xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphonesimulator SYMROOT=”${WRK_DIR}”

            part of the build script, the

            xcodebuild -configuration “Release” -target “${FMK_NAME}” -sdk iphoneos SYMROOT=”${WRK_DIR}”

            worked with both armv6 and armv7 parts

  18. Morris

    Sorry not sure what you are asking. Are you talking about … from the Xcode menu:
    Xcode –> Preferences –> Downloads

    If so, I have “iOS 4.3 Simulator” installed.
    “iOS 4.0 – 4.2 Device Debugging Support” and “iOS 3.0 – 3.2.2 Device Debugging Support” are not installed.

    Reply
    1. Diney Bomfim Post author

      Yep,

      So maybe you need to install them.
      Check on your folder:
      /Developer/Platforms/iPhoneOS.platform/Developer/ and see what SDKs you have.

      iOS 5 doesn’t use armv6 anymore…

      Reply
      1. Morris

        ls -la /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
        drwxr-xr-x 8 root wheel 272 Sep 20 02:26 iPhoneOS5.0.sdk

        ls -la /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/
        drwxrwxr-x 8 root admin 272 Mar 30 2011 iPhoneSimulator4.3.sdk
        drwxr-xr-x 8 root wheel 272 Oct 12 17:15 iPhoneSimulator5.0.sdk

        Yeah I am pretty sure Xcode 4.2 can build armv6, as I have built simple apps and ran them directly on an iPhone 3G. That was fun getting that to work — seem my answer at http://stackoverflow.com/questions/7760946/possible-to-target-older-ios-versions-when-using-xcode-4-2-and-ios-5-sdk/7762979#7762979

        But back to this … The last suggestion looked like it compiled armv7 and armv6, but when it was compiling for the iphonesimulator it had armv6 in the compiler commands (see #40 above) I would have expected i386. Send me an email (think you have it when I signed up here) and I will send you a stripped down version of the project.

        Reply
  19. Morris

    First off I want to say thanks for Diney for helping me resolve the issue with Framework recipe and Xcode 4.2 posts 35-47.

    Just in case anyone else out there has the same problem I will summarize the solution.
    The build settings for:

    Architectures: click other and type:
    $(ARCHS_STANDARD_32_BIT)
    armv6

    Valid Architectures: $(ARCHS_STANDARD_32_BIT)

    build the framework
    test to make sure all three architectures are there by running:

    nm -a .framework/ | grep arch
    make sure you see three lines, one with armv7, armv6, and i386.

    If armv6 is missing, close Xcode, find the project in finder, show the contents of the .xcodeproj, open the file project.pbxproj, delete the two lines with VALID_ARCHS = “$(ARCHS_STANDARD_32_BIT)”

    Thanks again for the help.

    Reply
    1. Diney Bomfim Post author

      Hello Leira.

      If you want to debug you can generate another target, like a unit test or an application test, in the same project and test your code.
      The framework only makes sense for release version, because its purpose is to share your code without expose the .m files (or .mm, or .cpp)

      This is the reason of the “Release” configuration.
      But, if you want to take advantage of some “Debug” macros and specs, just set it in the script. But as I said, there is no purpose in that.

      Cheers,

      Reply
  20. William

    Hi Diney,

    First of all, I would like to say “Nice work on your framework tutorial! This is truly good stuff.”.

    Now for a little trouble shooting. ;)

    I was able to create a framework and use it with ease if it only had Objective-C code in it. However, once I added any .cpp or .mm (C++) code to my framework, the framework would build fine but the project that included the framework would complain about “undefined symbols” in the C++ code. The code itself has no issues as I have used it outside of a framework in other projects in the past. See error snippet below for an example of the error I’m getting in my project that includes the framework. Is there a “magic” setting that I’m missing in my build settings? Any ideas?

    Undefined symbols for architecture i386:
    “std::terminate()”, referenced from:
    PalSpeechRecordSiren7::PalSpeechRecordSiren7() in MSAudio
    PalSpeechRecordSiren7::~PalSpeechRecordSiren7() in MSAudio
    “vtable for __cxxabiv1::__class_type_info”, referenced from:
    typeinfo for IPalObject in MSAudio
    typeinfo for IPalAudioService in MSAudio
    typeinfo for IPalSpeechService in MSAudio
    NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    “vtable for __cxxabiv1::__si_class_type_info”, referenced from:
    typeinfo for PalAudioCodec in MSAudio
    typeinfo for PalAudioCodecSiren7 in MSAudio
    typeinfo for PalAudioService in MSAudio
    typeinfo for PalSpeechRecord in MSAudio
    typeinfo for PalSpeechRecordGsm610 in MSAudio
    typeinfo for PalSpeechRecordSiren7 in MSAudio
    typeinfo for PalSpeechService in MSAudio

    ld: symbol(s) not found for architecture i386
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    Reply
    1. Diney Bomfim Post author

      Hi bro,

      Few time ago, I had a similar problem… but the problem was with the C++ code, because there is no real restriction or anything that could generate an error like this in this framework approach.

      Just to let you know, I’ve used that C++ code in many other projects too and always worked fine… however, just inside the framework the real problem comes up.
      So I was pretty sure that the problem was not with my code… however I was wrong… the problem was the code.

      I suggest you to create a blank (or almost blank) .mm/.cpp file and test the framework with it.

      Anyway, I’ll try to simulate the same error here using C++ files and reply to you soon.

      Cheers,

      Reply
      1. William

        Thanks Diney! Your reply was very fast. I’m simply impressed by your devotion to help people with problems that they come across when following your tutorial. Not a lot of people do that. Thank you.

        Additional info:
        The bug shows as an “Apple Mach-O Linker (Id) Error”.

        Try something like operator overloading… the compiler seems to complain about those as well.

        The code in question here was written in 1997 and has been used in a lot of projects since the time it was written. I’m not saying that it is impossible that something is wrong with this code, just seems unlikely. :P

        Reply
      2. William

        Additionally am I’m getting things like:

        Unknown type name ‘class’; did you mean ‘Class’?

        and

        Unknown type name ‘namespace’

        Seems like it’s not recognizing that the code is C++. The cpp files have a .cpp extension.

        Reply
        1. Diney Bomfim Post author

          Hi William,

          In my tests, I got the same error:
          “”Apple Mach-O Linker (Id) Error”
          “Undefined symbols for architecture i386:
          “_defaultTest”, referenced from:
          _globalTest in Test.o
          ld: symbol(s) not found for architecture i386
          collect2: ld returned 1 exit status”

          However it compiles pretty fine if I just use the code directly instead of creating the framework.

          This happened because I’d created two unambiguous definition, creating a duplicated global variable, without make use of the “extern” keyword.

          This error also happened when I created a referenced global variable (using “extern” keyword), but never really defined the global one.

          Well, It’s hard to say something, because that error can be generated by hundreds of problems. Problems that never appear outside the framework.

          Besides, the new compilers can interpreter the code following new rules, some of them that could be a new good practice to old codes. What compiler are you using?

          It’s really hard to say without see the code. If you send me the code, or a part of it, I could try to help you more.

          Reply
          1. William

            Unfortunately I’m not allowed to share the actual code. However, I did build a very simple test project and framework that I can share with you that has the same problems. I’ve compressed the framework and test project into a zip file. Where would you like me to send them?

          2. William

            It turns out that you may need to add “-lstdc++” to the “Other Linker Flags” in the build settings of your project that uses your custom framework.

            Additionally it seems that you can mix .cpp and .m/.mm header files in your framework header file.

            After I made those changes, everything works.

  21. Chris Moore

    Excellent tutorial. And the activity on this thread is great, thanks Willian for the -lstdc++ flags setting, saved me trouble as soon as I hit the problem.

    I’m creating a framework which then relies on a bunch of static libs that are compiled for ARM or for the Simulator.

    I have to look into it, but any quick clues on how I can put these into the framework? Or would I distribute them alongside the framework..

    Cheers

    Reply
    1. Diney Bomfim Post author

      Thank you buddy,

      Until now, I didn’t find a way to compile another libs/frameworks inside this framework approach. Actually, I think this is not possible. Any code to iOS must be compiled when you compile the final APP. This framework approach that I shown is just a way to “pre-compile” some amount of code. It’s not a real framework, which support many libs inside it.

      But if you find a way, please, let me know.

      Regards,

      Reply
  22. Shai Mishali

    I’m getting the following errors with Generate Debug Symbols OFF, anyone knows how i can resolve this? :) Thanks.

    ‘Cocoa/Cocoa.h’ file not found
    Cp: build/Release-iphoneos/MyFramework.framework/Headers/: No such file or directory
    Rm: /Users/freak4pc/Work/MyFramework/MyFramework/Products/MyFramework.framework/Versions/A/Resources/Headers: No such file or directory
    Rm: /Users/freak4pc/Work/MyFramework/MyFramework/Products/MyFramework.framework/Versions/A/Resources/MyFramework: No such file or directory
    Build task claims to succeed in spite of generating error messages

    Reply
    1. Diney Bomfim Post author

      Hi Shai,

      Are you importing the external frameworks into your new project?
      Remember that this framework approach doesn’t give support to external frameworks in it.

      Judging by the error, seems the framework was not compiled properly, check the final framework folder and see if the files you are compiling are really there.
      Every time that the framework can’t be compiled, it’s always because one of the settings in the step 4.

      Cheers,

      Reply
      1. Shai Mishali

        The problem was it tried to import Cocoa.h which is Mac only , i removed that import and added UIKit.h instead and it worked correctly and built with no errors, ill now try importing the framework and test it to hope its working :)

        Thanks!

        Reply
      2. Shai Mishali

        I got this when trying to use the frameowk:
        Undefined symbols for architecture armv7:
        “_OBJC_CLASS_$_CLLocation”, referenced from:
        objc-class-ref in Dropico
        ld: symbol(s) not found for architecture armv7
        clang: error: linker command failed with exit code 1 (use -v to see invocation)

        I guess its because i forgot to add CoreLocation.framework, but i added it now and still getting that error, Any ideas?

        Reply
          1. Shai Mishali

            Thanks again Diney :)

            Unforuntately i couldn’t get it to work for me …
            Re-compiled with armv6 and its still looking for CoreLocation even though its compiled into the Frameowkr…

            Also i tried running this : ‘nm -a name.framework.name | grep arch’ but wasn’t exactly sure what to do there (nm -a Myframework.framework didn’t work …)

            Thanks again :)

          2. Shai Mishali

            Ok i got the info and managed to compile it on armv6 as well but it doesn’t solve the problem , still same error, only thing that works is adding CoreLocation.framework to the target project as well, but its a bit of hassle… Theres no way to include in my own framework?

          3. Diney Bomfim Post author

            Wait wait wait….

            Didn’t you include the CoreLocation again on your new project?

            Oh dude… I told you before, in the FAQ above. This framework approach doesn’t work at this way, it can’t be used to pre-compile other frameworks, it’s not allowed on iOS.

            This framework approach is just to compile you very OWN code, not the code inside other libs or frameworks.

            In fact, you don’t need to include the CoreLocation framework when you are compiling your own framework. You just need to reference it in your code (“#import <CoreLocation/CoreLocation.h>”).

            The most important thing is that you must include the CoreLocation framework in the final project (the APP project).

            For example, if your custom framework uses the UIKit, CoreGraphics and CoreVideo inside the code, the project that will use your custom framework must include those 3 frameworks.

          4. Shai Mishali

            Yeah i guessed thats the deal ,
            Thank you Diney and sorry for being so much trouble :) This is my first time with this process and your tutorial was extremely helpful!

  23. Shai Mishali

    Also , could you clarify abit on the “private/project/public” header types?

    It appears that if i put something in private or project even the framework itself can’t include it from other headers, right? So how can i use them ?

    Reply
    1. Diney Bomfim Post author

      Hi again buddy,

      Sure!

      The project and private headers is for those header files that you don’t want AND don’t need to share.

      For example, when you #import a .h file inside a .m file or inside a private .h file. It means that just the project will have access to that file.

      However, for ALL .h files included in public .h files, must be public as well.

      The most important thing is that you can’t make cross or invalid references between public and private/project headers, especially inside your code.

      I hope it helps.

      Reply
      1. Shai Mishali

        So if one of my public headers #imports a file called “MyFile.h” , MyFile.h must be public as well ? :)

        Thank you so much for all your responses, i really appreciate it! :)

        Reply
        1. Diney Bomfim Post author

          Yes!

          You got it.

          But if you set a header file as private/project, then the #imports in it can be anything (private, project or public). The important thing is to never import a private header inside another public headers.

          Reply
  24. Shai Mishali

    Hey All, maybe you can assist with some weird issue i’m having. I’ve compiled this ARC-based framework successfully with a Depolyment target of iOS 4.3 , but when i import the framework to a 4.3 project it shows a ld: duplicate symbol _objc_retainedObject error, but it doesnt when its on 5.0 …

    I’ve posted a question on StackOverflow, if any of you could try and assist – i’m really confused with this

    http://stackoverflow.com/questions/8375233/ld-duplicate-symbol-objc-retainedobject-on-ios-4-3-but-not-on-ios-5-0

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      I never seen something like this. Conflicting with SDK… it’s very strange.

      Well, you know, ARC is not a runtime feature, it’s a compiler thing. So, when you create your framework it’s compiled, so the ARC instructions is executed and converted into real code. I don’t know if it’s possible, because any other of the Apple Frameworks use ARC inside the framework.

      ARC is something made to make the APP dev easier… so the best place to ask this question is probably the Apple Dev Forum, which have people specialized in ARC technology.

      https://devforums.apple.com/community/ios

      I’ll try to make some research as well.

      Cheers

      Reply
      1. Diney Bomfim Post author

        Oh… and something I’ve seen before, it’s not exactly equal, but can help you.

        When I compiled a framework using MRC, I let some MRC instructions in some header files (like “autorelease”). So when I tried to use that framework in another ARC project I got some errors, saying that I can’t use MRC in ARC.

        I removed that instruction from the headers, I compiled again, and it worked.

        The point is, don’t expose anything in the headers that could cause conflicts. Let the header files of your framework just to instruct Xcode about your methods and properties.

        So, thinking at this way, don’t include any ARC instruction inside the headers… or your framework will can’t be used without ARC. :|

        Cheers,

        Reply
        1. Shai Mishali

          Thanks for the replies man ,
          The problem isn’t arc or not-arc , it happens for both. The problem is it shows that error message on 4.3, and it doesnt show it on 5.0 . Im not sure whats this arclite library and why does it say its duplicate if ive never included it… This is really frustrating. Ill try the apple dev forum just in case. Thanks!

          Reply
          1. Diney Bomfim Post author

            Well,

            So certainly it’s a problem with the configs of your project.
            Try the sample project. It’s working 100%.

            Pay attention to the details.

  25. Dinu

    Thanks for a wonderful tutorial Diney… I have some doubts regarding this 1 – What is the settings bundle in your sample project and what does it contain. 2 – Can we include coredata classes in our framework. Now, coming to my errors :( , when i try to build the aggregate file, some of my Macro constants are throwing errors saying “Use of undeclared identifier xxxxxxx”… Can you tell me what might be the problem here?

    Reply
      1. Dinu

        i somehow craked it Diney…. no more erros now. I’v created a framework out of all my available classes. I have imported the newly created framework into my new xcode project. But i am not getting any response when i try to call the methods present in my framework. Even the Log statements in my framework methods are not getting printed. There were no errors either… Any thing more should i do here???

        Reply
  26. Dinu


    Dinu:

    i somehow craked it Diney…. no more erros now. I’v created a framework out of all my available classes. I have imported the newly created framework into my new xcode project. But i am not getting any response when i try to call the methods present in my framework. Even the Log statements in my framework methods are not getting printed. There were no errors either… Any thing more should i do here???

    i have imported the framework in my new class as well.

    Reply
  27. Pingback: How to add core data classes to a framework in iOS

  28. Michael

    Thank for the great tutorial. I’m starting to build a custom framework and I was wondering if I can manipulate screen elements from inside my framework. Since it’s just plain Obj-C code, I believe I can do it. Have you tried it?

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      Sure you can. For example, when you use Cocoa and hit a textfield, the keyboard automatically comes up right in front of everything else. The UIAlertView animate itself. Of course, if you are planning a Framework, probably you will want to trigger your actions from a function or from a method.

      Cheers,

      Reply
      1. Gopesh

        hey diney actually i was using the framework from Debug folder. so it was working for one…

        diney i am getting the issue in
        generate debug symbols not found…

        Reply
        1. Diney Bomfim Post author

          Hi,

          It’s hard to say what is happening with you with only these informations. Creating a framework will never show the error that is happening, because Apple doesn’t think about it before. So there are many reasons that could lead you in this.

          A little mistake in any of the steps, on your classes’ code, destination or in any part of the process can lead you in this.

          So, my advice is to take the sample project and try it, change its settings and try to find out the difference between it and your project.

          If you want, I can take a look at your project to find out what is happening: diney@db-in.com

          Reply
  29. Chris

    Hello,

    When I move my framework from Project Navigator to Copy Bundle Resources I can no longer install the application via iTunes or testflightapp.com, the message is displayed on the iPod’s screen saying that it couldn’t be installed at this time. When I remove framework from Copy Bundle Resources it can be installed again.

    Installing via Xcode always works.

    Reply
      1. Diney Bomfim Post author

        I don’t know what it’s about. Give me more information about what are u doing in the entire process.

        Remember that one error in one step may not appear until you use the final framework.

        Reply
        1. Chris

          Diney, I did everything as you described in the article above.
          I’ve moved my frequently used parts of code to the custom framework so I don’t have to copy the .h & .m files to every new project and compile them every time. Here everything works beautifully – I can submit it to the App Store, I can share it with my beta testers and so on.

          But the problem starts when I want to use some resources – like images, xib files etc that has been added to my custom framework. And here starts the trouble. As you said, to use those resources I have to move the framework from Project Navigator (left sidebar) to the “Copy Bundle Resources” section of my target. So my framework is both in “Link Binary With Libraries” and “C.B.R.”.

          At this point I can use all the resources that has been added to my custom framework, I can launch the application using Xcode on both simulator and my device. But when my beta testers try to run this app, the installation shows the alert on device saying that installation has failed. They install it via iTunes. When I install it via iTunes – the same alert is displayed on my device.

          And again – as soon as I remove the framework from Copy Bundle Resources, me and my beta testers can install the app through iTunes without any problems.

          Reply
          1. Diney Bomfim Post author

            Hi,

            I see.
            Well, this problem seems doesn’t have a solution for now. Just don’t use resources inside the framework. Leave it only for code.

            To resources, like images, use another bundle, a simple bundle from the Xcode template.

            Just it.

            If I find a solution for that, I’ll inform you.

    1. Diney Bomfim Post author

      The Xcode framework window is path dependent.
      Your framework just appear there if you place it inside the /Developer/Library/Frameworks. But as the new Xcode is a single APP, you should place it inside the APP.

      However, for somehow, maybe a Dcode bug, no custom framework or lib you put inside that folder will work when you compile your project.

      Reply
  30. Peer

    Hello folks,

    I just did an Ad-Hoc-Deployment with a little TestApp using the above framework approach containing several images and xibs via iTunes and I _cannot_ confirm any problems with it.

    So it seems that there is no fundamental problem…

    Regards,
    Peer

    Reply
  31. Greg

    Hi Diney,

    I am new to iOS development, and this is just what I am looking for.

    I have a newbie question. I’m not sure how you build the aggregate target. How do you run the script that calls lipo from within Xcode?

    Thanks for any help.

    Greg

    Reply
    1. Diney Bomfim Post author

      Hi,

      You’re welcome.

      About your question:
      1 – Create the aggregate target.
      2 – Click on its icon. (will appear a list of targets when you click on the project icon in the navigation panel).
      3 – Click on “Build Phase” tab.
      4 – Click on the plus button in the right lower corner and choose “Add Run Script”.
      5 – So copy and past the Lipo script in there.

      Well, buddy, I must to remember you that this is an advanced technique for advanced developers. This Framework approach is just if you want to share your Very Own code without expose the implementation files. Just it, nothing more. With this Framework approach you can not put the iOS framework that you often use into one single place, this is not allowed in the iOS devices. You can’t merge two frameworks.

      So, as you said that you’re new to iOS dev, think about if this is really your intention, because if not, this Framework will not serve to you.

      Reply
  32. Greg

    Hi Diney,

    Thank you for the quick response.

    What I am trying to do is this. I have made some custom controls that I want to use in multiple projects. I thought if I created a framework then it could be used across multiple projects. Should I be doing it differently?

    Thanks again,

    Greg

    Reply
    1. Diney Bomfim Post author

      Hey Greg,

      So you are on the right path! ;)

      This is exactly for that this framework approach is for.

      If you have any problem, please fell free to ask.

      Cheers,

      Reply
  33. Steve

    Hi Diney,

    Thanks for this awesome Project Template. It all works like a charm … except the code completion when using header, provided by the framework.
    In the screenshot of your old tutorial the pop-up for the import of #import is visible.
    However in your current sample this is not working. I’ve searched for hours and tried many things out but I can’t figure this out. It is really annoying if you have many headers in a large Framework :-(
    Have you got an answer to this problem?

    greetz Steve

    Reply
    1. Diney Bomfim Post author

      Hi man,

      Thanks, I’m not sure if I got your point.

      The “#import with many headers”? Does your framework have many header that other developer must import to use your custom framework?

      If so, this is not the correct approach. For example, you never import iOS header like “UIView.h”, “UIViewController.h”, “UINavigationBar.h”, etc… Because there is a single header in the UIKit that import all the public classes of the framework. So the user just need to import “UIKit.h”. In the case of this custom framework you should use the same approach. Create a single header with the name of your framework and import all the framework classes there.

      This was your doubt?

      Reply
      1. Steve

        Thanks for your reply Diney!

        My last post seems not be be submitted successfully …
        What I meant, was that I have no code completion when typing in the import statements for the framework headers that provide further headers.

        For example:
        I have a header named Core.h in my framework that imports CoreClass1.h CoreClass2.h etc.
        When typing in the header import for MyFramework/Core.h the code completion is missing. Apple provides this: When I type in Quartz/Q .. it will autocomplete it to Quartz/QuartzCore.h. In my framework my Core.h header will be hard to find without any special prefix because all of the other header it implements are also in the bundle.
        If I need a single header of my Core framework e.g Core.h/CoreClass1.h I have to know the exact name because it won’t autocomplete.
        Maybe its a little bit more clear what I meant.

        Steve

        Reply
        1. Diney Bomfim Post author

          Hello Buddy,

          As I told you before. It’s not a good approach to force the user importing many headers of your framework. The good approach is to import only one single header. Usually with the same name as the framework “” and this “MyFramework.h” is just a file that imports all the public headers of your framework.

          The code completion depends on the folder the framework are. In the case of this custom framework if you put it in any of the default framework folders it will not work, because it is not a real framework.

          So, there is no import header completion with this framework approach. Sorry for that, but this is not a big deal if you follow the best practices.

          Hope you understand.

          Reply
          1. Steve

            Hi again,

            I understand what you mean. Thanks for your reply. Then I will simple use one header for all imports.

            One last question:
            Importing 30 headers globally or more has no negative impact concerning performance?

          2. Diney Bomfim Post author

            Hello buddy,

            I suggest you to take a look at the UIKit/UIKit.h or Foundation/Foundation.h.

            This is the normal behavior in C. There is no kind of impact specially in the performance. This is not how standard C works.

            Everything is compiled at once, I mean, to the compiler there is no separated files, everything is compiled as one single big file. The imports and headers is just an external reference, a convention that we adopt to make the code more readable by other developers.

            So when you use “#import” this is not a runtime instruction, this is a compiler time instruction, it’s a macro, just like “#define”. You know how macro works, right?

            By the way, nor header nor imports are necessary to C. In the runtime the C is a pure abstract language, everything is in fact an “id” (equivalent to void *). If you have more interest to understand the compiler and the runtime behavior in C/Obj-C I suggest you a fast search about these subjects.

            Hope it help you to understand.

            Cheers,

  34. Ravi Kishore

    Hi Diney,

    I am new to iOS Dev [shift from java and javascript development] and my first task was to develop a library so that our customers can use our API from our library to build their App.
    I nearly search for 1 week to get info on building library, finally my friend gave me this blog which help to understand and solve my problem.

    Thanks for the post.

    After following your steps I was not able to still build .framework. finally after 3 hours of investigation I found that I need to change the scheme from applicationName to aggregateName ( from Product > Edit Scheme menu.)

    If possible can you edit your post to include this step?

    Regards,
    Ravi Kishore.

    Reply
    1. Diney Bomfim Post author

      Hello Ravi,

      Thanks for your feedback.

      What Xcode are u using for?
      Since the Xcode 4, when you create a new target, in this case the Bundle target it will create schemes automatically for you. So you don’t really need to edit them. :)

      Did you already have a project and just tried to create a framework from them? This is another situation which you could need to edit schemes manually.

      Reply
  35. Ravi Kishore

    Hi Diney,

    Yes I already have a project.

    What I meant by editing scheme is that current Active scheme is not aggregate so when I changed Active Scheme to aggregate it worked.

    Regards,
    Ravi Kishore.

    Reply
    1. Diney Bomfim Post author

      :)

      Well buddy… this is what I suppose you’ll do when I say “Now build the Aggregate target”.

      This is about your practice with Xcode. And I’m not focused on teaching Xcode here. :)

      Happy you find it by your self.

      Reply
  36. Ravi Kishore

    Hi Diney,

    If a framework has a storyboard, then how to access that storyboard?

    I am using below API:

    [UIStoryboard storyboardWithName:@"ShareWidget" bundle: nil]

    and

    [UIStoryboard storyboardWithName:@"ShareWidget" bundle: [NSBundle bundleWithIdentifier:@"com.testframework"]]

    In both the cases it says unable to find “ShareWidget” in the current App.

    Is this correct way to access it or there’s another way?

    Because using this storyboard I would initiate initateViewController from current ViewController.

    Regards,
    K. Ravi Kishore.

    Reply
  37. Ravi Kishore

    Hi Diney,

    After some troubleshooting I was able to load the bundle using the below code snippet:

    NSString *resourceBundlePath = [[NSBundle mainBundle] pathForResource:@”lib1234″ ofType:@”framework”];
    NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];

    UIStoryboard * stWidgetSB = [UIStoryboard storyboardWithName:@"ShareWidget" bundle: resourceBundle];

    but it gives an error:

    Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Could not find a storyboard named ‘ShareWidget’ in bundle NSBundle (not yet loaded)’

    When will this error occur and how to solve it?

    Regards,
    K. Ravi Kishore.

    Reply
  38. Ravi Kishore

    I found solution for this. storyboard name was “ShareWidget_iPhone” and not just “ShareWidget”. So when I gave “ShareWidget_iPhone” it worked.

    Reply
  39. zhan

    I got confused! All step is run well. But when I create a text project for framework. The #import or #import “TFdemo.h” is not found by the project. But the framework in the project which I can see the TFdemo.h file in the /TFDemoFramework/Headers.

    I expect to get your help as soon as possible! Thanks!

    addtion: The TFDemo.h is public and my xcode is xcode 4.2

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      It’s simple, take another look at 2. about “import headers”.
      It’s one single header that import all other headers of your framework, just like the Cocoa does.

      Remember now that the file is not at your main folder in the project, it’s inside a framework, so you must import it as a normal framework header, for example:
      #import

      Get it?

      Reply
  40. serhat

    Hello and thanks for you article.

    I have a problem with ios simulator. I successfully build and test my framework with a test project on my device. but it gives me error on simulator.

    ld: warning: ignoring file /Users/macbookpro/Desktop/test-app/../netmera, missing required architecture i386 in file
    Undefined symbols for architecture i386:
    “_OBJC_CLASS_$_NetmeraClient”, referenced from:
    objc-class-ref in test_appViewController.o
    “_OBJC_CLASS_$_NetmeraContent”, referenced from:
    objc-class-ref in test_appViewController.o
    ld: symbol(s) not found for architecture i386
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      Well, so your global framework was not compiled properly.
      Review the steps, specially that one about Lipo script and the final framework.

      A good tip is to pay attention to the file size.
      The final binary will have about the double file size compared to the single frameworks for iOS or Simulator.
      For example:
      ARMV 6/7 – 500kb
      i386 – 500kb
      Final framework – 1MB

      BTW, take a look at the sample project to help you finding the error.
      ;)

      Reply
      1. serhat

        I’m sorry. that was my foult. i used the binary file under …Xcode/DerivedData/inomeraNetmera-fjmsjkzbuhheokfvrlnznedxhotx/Build/Products/Debug-iphoneos/netmera.framework

        it is ok now :D

        Reply
  41. Gopesh

    hello thanks for your article,
    I have made the universal framework in ios. But i am facing issue in delegate methods. I have used textField delegate methods in my framework.

    When i import this framework in my application , and used this utility, delegate methods are not getting called. I have researched. But i am not getting the issue what is it?

    Reply
    1. Diney Bomfim Post author

      Well buddy,

      This seems to be caused by misspelling. You must be sure that all the connectors and names are matching the correct action.

      This is the reason I said that is very important to have a testing target inside the project, that means, a target to you use your code before compiling the framework.

      Reply
  42. Geri

    Thanks.

    Minor question: Is there a way read version number and target name (from the framework target) in the aggregator shell script?

    Reply
  43. Geri

    Hi.

    When I’m importing some Frameworks (OpenGLES, QuartzCore, CoreGraphics), it has problems with i386 architecture. I cannot compile, please help.

    Like:
    Undefined symbols for architecture i386:
    “_OBJC_CLASS_$_CAEAGLLayer”, referenced from:

    And:
    ld: warning: unexpected dylib (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks//OpenGLES.framework/OpenGLES) on link line

    Reply
    1. Geri

      I’ve got over this, simply forget to link frameworks into the client/test project. But the unexpected dylib warnings still appears in the framework target, a bit annoying.

      Reply
      1. Diney Bomfim Post author

        Hello buddy,

        About the target name and version… probably not. Because these are bundle information and the shell script doesn’t know anything about that because it runs before the target compilation starts.

        About your second question:
        Are you trying to link other frameworks or dylibs with your custom framework?
        You know that this is not possible, right?

        Understand this framework approach as a way to compile ONLY YOUR OWN CODE and make it private, so anyone else will see nor change your code.

        ALL the related frameworks or dylibs that is used by your custom framework code MUST BE imported again when using your custom framework into other projects.

        Reply
        1. Geri

          Sorry to hear.
          Some kind of static info.plist tweak by hand? I have both my framework’s product name, and version number in its info.plist. Can you show me how to read it off?

          Ye, I see that client should import the frameworks again.

          The only problem left is the warning at the framework building phase (it works well, though):

          ld: warning: unexpected dylib (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks//OpenGLES.framework/OpenGLES)

          Reply
          1. Diney Bomfim Post author

            About name and version,
            As I told you, I don’t think it’s possible.
            This is the reason I’ve defined in the script the first two variables
            FMK_NAME=FI
            FMK_VERSION=A

            You should use that to orient your script, because I don’t think it’s possible to read the name and version directly from the bundle.

            This warning is strange. Check what your code is importing and how it’s importing.
            Remember that the bundle target should has no linked binaries or any other dependencies on it. Only your own code will be compiled inside your custom framework.

  44. Geri

    Ohh, what did I wrecked?

    ld: framework not found EPPZKit
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    Reply
  45. vipin

    HomescreenViewController setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key

    this is the exception

    Reply
  46. vipin

    hii

    I have made a custom framework as described by you and in that one of my class contain quartzcore framework imported in it. so when i am importing my framework in other project exception is throwing. i am also importing quartz core frame work in other project.

    Reply
  47. intropedro

    Hello,

    First of all I want to congratulate you for the tutorial. It’s fine.

    And coming in, I have a doubt. Is there any way to debug the application and stand on a breakpoint, I can go into methods of framework classes seeing your code?

    I hope I explained well.

    Thank you!

    Reply
    1. Diney Bomfim Post author

      Hi,

      Well, once the framework is compiled there is no way to get access to the inner code, just as all the Cocoa frameworks, if you make a break point in your code and then go ahead step by step you’ll just see runtime instructions, making references to your own non-framework code.

      But while you’re developing the framework and you have acccess to the code, of course you can make break points.

      Reply
  48. MultiMe

    Hello, Thank you for this great tutorial!

    I’ve been using this to create frameworks for some time and it’s been working without any issues until now. After the last Xcode update (4.6) I started getting errors in Organizer when creating AdHocks from an archieve and it turns out that adding the framework to the copy bundle resources build phase is what’s causing it… have you seen this too and if so, do you have any suggestions of how to get around it without actually adding the resources to the app project manually?

    Thank you!

    Reply
    1. Diney Bomfim Post author

      Hello,

      Well, I and all the others I know still using with 4.6 and making the frameworks, compiling AdHocks and everything else without any trouble.
      Make sure your framework is beeing compiled to the universal version, including both archs. Pay attention to the final size of the framework, it must be bigger than when you just make a simple compilation generation only one arch.

      Reply
      1. MultiMe

        Thanks for your quick reply!
        After removing the framework from the resources, cleaning, restarting and adding it back, the error is gone! :)
        Wish I knew what the problem was tho…

        Reply
  49. Niels

    First I want to thank you about this great tutorial. It is clear and easy to go through.

    I’ve read all the comments and like a lot of others I have the same linker error. But i did set the Generate Debug Symbols to NO. Is it because I’ve added the armv7s architecture?

    Can you help me out?

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      No, the debug symbol will appear in any kind of C compiler.
      Make sure the “All” option is checked.
      In the “Build Settings” tab, there is a search field right below. In the same line the first two options are “Basic All”.
      If “Basic” is set you’ll not see the option anyway.

      Reply
  50. Blake

    Thank you for the amazing tutorial! But for some reason the Products folder isn’t being created with your script. Any ideas on how to fix this?

    Thanks,

    Blake

    Reply
  51. Blake

    Hi, I solved the last problem. But now I am getting this:

    The following build commands failed:
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCImageView.o BCClasses/../../BCImageView.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCButton.o BCClasses/../../BCButton.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCStandardConnection.o BCClasses/../../BCStandardConnection.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCLoginView.o BCClasses/../../BCLoginView.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCRatingView.o BCClasses/../../BCRatingView.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCSlideshowView.o BCClasses/../../BCSlideshowView.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCDateLabel.o BCClasses/../../BCDateLabel.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC build/BCClasses.build/Release-iphonesimulator/BC.build/Objects-normal/armv6/BCRSSReader.o BCClasses/../../BCRSSReader.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    (8 failures)
    rm: /Users/Blake/Dropbox/Personal/iPhone Apps/BCClasses/BCClasses/Products/BC.framework/Versions/A/Resources/BC: No such file or directory
    lipo: can’t open input file: build/Release-iphoneos/BC.framework/BC (No such file or directory)
    Showing first 200 notices only
    Command /bin/sh emitted errors but did not return a nonzero exit code to indicate failure

    Thanks,

    Blake

    Reply
  52. Blake

    Sorry for the last two posts, I figured those out :)

    Now I’m getting this:

    ld: framework not found BC
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    I have made sure that I set debug symbols off in the bundle build settings. What should I do to fix this?

    Thanks,

    Blake

    Reply
  53. haptic

    Hello, Diney,

    First of all, thank you very much! Excellent stuff.

    But I still have difficulties to make your sample project run. I have been following your instructions, the framework seems to be correctly built and I have made a one view universal sample app (with and without ARC), development target iOS 6.1.

    If I try to call the public method “methodA” in the “FIClassA” class, I would expect it to write “Calling methodA at FIClassA” to the console area. Am I missing something?

    My ViewController.m looks now like this:


    #import "ViewController.h"

    #import
    #import // because it is in the framework

    @interface ViewController ()

    @end

    @implementation ViewController

    - (void)viewDidLoad {
    [super viewDidLoad];

    [FIClassA methodA];
    }

    It complains: “No known class method for selector ‘methodA’”, – at least the class by itself seems to be known (is syntax highlighted in Xcode).

    Sorry for this beginner question.

    Is there anything I should think about specifically? I am trying to make a framework of non-ARC code to be used in a “modern” ARC environment.

    Thank you very much indeed.

    Reply
  54. haptic

    Hello, Diney,

    An edit function would be nice, seems to have eaten my slashes in the code part. Sorry.

    Reply
  55. haptic

    Hello, Diney,

    It is embarrassing, I forgot to initiate the class:

    FIClassA *classA = [[FIClassA alloc] init];
    [classA methodA];

    Please don’t tell anybody ;-)

    At least this part could be found in his stolen rubbish.

    By the way, I like your NinevehGL project! I am actually playing around with iSGL3D at this moment, but the project is rather dead unfortunately.

    Since I see some results with your framework sample, I will try to compile an iSGL3D framework to run under ARC conditions.

    Thanks a lot! Cheers

    Reply
    1. Diney Bomfim Post author

      Hello buddy,

      Thanks for your comments. I’m glad you found the solution by your own.
      This could be good to others facing the same problem as you.

      Following these steps correctly the framework will compile and work regardless the Xcode or iOS version.
      If something goes wrong, just double check the mistakes the people are used to make:
      - Public Headers are correctly set on “Building Phase”? The sources (.m, .mm, .cpp) are also placed in “Build Phase”?
      - The architectures are correct (armv7, armv7s, etC)? The framework is being compiled to each of those archs?
      - To make sure the binary is being compiled, remove the last line of the shell script (rm -r “${WRK_DIR}”). This will keep the working folder, so you can check if the binary is at least being compiled to each platforms. If one platform is missing, start tracking what could lead to that specific platform compilation to fail.
      - Make sure the “Debug Symbols” are off.

      Those few steps could sounds confusing at the first time, but if you pass through them at least one time you’ll see how easy it is. ;)

      Reply
  56. i-raqz

    Excellent Tutorial…
    I was able to instantiate the class and print stuff out of it. But when I tried to add the class’s view as a subview in the app. It says,

    Could not load NIB in bundle: ‘NSBundle (loaded)’ with name ‘/Users/nbkqkka/Library/Application Support/iPhone Simulator/6.1/Applications/EF0A9D34-1BDB-482C-8706-6B8C3E60D412/MLTestHarnessApp.app/MyTestFrameworkBundle.framework/Resources/ViewController_iPad.nib”

    Could you please help me with this…

    This is how I am instantiating the class.

    NSString *path = [[NSBundle mainBundle] pathForResource:@”MyTestFrameworkBundle.framework/Resources/ViewController_iPad” ofType:@”nib”];

    NSLog(@”Path:%@”, path);
    ViewController *controller = [[[ViewController alloc] initWithNibName:path bundle:[NSBundle mainBundle]] autorelease];
    [controller printTHis:@"hello"];
    [self.view addSubview:controller.view];
    [self.view bringSubviewToFront:controller.view];

    Console output

    MLTestHarnessApp[87975:c07] Path:/Users/i-raqz/Library/Application Support/iPhone Simulator/6.1/Applications/EF0A9D34-1BDB-482C-8706-6B8C3E60D412/MLTestHarnessApp.app/MyTestFrameworkBundle.framework/Resources/ViewController_iPad.nib

    I did a show package contents of the app but i couldn’t see the Framework folder, I thought the folder will be copied as it is into dervied data.

    Reply
    1. Diney Bomfim Post author

      When you compile a bundle within your framework you must add it to your project as well, that means, you will add the framework, then open the Framework folder in finder, navigate to the bundle and import it to the project again.

      When you import a compiled framework its bundle doesn’t comes.

      Reply
  57. Pingback: 【私訳】iOSのスタティックフレームワークを高速かつ効果的に、作成・開発・配布する方法 | yumtec.info

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>