ios programming - overriding static library inside a static library at application level - ios

I am very new to the field of ios programming and working with linker is just a whole new world to me. I would try my best to be precise about my question.
Context: Static library linking in an ios project using xcode.
Problem:
Problem members:
3 static libraries.
libTestLibA.a
libTestLibB.a
libTestLibB_mine.a -- same functionality as libTestLibB.a -- same classes/methods everything.
Problem description
I am making an app using libTestLibA.a.
libTestLibA has some classes that depend on some classes from libTestLibB. Hence libTestLibA.a has libTestLibB.a compiled in itself.
Now, I have my own library named libTestLibB_mine. It has the exact same functionality as that of libTestLibB. Same methods / classes for same functionality. I want libTestLibA to use libTestLibB_mine instead of libTestLibB. I just have compiled static libraries (.a) for each of the problem members , ie, libTestLibA, libTestLibB and libTestLibB_mine.
Question:
When I compile my application, can I force a static compiled library (libTestLibA.a) to make use of another library (libTestLibB_mine.a) instead of what it already contains (libTestLibB.a)? If yes, how? If not, is there some work around?
Much thanks.

If A has already been statically complied against B, then I don't think you can replace B with B_mine. But as a workaround, I think what you might be looking for here is "Method Swizzling". What it does is, at runtime, replace the method of a class with another method (intercept the message and direct it somewhere else).
The following links should be useful to you.
CocoaDev Method Swizzling
JRSwizzle - open source library to make swizzling easier
Be sure to read about the dangers of method swizzling too.

Related

Framework using library crash

