简体   繁体   中英

Is it possible to use a static library only when testing with device and not simulator?

I have external closed library that can compile with armv7s (etc) only. when I try to compile against simulator obviously its not running and display some errors. I don't want to insert this library to my code unless I can configure Xcode to use this library only when i test with a device. unfortunately, i tried to do it with cocoapods with no success and i wonder if there any way to do it?

Yes, this can be done. I had a similar problem with a framework that caused linker errors only in the simulator so I setup up my project to only use the framework when building for a device.

The following assumes you are not using cocoa pods to link the library. I'm not sure what would need to be changed if you are.

  1. Select your target and go to the Build Phases tab.
  2. Under the "Link Binary With Libraries" section, remove the static library from the list but make sure the library file still exists in your project files under Frameworks folder. If the library file name is missing the leading "lib" in its name you might need to rename the file in the project navigator and add the leading "lib" to the file name.
  3. Go to the Build Settings tab.
  4. Find the "Other Linker Flags" setting.
  5. Double-click on the Debug value. Tap the + and enter "-l"
  6. In place of enter the actual name of your library minus the leading "lib". Do not include the extension. The "libMyLibrary.a" should be entered as "-lMyLibrary"
  7. Select the Debug value and notice a little circled +. Click the +.
  8. Click on the new "Any Architecture | Any SDK" part and change it to "Any iOS Simulator SDK".
  9. Now double click on the value to the right of "Any iOS Simulator SDK" and remove the -lsomeLibrary entry you added.

Now do a debug build.

The above change basically means that the library is linked in for all builds except for iOS Simulator builds.

You will probably also need to make some code changes. Any code making any reference to header files or other symbols from the library should be wrapped as follows:

#if !TARGET_IPHONE_SIMULATOR
#import "someLibrary.h"
#endif

#if !TARGET_IPHONE_SIMULATOR
    // Use stuff from the library
#endif

The reason is because the Library is missing the i386 (simulator) architecture slice, not a problem...

  1. Add your library to the project
  2. Wrap all your references to the library, including imports, in preprocessor directives for Debug vs Production. Preprocessor Directives to separate targets in xcode
  3. Manage your Schemes so that Simulator is Debug and Build (to Device) is set for Production.
  4. create a duplicate build target... One for simulator, and one for Device/production http://blog.just2us.com/2009/07/tutorial-creating-multiple-targets-for-xcode-iphone-projects/
  5. in build settings remove the library from Link Binary With Libraries for the "simulator" target

Now, when you use the "Sim" target... library and all related code will be excluded.

When you use the "Device" Target... the code and library will be included

Steps to avoid the simulator problem with static library without simulator architecture:

  1. Select the framework like optional in in Link Binary With Libraries. 可选框架
  2. Access to Build Settings to Linking part and add in Debug "-lNameLibrary". Then, check the button plus and select the option Any iOS Simulator SDK like key. Delete de value information add in the value information in the row Any iOS Simulator SDK . 其他链接器标志
  3. Add this code in the places where you use the library.
#if targetEnviroment(simulator)
#else
#endif

进口 代码

I've just solved such issue, so I leave here few hints.

Problem:

Static library is not built for simulator architecture. During test on simulator device I get error (not supported architecture).

Solution:

Exclude the static library from build on Simulator platform.

How to:

  1. Select your target and go to Build Settings , section Other Linker Flags (don't waste your time, use search)
  2. Select the Debug value and notice a little circled +.
  3. Using the + button create 2 entries:
    • Any iOS Simulator SDK
    • Any iOS SDK
  4. All values from the main Debug field (if not empty) move to Any iOS SDK . In the main Debug field and Any iOS Simulator SDK leave just $(inherited) . This way in Simulator will be included all other required libraries except f.ex. MyLib which you include just in Any iOS SDK .
  5. In your target go to the Build Phases tab, Link Binary With Libraries section
  6. On the static Library you want to exclude switch to Optional from Required
  7. Make code changes in any class making reference to the static library's header file. Find .m file for the class and wrap implementation code with #if !TARGET_IPHONE_SIMULATOR and #endif like following:
#if !TARGET_IPHONE_SIMULATOR
@implementation MyXLibrary

- (NSString *)myXMethod:(NSString *) encoded {
    return @"my exemple"
}
@end

#endif

If you have class in Swift, use #if targetEnvironment(simulator) to exclude class from Simulator or create "alternative mock implementation" for Simulator purpose if it is going to influence on many other places in the project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM