Using static library in both App and Cocoa Touch Framework targets - objective-c

I've created a new "Cocoa Touch Framework" target called MyAppCore in my iPad project called MyApp, with the intention of putting some common code in there. Overall it works great, however, I've encountered problems with adding the static library provided by Google Analytics.
I want to be able to use Google Analytics not only in the MyApp target, but inside of the MyAppCore target as well. In order to make both targets build, I have to link both targets with libGoogleAnalyticsServices.a. That appears to work, but when I run the app, the log is bombarded with messages like these:
Class GAI is implemented in both /path/to/MyAppCore.framework/MyAppCore
and /path/to/MyApp.app/MyApp.
One of the two will be used. Which one is undefined.
How can I share Google Analytics between the two targets in a successful way?

I managed to solve this issue by creating a wrapper class for Google Analytics (which is pretty handy to have, anyways) in the MyAppCore target. All access to Google Analytics will go through this wrapper. That way the only target that will use Google Analytics directly is MyAppCore, so I only have to link that target with Google Analytics.
This does not solve the underlying issue of sharing static libraries between my app target and a Cocoa Touch Framework, but for this purpose it works just as well.

Even if your static library depends on the external static library, don't link against it. Your main app will link against BOTH your library and the 3rd party library. A static library is a bunch of built code so you have two copies of everything doing things the way you are doing now.
You should still be able to reference the headers for the 3rd party library and things should compile on your static library without any warnings.
In my application I have two static libraries. "Wraith" is dependent on "PhilosophersStone" and the app is dependent on both. (Target Dependencies in Build Phases)
"Wraith" does not link against "PhilosophersStone", main app links against both. (Link Binary With Libraries in Build Phases)

Related

iOS: staic framework and dynamic framework?

