2

Is there an elegant way (Objective C or C) for my app (jailbroken iOS) to check whether a specific dynamic library is available or not in iOS, other than checking if the actual dylib file exists at a specific path with an NSFileManager or calling dlopen? (e.g., an object that has info about available dynamic libraries that I can access.)

Update: I know I can also make it a requirement in my project settings (Xcode), but then the app just crashes on startup if the dylib isn't available, without any feedback (if there's a way to catch this and do an alert before crashing, that would be an acceptable solution, too).

newenglander
  • 2,019
  • 24
  • 55
  • This is what package references are for (In APT or similar). It manages these dylibs for you, so that you may properly launch your app regardless of the state of the libraries. – Richard J. Ross III Jan 09 '13 at 13:50
  • Thanks, but I don't quite follow. I can launch my app regardless of the state of the libraries by weak linking in Xcode. But I want the user to know if something is missing. – newenglander Jan 09 '13 at 13:59
  • Something should never be missing if the app is installed properly through APT. This is a situation that should never occur. – Richard J. Ross III Jan 09 '13 at 14:11
  • You're dealing with an edge case here. If the user goes into the file system and manually deletes a dylib, then the app should crash - They shouldn't expect to just willy-nilly be able to delete files. If they uninstall the library through APT, as a result your app will be removed as well, so no harm done to your app. – Richard J. Ross III Jan 09 '13 at 14:23
  • Ok, that's a good point. Assuming there are no other ways to check for dylibs and you want to put your comment/s in here as an answer, I'll accept it. – newenglander Jan 09 '13 at 14:41
  • Try to search for "weak linking". iOS supports this, and it can be set from xCode... – Macmade Jan 09 '13 at 14:49
  • @Macmade the OP already specified that he IS using weak linking already, he just wants to ensure that the library exists at run-time. – Richard J. Ross III Jan 09 '13 at 14:53
  • Then, with weak linking, symbols from a lib should be NULL if the lib is missing... https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html#//apple_ref/doc/uid/20002378-106633 – Macmade Jan 09 '13 at 15:10
  • @Macmade: ok, I see what you mean, that seems like a simple way to do it. Too bad I can't accept comments. – newenglander Jan 09 '13 at 15:25
  • Added and answer with a little more details... ; ) – Macmade Jan 09 '13 at 15:28
  • Interesting question, but I'm curious why you wouldn't want to just use `dlopen`? I understand why you might not want to use `NSFileManager`, because [some frameworks aren't actually at their nominal locations on the filesystem anymore.](http://stackoverflow.com/a/10859489/119114) – Nate Jan 09 '13 at 21:32
  • @Nate: not really a reason (thought I thought `dlopen` might be too much), just curious to see if there was an alternative. – newenglander Jan 09 '13 at 22:08

2 Answers2

4

If you are using weak linking for your dylib, it should be pretty easy to detect if the library is present by checking for a particular symbol.

Say you have a void foo( void ); function in that library.

You can declare that prototype as extern in your own code, and use the weak_import attribute:

extern void foo( void ) __attribute__( ( weak_import ) );

This way, if the symbol is not found (because its not anymore in the library, or because the whole library is not available), the linker will set the address of the symbol to NULL.

You can then simply and elegantly check for that symbol:

if( foo == NULL )
{
    /* Alerts the user */
}
else
{
    /* It's safe to use foo() */
}

For further reading: Framework Programming Guide

Macmade
  • 52,708
  • 13
  • 106
  • 123
0

It's my personal opinion that your approach is off. When installing a jailbroken app, most end-users will install it through Cydia/Installer/Icy, which is a wrapper for APT.

When you do finally push your package up to those stores, you can specify package 'dependencies', which will make it so that your app will not be able to be installed at all, let alone be run, without those packages installed.

It's up to you, however, to determine the package which contains the dylib you wish.

There are only a few edge-case scenarios which could cause a missing dylib once installed from APT, namely deleting the libraries, messing with MobileSubstrate settings, and someone downloading your app outside of APT.

However, in this case, the users shouldn't expect your app to work perfectly, seeing as they have been messing around with developer-type things which they probably shouldn't be.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • 2
    Sorry, but I think "It's my personal opinion that your approach is off." is a bit much. Why not "I don't know of any such functions, but...." or "No such functions exist, but....". This way you're actually starting off with an answer, rather than an opinion. – newenglander Jan 09 '13 at 15:02
  • @newenglander I never said that it wasn't possible. It is quite possible, using the APIs you specified in the OP. However, I was going at it from a more philosophical standpoint, rather than a code standpoint. If there is no situation that could occur where this would be necessary, why do you need it at all? – Richard J. Ross III Jan 09 '13 at 15:12
  • 1
    Ok, then we misunderstood each other. I wrote "Assuming there are no other ways to check for dylibs..." in my comment because I thought there were not other ways to check. Sorry for making you write out this whole thing. But I'm not a fan of "why do you want to do that" answers that don't give the actual answer first. – newenglander Jan 09 '13 at 15:22