How can I create an Objective-C static library to distribute as a single binary and header file?

I am creating a MyLibrary static library for iOS in Objective-C that combines dozens of useful classes, each with its own .h file. I would like to distribute MyLibrary as one compiled binary, libMyLibrary.a and one .h header file, MyLibraryAPI.h . MyLibraryAPI.h has a dozen #import statements, one for each of MyLibrary dozen open classes. Developers who want to include MyLibrary in their host projects should only include the binary file libMyLibrary.a and MyLibraryAPI.h . This is the goal.

So, I installed the Role each public class in the MyLibrary Xcode project on Public and built libMyLibrary.a successfully using the Xcode and lipo command-line build lipo . Then I manually included all the dozens of MyLibrary header MyLibrary along with libMyLibrary.a in the host project, and the host project can use the public MyLibrary classes without problems. Excellent!

The problem is that I delete these dozens of header files and use MyLibraryAPI.h (like my goal), the host project classes can no longer find the MyLibrary header files referenced in MyLibraryAPI.h . Instead, during compilation, I get errors like: MyAwesomeThingDelegate.h: No such file or directory... for every MyLibrary class that I'm trying to execute #import in MyLibraryAPI.h . I have a folder in the root directory of my host project with the name lib , and in the host build settings the search path for the recursive header to lib/** and in the library search path, set the recursive path to lib/** .

I would like to hear community suggestions on how to properly set the host project search paths, so I need to enable libMyLibrary.a and MyLibraryAPI.h to use MyLibrary classes. Or, if I am doing something wrong, I would like to hear another sentence in order to achieve my goal of distributing one binary and one API header file.

+4
source share
2 answers

I had the same problem and came with the following solution:

First, I tried to hide as many implementation details as possible. For this reason, I usually built pairs of classes: one class is a public interface, and the other is a private implementation. An open class has only one instance instance: a pointer to an implementation. The private class has only forward declaration.

 @class MyViewImpl; @interface MyView : UIView { @private MyViewImpl* _internal; } @property (nonatomic, assign) CGRect highlightArea; - (void) startAnimation; @end 

Secondly, I put all public announcements in one header file. This is convenient for working with a separate header file, but it works. The only import that remains is the import of iOS data, for example:

 #import <UIKit/UIKit.h> 
+1
source

I give a second answer here with a different approach.

Objective-C's way is that the compiler needs a full declaration (i.e., header files) of all classes that will directly call your library users. The library file (.a file) contains only compiled code and without declaration. It will only be used by the linker, which is one of the last steps in creating the application.

[Programming languages ​​such as C or C ++ are the same. Programming languages ​​such as Java or C #, however, store meta-information about classes in compiled code, so they don’t need any header files, just .jar or .dll files.]

Thus, one approach would be to provide the user with .a and a directory with header files. Then they add the .a file to their project, add one #import statement wherever they use your classes, and add the path to the header file to their build settings (it is called "Header Search Contours").

+1
source

Source: https://habr.com/ru/post/1333803/


All Articles