1

Is it possible in IOS to dynamically load/create a function on a class at runtime?

I'm specifically thinking for example of adding a class the the app delegate at runtime, but I'm not sure it is even possible in the language?

For instance, this is used for push notifications, but could it be added dynamically by a Push framework behind the scenes at runtime?

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    ....
}

As an alternative, could it simply be defined in the framework, outside the app delegate file, but still a part of the app delegate logic?

Miro
  • 5,307
  • 2
  • 39
  • 64

2 Answers2

1

Both are options.

Dynamically adding methods, is via a C function called class_addMethod. You can even change an existing method (and still use the original!), it's called method swizzling. You can read the Apple documentation, or google for other examples. Note that you will need something in the program to at least touch your library to get it loaded (if you put the swizzling in your class's +initialize method), and it's probably easiest overall to just have the user initialize your library with something along the lines of [MYLibrary applicationLaunchedWithDelegate:self launchOptions:launchOptions].

If you know the class you need to add the method to, you can use a category.

Kevin
  • 53,822
  • 15
  • 101
  • 132
  • Categories seem simpler to start. Question-- how do you implement a category if the name of the class could change? For instance, iOS app delegate classes often reflect the name of the Project, and could be MyFunAppDelegate instead of just AppDelegate. Thus making a common category that any project could use would be difficult. – Miro Apr 04 '14 at 03:01
  • Likewise, for class_addMethod, the first argument is a class, such as [AppDelegate class]. What happens if the AppDelegate is called something else? – Miro Apr 04 '14 at 03:13
  • 1
    Categories are much, much simpler, but that question is the problem with them - you can't just add a category to "whatever class happens to be the app delegate," you need to know the class name. In fact, there's no reason that there has to be just one class that implements the UIApplicationDelegate protocol. And if you're going to precompile your library (i.e. distribute as a .a file or framework instead of source), I don't think even guessing the name will work. – Kevin Apr 04 '14 at 03:15
  • 1
    For `class_addMethod`, you can either have the delegate pass itself to some sort of initialization method (which most libraries do) and get the class with `foo.class`, or you can use `[[UIApplication sharedApplication] delegate]`. – Kevin Apr 04 '14 at 03:18
  • Making another class the delegate of certain methods is a good idea. I can setup that class. How do I assign the secondary delegate though? I could leave the function in the main AppDelegate and call the secondary one, but this just distributes the work. I'd like to set it up in the framework, entirely outside the main app delegate. – Miro Apr 04 '14 at 15:54
  • I also tried to use Notification center, similar to UIApplicationDidBecomeActiveNotification listeners, but there are no Notification events for didReceiveRemoteNotification, or registerDeviceToken. This would have been ideal. – Miro Apr 04 '14 at 15:55
1

you can put your self as app delegate and bypass all received delegates to old one for backward compatibility.here is a pseudo code.

1)by default we have this wiring:

ios -> appdelegate.m

now you need to put your self in the middle like :

ios -> framework -> appdelegate.m

2)so you can do it by set old delegate to another variable like: (in your framework delegate)

self.oldDelegate = [UIApplication sharedApplication].delegate;

and set yourself as application delegate:

[[UIApplication sharedApplication] setDelagate:self];

3)for backward compatibility you need to bypass all delegates to oldDeleagete

4)warning:this is pseudo code to give you the idea but remember you need to take care of multi threading of your app may be there is another framework like you and both are changing app delegates but will get wrong oldDelegate and your wiring will not work .so pay more attention to these kind of stuffs.look at this

Community
  • 1
  • 1
Hamed Nova
  • 1,061
  • 9
  • 15
  • this is an old question, but I think I ended up doing a similar approach. CustomAppDelegate with just a few custom methods, and that tests itself if it handles a method when any message is received. If not, it calls the message/method on the default AppDelegate that it retains. So it is a proxy or a swizzle approach. – Miro Jan 27 '17 at 17:20