Recently, I decide to make a framework for login module. I add the image resources to the framework, but I could not get it by code. I change the build the setting. mach-o type static library into dynamic library. I can get the image.
It is easier to make a moudle with dynamic framework than static framework.
but I google and find the dynamic framework made by developer is different with the Apple's dynamic framework. the app contain custom dynamic framework can not upload to Appstore ? Is it true?
who can answer my question? Thank you so much!!!
Dynamic frameworks are extremely common in AppStore apps. What you're probably seeing in posts is that you cannot manually load frameworks at runtime on iOS (i.e. there's no access to dlopen). They all have to be loaded at link time. You also cannot ship "shared" frameworks, where multiple apps share a single copy (like Apple's system frameworks). Each app must contain all of its custom frameworks.
But you can certainly ship dynamic frameworks in your bundle.

How to compile ios example in tensorflow

I just realized the tensorflow has supported ios now. But how to compile the example in contrib/ios_examples directory?
thanks!
josh
We're still finishing off all the documentation, but here's a draft of the README I'll be adding to the ios_examples directory. I'd be interested to hear if this helps, and if you have ideas for improvements.
TensorFlow iOS Examples
This folder contains examples of how to build applications for iOS devices using TensorFlow.
Building the Examples
You'll need Xcode 7.3 or later, with the command-line tools installed.
Follow the instructions at tensorflow/contrib/makefile to compile a static library containing the core TensorFlow code.
Download Inception v1, and extract the label and graph files into the data folders inside both the simple and camera examples.
Load the Xcode project inside the simple subfolder, and press Command-R to build and run it on the simulator or your connected device.
You should see a single-screen app with a "Run Model" button. Tap that, and you should see some debug output appear below indicating that the example Grace Hopper image has been analyzed, with a military uniform recognized.
Once that's been successfully run, make sure you have a real device connected and open up the Xcode project in the camera subfolder. Once you build and run that, you should get a live camera view that you can point at objects to get real-time recognition results.
Troubleshooting
If you're hitting problems, here's a checklist of common things to investigate:
Make sure that you've run the download_dependencies.sh and compile_ios_protobuf.sh scripts before you run compile_ios_tensorflow.
Check that you have version 7.3 of Xcode.
If there are Eigen errors, look inside the build settings of your Xcode project. In the Search Paths section, you'll see an Eigen include directory that changes with each version of the framework. You may need to update this to may the version in your tensorflow/contrib/makefile/downloads folder.
If there's a complaint about no Session's registered, that means that the C++ global constructors that TensorFlow relies on for registration haven't been linked in properly. You'll have to make sure your project uses force_load, as described below.
Creating your Own App
You'll need to update various settings in your app to link against TensorFlow. You can view them in the example projects, but here's a full rundown:
The `compile_ios_tensorflow.sh' script builds a universal static library in tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a. You'll need to add this to your linking build stage, and in Search Paths add tensorflow/contrib/makefile/gen/lib to the Library Search Paths setting.
You'll also need to add libprotobuf.a and libprotobuf-lite.a from tensorflow/contrib/makefile/gen/protobuf_ios/lib to your Build Stages and Library Search Paths.
The Header Search paths needs to contain the root folder of tensorflow, tensorflow/contrib/makefile/downloads/protobuf/src, tensorflow/contrib/makefile/downloads, tensorflow/contrib/makefile/downloads/eigen-eigen-, and tensorflow/contrib/makefile/gen/proto.
In the Linking section, you need to add -force_load followed by the path to the TensorFlow static library in the Other Linker Flags section. This ensures that the global C++ objects that are used to register important classes inside the library are not stripped out. To the linker, they can appear unused because no other code references the variables, but in fact their constructors have the important side effect of registering the class.
The library doesn't currently support bitcode, so you'll need to disable that in your project settings.

Understanding bundles frameworks and libraries

I'm developing ios B2B app and I have several questions regarding app modularization.
Firstly i need to understand main difference between bundles and frameworks. When to use bundles and when frameworks.
Another question is. Is it possible for bundle to contain a .framework inside in it and vice versa.
Is it possible to create a plugins for ios app and load them dynamically, if yes then what it should be? bundle framework or library?
Is it possible for library to contain a resource files ?
Is it possible to create a resource bundle and dynamic library and then load them dynamically at runtime.
Is it possible to create a plugins for ios app and load them
dynamically, if yes then what it should be? bundle framework or
library?
No
Is it possible for library to contain a resource files ?
No
Is it possible to create a resource bundle and dynamic library and
then load them dynamically at runtime.
No
A Bundle is a type of Directory, a folder. A Framework is a bundle. So is an Application and so is a Plugin.
A Static Library is a single file code archive you can compile into your app at build time
A Dynamic Library is a single file code archive you can load at Runtime
A Framework is a Dynamic library in a Bundle with other things
A Plugin is a Dynamic library in a Bundle with other things
The Xcode build option 'Bundle' means 'Place the compiled Dynamic Library in a Bundle' - this is what you do when you want to create a Plugin.
Static libraries are the only option for modularising your code on iOS.
On the desktop..
Typically a Framework is for sharing code and resources between multiple apps. You want your app to behave as though the code was actually compiled into it. You want loading to happen transparently and you don't want to do anything special to use the methods, functions, etc. contained in it.
A Plugin (a Bundle containing compiled code and resources) is for optional, dynamically loaded code, e.g. a software extension that you can choose to load or not. You want to carefully architect your app so that it isn't dependent on the Plugin but acquires new behaviour if you manually locate and load it at Runtime.
A Framework and a Plugin are very similar, but a Framework has a strict file layout to facilitate locating and loading code and resources. With a plugin, these jobs are your responsibility so you can structure the Bundle contents however you want.
Because loading code is so easy in Cocoa on OSX (but not iOS) Frameworks can contain Plugins which contain Frameworks which contain more Frameworks, etc.
On iOS some people put Static Libraries in Bundles with resources and call them Frameworks. This has none of the benefits and all of the drawbacks of a real framework.

How to ignore some static library at compile time

I am trying to figure out if there is a way to ignore a static library at compile time if the project already exists with similar library?
I am creating a framework in which I require to have the static library to utilize the scanning mechanism. However, the project I am trying to utilize this project also have such library, hence I am curious if there is any mechanism to ignore such library at compile time? Doesn't matter either from the framework or project.
Thanks.
I once had a similar case, where a library I wrote required some common open source components, which were used by many developers.
The best solution we found was to not link those components into our library, provide a list of these components, and to require the user of our library to include those components.

Creating one static library for iOS and simulator for distribution

If you create a static library for iOS do you have to distribute the header file(s) with it or is there another way to get it to work?
Currently I have a single my_lib.a file for both device and simulator but when I drag it into another test app to use it, it says it can't find the header and that all the places I'm using it in the code are undeclared. So I figure I'm either doing something wrong, or I have to also send the appropriate header files with it.
Background to my process:
I've seen two guides for creating a static library for both device and simulator. One on this site: Build fat static library (device + simulator) using Xcode and SDK 4+
and one here: http://mark.aufflick.com/blog/2010/11/19/making-a-fat-static-library-for-ios-device-and-simulator
I used the second site to just try it out. I'm also a bit curious if I did it correctly. I just went into the Release-iphone(os|simulator) folders and found the .a in the ios one and the .o in the simulator one.
The short answer is yes, you have to package header files with your static library. You have to package header files with any library in fact, dynamic or static. The library itself contains the compiled code, but you still have to tell the compiler about the identifiers in the library so when it's compiling your code it knows that they exist.
If you care, you can package your static library into a static framework with a little care. You simply create the same directory structure that a dynamic framework has, with your .a file in place of the .dylib (or .so) file. Frameworks contain a directory for headers, so you can distribute the binary and headers as a single package, and you can easily import headers from a framework without messing with the Additional Header Search Paths build setting.
Just in case it's useful - I followed Ray Wenderlich's instructions from here and was able to produce a framework for iOS that supported several architectures at once (including the simulator). The instructions are a bit too long to just copy-paste here.