简体   繁体   中英

Weak linking in static library iOS

We have a static framework that we have built and it depends upon an SDK that we use to access ID's. This SDK has come out with a new version which has a new interface.

Currently the user would add our framework and the dependency SDK and everything would work fine. Now we want the user to be able to add our framework and either the old or new SDK and I'm not sure how to do this without creating multiple targets which we would rather not do. With the way I have it setup the user has to add our SDK and both the old and new SDK's.

I have a protocol SDKProtocol which is implemented by two classes NewSDKServices and OldSDKServices .

NewSDKServices won't compile unless the new SDK is present and OldSDKServices won't compile unless the old SDK is present. I figure this is OK since it is a precompiled framework and we can decided at runtime which to use.

Then I'd like to be able to do something like this, maybe with a ifdef to import and initialize the correct service.

if (useNewSDK) {
    _sdkService = [[NewSDKServices alloc] init];
} else {
    _sdkService = [[OldSDKServices alloc] init];
}

I've thought about weak linking these libraries but not exactly sure how it would work since you can't static link frameworks to other static frameworks. I'm hoping for some direction.

Both SDK's have a few headers and a .a .

I know you said you didn't want two targets. To be honest this is probably the best option as you are being explicit and up-front about the requirements so nobody can get confused easily. There are many ways to manage this by re-using source files and even having the way you suggested

if (useNewSDK) {
    _sdkService = [[NewSDKServices alloc] init];
} else {
    _sdkService = [[OldSDKServices alloc] init];
}

would be

#ifdef USE_SDK_NEW
    _sdkService = [[LinkedSDK alloc] init];
#else //USE_SDK_NEW
    _sdkService = [[LinkedSDK alloc] init];
#endif //USE_SDK_NEW 

However... if you really want to do it the other way and it works out, you must try to use weak linking.

If using weak linking it generally requires NSClassFromString(...) to access stuff. You would need to determine the availability of the SDK, hopefully someone has either added the info to the static classes like [NSClassFromString("TheSdk") performSelector: @"GetVersion"] or use the knowledge that other classes exist or do not exist. If the set of classes between two version is the same, you'd fallback to querying selectors or members.

Again this would not be pretty. You could make it less ugly by using the strategy pattern if you are familiar and have a strategy for the old SDK and the new SDK, and try to weak-link the classes without causing the compiler to require them.

If you are distributing yourself as a pod, you could create two targets and use the version to differentiate the required other SDK.

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