I have 2 frameworks created by me that use (both of them) a library also created by me.
The first framework initialize the library and makes all its workflow. After finishing the first framework, the second one must start.
But when the second one is going to start, after initializing the library, the app using both frameworks crashes with a exc_bad_access error.
Apparently the library is created correctly, but if i comment the line of code to initialize the library in the second framework, the workflow continues (it crashes later because it has no library initialization).
Is there anything I'm doing wrong? Should I use two separate libraries instead?
EDIT:
Imagine the situation:
Framework A has this methods: start, stop. And while it works it delegate to the methods: infoFromA,frameworkAFinished.
Framework B has this methods: start, stop. And while it works it delegate to the methods: infoFromB,frameworkBFinished.
Both start methods initialize the static library mentioned (lets call it problematicLibrary).
Both frameworks present some views to make its functionality. So lets make an example of the app workflow.
At the app view viewWillAppear method, I start the Framework A just using:
[FrameworkA start]; , this will initialize the library and present a view. With this view (using my problematicLibrary) some info will be delegated to the infoFromA delegated method. And after all the info is delegated, it will delegate to frameworkAFinished.
When the FrameworkA has delegated to the frameworkAFinished I start the next Framework: [FrameworkB start]. As the other Framework, it will initialize the library and present a view. While debugging, all the initialization of the library is done (create the instances of the needed objects and a new instance of the library is created) and while its presenting the view it goes through the viewDidLoad method and then it throws an exc_bad_access error at the problematicLibrary initialization line (which has been done before and continued to present the view!!) without going into any other method from the view.
I have checked if the initialization is doing well, and all the variables were at null value before the initialization, and a new memory address is given to the library object.
This sounds strongly like a symbol conflict to me. I'm just surprised the linker didn't catch it, but I assume that's because you're using a static library in both your frameworks instead of simply yet another framework.
Generally speaking, I'd warn that "this is a bad idea™". What you're trying to introduce into your design is basically dependency management. Like a lot of blog articles and specifically this SO answer suggest, you should avoid packaging frameworks (and by extension libraries) into frameworks.
What most likely happens in your scenario is this (I admit I'm guessing a bit here): You linked the library into Framework A. Thus, the library becomes a fixed part of it. Its symbols are in it, even if you did not expose them to the app in any header files or the like. As long as you use only that, everything works smoothly. Then comes Framework B, of which the library is also a fixed part. Even though you can't see it from your app, the very same symbols are inside it. This, however, clashes with the symbols that were already loaded by Framework A, hence a crash (as said, this would usually be caught by the linker, but I guess you "tricked" it by building the frameworks beforehand and packaged the library in them). Maybe somebody else can explain this in more detail, but that quickly becomes besides the point as to how you would go for a solution. From how I see it, it just won't work this way.
So here's a suggestion for how you can solve your problem:
If you really, really need to split like this (two frameworks used in your app using the same dependency), I'd suggest removing the library from the frameworks (i.e. make them depend on it, but not package the actual .a file in them) and documenting that properly. Then add the library to your app project, just like you added the frameworks.
If you want to make this fancy and easily installable into other apps, I'd recommend setting up a private CocoaPods repository and turn your frameworks into private pods. You can then easily define the library (or rather "new Framework C") as a dependency for Framework A and Framework B. When you then pod install in your app, cocoapods figures out the dependency and adds Framework C automatically to your project. This scenario is exactly what cocoapods (or any dependency manager for that matter) was designed for. It automates and helps in the project setup, so that the final build (the app) doesn't have to figure out dynamically what it can and can't use. The end result is the same.
Trying to duplicate that "in code" quickly becomes messy. Frameworks trying to figure out things of the surrounding app/project that uses them (like "is my dependency so-and-so already linked? if not, can I load my own version of the library?") can lead to a lot of pain.
Okay, in response to your comment I'll try my hand at a more detailed How-To for the non-cocoapods setup. As a preface, though, let me say that that's kinda hard to do on top of my head, as I have no ready sample project to toy around with. Since this is one of those "set it up once and then forget aout it for a long time" I have to admit my recollection of these things is a bit fuzzy, so consider this as a sort of "rough direction". There might be things you need to configure differently than how I recall them. Other SO user are thus hereby invited to edit and correct my answer here, too. :)
First, I have to say I am not exactly sure whether you need to convert your static library into a framework or not for this, I think you don't so I'll go from here (I have never used a static library in that way).
That means you can leave the project that builds your library as is. On second thought, you probably have to do this to be able to link against the library without making it a part of the framework that uses it. I will still refer to this code as "library" in the below points, but assume that you're able to turn it into a dynamic framework as well.
The projects building Framework A and Framework B should be changed. I don't know how you have this set up (as one project with various targets, whether you have a "development application" as part of it to test the frameworks on themselves, etc.), but the important thing is that in the target that builds a framework, the library should be linked (i.e. in the "Link Binary With Libraries" build phase), but not copied (i.e. it must not be in the "Copy Bundle Ressources" build phase). It might be tricky to set up any development/test target you use to run, depending on how you did that so far. For example you might have to manually edit Library Search paths in your build settings to be able to properly compile the framework.
Lastly, you need to change your final app's project settings, obviously. The library that was originally part of Framework A and B now needs to be linked to from its project directly, and, obviously, it needs to be copied into the bundle as well. Note that any projects that include either of your frameworks (A or B or both) in the future must do so, otherwise they won't work, because these frameworks expect the library to be present (but no longer "bring it with them").
In spite of this long-ish text wall, it shouldn't be that complicated, I think, but you may still want to check out how cocoapods can support you with something like this, perhaps it's helpful in the future. The linked article expects basic knowledge on how to use a pod and write one, but the other guides on the site explain that pretty well. I am just saying this because in the end, when using cocoapods in a project to add multiple libraries/frameworks that introduce dependencies, it basically sets up your project in the way I described above. It uses some fancy shell scripts that ensure everything is copied to the correct folders and such, but overall speaking that's how it works: A pod's podspec tells cocoapods what additional pods to include in your app for it to work (a dependecy the pod expects to be there, but doesn't "bring in" by itself).
Check if they are both compiling for the same target.
Check if they have access to the same target membership.
Check build phases to see that they are both there.
I think because the first library is not 'well' referencing the second one.
Also i think that you can't import a framework inside another one.
To make things easier, you can merge the two frameworks on a single one.
Also you can add a callback (using protocols or closures) that informs for the end of the first workflow, and you use this callback to initialize the second framework. This way the initialization will not be made automatically.

iOS + C: the use of __attribute__ ((__constructor__)) in static framework

I did quite a bit of googling for a definitive answer, but I could not find one.
We have cross-platform sources that need to be used by our iOS apps. I have already packaged them as static framework and got a test app to link successfully against and make a call into it.
The problem I am having is that it makes heavy use of global static constructors.
I am seeing erratic behavior with only a subset of objects getting instantiated but not all.
My questions:
Do static constructors even work within the context of an iOS static
lib?
How would one debug such a problem?
Thanks!
constructors in a static library get called erratically
The use of -all_load and -force_load does not make any difference in invocation of constructor attribute labeled functions
What you need to do is this:
make sure the constructors are global symbols. do this by exporting them via a symbols' file.
consider creating an init function and use the linker setting "initialization routine" to control the order of the instantiation of your global objects..
Do static constructors work within the context of an iOS static lib?
They only start to work once they're linked into an executable, but once that is accomplished they will work.
How do you debug such a problem
There are a few approaches
You have to presume no specific order of the invocation of the constructors.
Make sure the constructors are being linked into the executable (use nm to determine this)
You can try an -Wl,-all_load to get it to load all the components of all archives into the executable (or -Wl,-force_load,libstatic.a to just load for a specific static archive).

How do i use static members in my application, which is in my library's dependency

I'm making a HTML5 game engine DartRocket, which depends on StageXL. StageXL has some class, which is full of static members and I need some of them in my game.
My problem is that I can use these static members in my library(DartRocket), but I can't reach them from my game which uses my library.
Basically, because I can't see my library's dependency from my game.
When I say game I mean one of my examples in my library.
My question is: How should I access these static members?
I have some solutions in mind:
Let the user import StageXL so he can access them
Copy-paste the whole class into my library
Use mirror API
I find the first solution stupid, because the user have to import StageXL and because my library already depends on it.
I use the second one, because I find it easy and I wanted to make changes to the class, but this is not ideal either, because i have to update it myself, if there is a change in the library's dependency.
I have not tried the third solution yet, because I don't really like to use mirrors, because it increases code complexity and the usage became based on the member's name(String).
Some "solutions" that didn't work:
Making an instance of the class (it was embarrassing and stupid to hope it will work :D)
Extending the class(doesn't work because static members are not inherited)
What do you guys think?
If you have a library in dart you can re-export other libraries.
So for example:
The StageXL Library:
library stagexl;
// parts
// definitions
// ...
And your library:
library dartrocket;
export 'stagexl.dart';
Afterwards you can use:
import 'dartrocket.dart';
SomeStageXLClass.method();
This way the user can use your lib and also use the methods and classes from the stagexl library. By using the show keyword you can also define which classes to export.
Regards
Robert

Is there a way to make a native cocoa class library in MonoTouch?

I know that MonoTouch compiles code down to native machine code. Is there anyway to make a native (.a) class library using MonoTouch? Just to be clear, I'm not looking to share code between the two since I know that is not possible.
I believe it might be possible, but it would be hard work, and it's a long way from shrink-wrapped out-of-the-box functionality.
For reference, take a look through the answers on Is there a way to mix MonoTouch and Objective-C? - that question is about how to bootstrap and then call into mt from an obj-c application. I think the same approach would just about work for a .a library.

Can an iOS static library contain classes/interfaces, that can be used/implemented by iOS code that is using the library?

I apologize if this is a dumb question, or if it does not make sense. I've written some Objective-C code before, but I am not very familiar with writing code for OS X or iOS; I'm pretty much a novice. Currently, I'm trying to port a project from OS X into iOS. The project compiles into a Framework, that other OS X projects can use.
I'm trying to do something similar for iOS. I understand that iOS does not support Frameworks that contain dylibs and that the solution is to create a static library. However, the OS X Framework has several classes (in .m files) that the implementing code uses, extends, or implements. All the examples I've seen for static libraries seem to define a header-file with some functions that can be compiled into a static library.
Is it possible to have classes inside the static library, that iOS code can use? Also, how can I tell if the code is using dynamic libraries?
Yes, static libraries can contain Objective-C classes.
In some cases, you will need to pass options to the linker to force it to include all of the classes and categories defined in a static library. See http://developer.apple.com/library/mac/#qa/qa1490/_index.html

Resources