jimbo
jimbo

Reputation: 11042

How to use open source iOS libraries without collisions?

I'm writing an iOS library (SDK) and I need JSON decoding support. There are lots of choices, but the problem is upstream collisions.

If I add, say, JSONKit to my library, and another third party library does the same, then the upstream user who wants to use both my library and the other library will experience a collision.

It would appear then that it's impossible for me to add any third party libraries into my library because of the risk of collisions. How can I use iOS libraries as dependencies of mine without causing collisions for upstream developers?

Upvotes: 6

Views: 546

Answers (3)

JRG-Developer
JRG-Developer

Reputation: 12663

We're having this same issue. Here's my thoughts on how to solve it (perhaps we can figure out a robust solution together). For versioning control, we're using Git:

  • One option is simply to prefix all classes within your library with your own identifier. In such, even if the class is part of JSONKit, I'd still prefix it with my own identifier ("JG") to get the classname "JGJSONKit.h". In this manner, it's much less likely that a collision would occur.

    This method has the drawback that should a third party repository (such as JSONKit) be updated, however, it's more difficult to pull these changes into our library's version of JSONKit.

    This may be acceptable, however, if this code is intended to be exported as a static library (as you'd still maintain full control over the code, and you'd be able to manually pull changes to third party repositories and rename them appropriately, if you should so choose to do such in future updates of the static library).

  • Another option I've considered is using Git submodules. This solution seems to be better should your library be open source (or at least open source to the developers that have access to it -- not necessarily available publicly). In such, developers could choose to simply not include any submodule that they were already using within their own project.

Ideas?

Edit:

Here's the solution that we came up with:

1) We encapsulated our shared code (which we'd written- not a third party) into a project with a static library target and our shared resources (xibs and images) into a bundle following this tutorial:

https://github.com/jverkoey/iOS-Framework

2) We created a Git repository that included said static library and bundle.

3) We forked all desired third party libraries (so we could make changes to them if desired) and also added the original repos as another remote within each forked repo (so that should changes be made upstream, we could easily pull them into our own fork)

4) We added -objc to the "other linker" flags (important) so that all categories would work correctly during runtime.

All in all, the solution is near perfect for us:

We avoid collisions by either hiding the third party libraries (not including them in the public headers but private instead), or we warn that those libraries are used within the project for publicly exposed headers and that developers should not add them again (they can use the already included code instead, which is kept up-to-date via the simplicity of including them via said Git submodule method)

I hope this helps your efforts too!

Upvotes: 1

justin
justin

Reputation: 104708

How can I use iOS libraries as dependencies of mine without causing collisions for upstream developers?

Just specify that that third party library is a dependency of your library, provide appropriate links to the project, and any necessary instructions, version info, etc..

If that package/distro is not well-suited for distribution (e.g. they just have a pile o' source files), then create a public project (fork) which includes a proper static library target.

Upvotes: 2

hooleyhoop
hooleyhoop

Reputation: 9198

I had a look at JSONKit and i see that it isn't a Static Library, it is a src file to copy into your project.

All Classes, etc. in your project must be prefixed with your (cough) globally unique two letter prefix, including classes you copy and paste off the internet.

You would be better off if JSONKit was a library. Your library would depend on JSONKit, but not contain it, and it would be up to whoever building an app with your library to make sure JSONKit was also included and linked against - no collisions (although distributing a library that is dependent on other third party libraries that aren't yours to distribute is inherently somewhat tricky).

If other people are pasting this JSONKit file into their libraries and then distributing them you have only two options*

Modify JSONKit.h & .m, prefixing all symbols (you must do this with any code you include as source) or choose something else (NSJSONSerialization?).

This doesn't mean you can't have third party library dependencies (or that doing so is dangerous), just that copying a source file into your project is not the same as adding a library dependency.

*arghh, ok 3.. you could weak link all the symbols from JSONKit and leave it up to the library user to supply JSONKit.m, but then still the problem is the other libraries..

TLDR.. avoid JSONKit, it isn't suitable to use 'as is' in a library that you want to distribute.

Upvotes: 0

Related Questions