I am building an iOS app where I want to be able to start my app in a demo mode with mocked connections. I use a static library for the mocking. However I don't want this library to be linked in my release build for the app store. I am looking for a solution to this problem.
The best solution I could imagine would be if I can define a compiler macro like this:
#define TEST_ENVIRONMENT 1
and if this macro is 1, the library would be linked. But I don't know how to setup the linking for this. Is there anything similar that would work?
I know I could create a new configuration in Xcode and manually add the -l option for the library for this configuration but this means that it can easily happen that one edits a build setting and forgets to edit the test configuration as well, or vise versa.
Best regards,
Michael
Related
I'm exploring Swift with Xcode-6 and so far so good although I think the new collections need a little bit of work as I've managed to break the compiler a few times.
Problem is I'm now stuck trying to create the framework package to then use in another project. The project builds without issue and all tests pass successfully. When I go to create Archive (which I assume is what is required) I receive the error:
:0: error: underlying Objective-C module 'Sample' not found
Now I assume this has something to do with the contents of my Sample.h which tells me
// In this header, you should import all the public headers of your framework using statements like #import <Sample/PublicHeader.h>
which is fine except I have only used swift enums, structs and classes for this framework so therefore no .h files exist.
Can anyone shed some light on this one as I can't find any documentation available yet?
EDIT (7/27/2018)
The information in the answer below may no longer be accurate. Your mileage may vary.
I sat down with an engineer and asked this exact question. This was their response:
Xcode 6 does not support building distributable Swift frameworks at this time and that Apple likely won't build this functionality into Xcode until its advantageous for them to do so. Right now, Frameworks are meant to be embedded in your app's project, rather than distributed. If you watch any of the session videos or see the sample projects, this is always the arrangement. Another reason is that Swift is very new and likely to change. Thus your Swift-based framework is not guaranteed to work on the platform you originally built it on.
Slight Update
The engineer mentioned that it's not impossible to make a framework for distribution, just that it's not supported.
I was able to get past the error by going to the target for the framework and on the Build Phases tab under Headers, remove the MyFramework.h file
However I was getting the "Underlying Objective-C module not found" error when I was using a framework to share code between a containing app and an app extension, both of which were pure Swift.
Assuming you are creating a truly pure Swift module, you must disable the Objective-C Compatibility Header and any generated interface headers so the compiler doesn't go off assuming it can find an Objective-C module for the framework.
Do Not remove your public framework header. You'll get a module-map warning at link time if you do.
You might find this useful: Creation of pure swift module
In short: it's possible to make static framework, but there is one issue: it doesn't work in end user' project if "ProjectName-Swift.h" header included.
But, it works fine if you use only swift.
I think it's a bug in XCode 6, or that Apple does not allow archiving the Framework from XCode while in beta.
If you compile to profile XCode generates the framework correctly. (See the Release folder created in DerivedData)
My clients wants to use some of the already available features in my app into their app. But, i dont want to share my source code with them and vice versa. I found out from some googling that, we can do this by creating some static libraries or frameworks in iOS. Can anyone throw some light on how to create a static library or framework (which ever is better) out of my already available source code.
My preference is to use static libraries over Frameworks. You will provide your customers the library file (.a extension) and the header file(s) for the functions in it. They just need to install the files somewhere in their project tree, set the include path, add the library to the project and they are good to go.
Note that if you want them to use your lib in the Simulator as well as on device you will need to provide them two versions of the library, one for each.
For instructions on how to create and use an iOS static library see this site.
Just for your information:
I created a static framework for iOS according to jverkoey's instruction
A ton of thanks to Diney Bomfim for his excellent article on how to create a framework. This is exactly what i am looking for.
EDIT - The Link is NOT working anymore...
I have an NSLog alternative that outputs the class it's called from as well as the line number and method (selector) called PLog in a class called PLogging. It's the exact same as the DLog taken from here with the exception of the name change. The advantage of DLog as it is written is that when compiled under Release mode, the log call is changed to a comment, negating the performance impact you would otherwise be subject to. I want to be able to use this and keep it within the framework, but be able to call it from the projects I add the framework to. But still have the log calls compiled to comments when in Release mode. Is this possible?
I would suggest a white list approach: add a preprocessor definition to your debug configurations which enables DLog/Plog to log to the console. In every other case it turns to comments.
Please have a look at this blog post which seems to point a finger at your problem. Of course, assuming that you don't want to change the way you are achieving your functionality: macros. I'm quoting abit: "An example of the basic problem is you want to link to a library that has both a Debug and a Release version. So in your application you want your Debug version to link to the Debug version of the library, and you want your Release version to link the Release version of the library."
I would rather tend to use targets for that, the trouble does look uncomfortable.
Third-party frameworks aren't allowed by the App Store. I assume you've got a static library or source files that you add to your apps with a cross-project reference?
If you've set your library project up with a debug flag set for your Debug configuration and unset for your Release configuration, then all you have to do is use the same configuration names for your app project, and the library will be built with the same configuration.
I'd like to develop a Mac application that builds custom static libraries for iPhone on behalf of the user.
I know that I can invoke xcode from the terminal with -xcodebuild to build these static libraries on the user machine, but my problem is that I don't want show to the user my objective-c classes used for the static library.
So my question is there any way to not show to the user my classes? Instead of use -xcodebuild I have other some way?
Thanks in advance
I guess you want to prevent the users of your library to see the header files of your static lib, right? I guess this is really problematic, as a compiler requires the header files to compile properly.
What you can do is to provide a "stripped down" version of your headers to your class users.
I stumbled across this tutorial a while ago. If you want to keep the code of your classes "closed" to any developers who are supposed to use it, I suggest making it a static library. Alternatively you can make a Framework.
http://www.clintharris.net/2009/iphone-app-shared-libraries/
No worries, this is the same process for iOS and Mac OS X.
In short, No. Since your code will be compiled for the machine by gcc, the user need only intercept Gcc at the appropriate moment and read out the code.
You can make this more difficult (but not impossible) to intercept by piping the code directly into gcc from your application, and do some checks to validate that it's really gcc it's going to.
You can also precompile some of the code that is common to all users into a framework, and that means you don't need to distribute the source to that part.
I have an iphone application using the third party library from my customer. They provide me two static library one for simulator and one for device. How can I change setting to allow me set to project setting to build against right library when project change configuration? can i use --framework flag? if it is, how I can do that?
Easiest way might be to merge the two libraries with lipo. The linker will choose the appropriate architecture's code during the build. This blog post discusses the process (in the context of a much more complete pseudo-framework setup).
See also this question and this question.