Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storyboard integration doesn't work with Share Extensions #352

Closed
cakper opened this issue May 18, 2015 · 12 comments
Closed

Storyboard integration doesn't work with Share Extensions #352

cakper opened this issue May 18, 2015 · 12 comments
Assignees

Comments

@cakper
Copy link

cakper commented May 18, 2015

Hello,

I've tried to use Typhoon storyboard integration with the Share Extension that I'm working on at the moment and as extension doesn't have AppDelegate it doesn't seem to work properly. Probably that will be the case with all extensions supported by new iOS as they are not normal apps and have different lifecycle.

Manual injection as described on this page: https://github.com/appsquickly/Typhoon/wiki/Activating-Assemblies#instructing-typhoon-to-inject-a-pre-obtained-instance works as expected, but adds a bit of noise to the view controllers (works well as a workaround).

To give a bit more context what was already discussed here is the link to twitter: https://twitter.com/cakper/status/599245416442507264
And sample project created to demonstrate the problem: https://github.com/cakper/TestExtensionApp
https://github.com/cakper/TestExtensionApp/blob/master/Podfile.lock contains versions of the Typhoon and Cocoapods used

Thank you, Kacper :)

@alexgarbarev
Copy link
Contributor

Sorry, haven't tried iOS extensions yet..

How UIStoryboard instance is created in the extension? Manually, with `[UIStoryboard storyboardWithName:bundle:]``? Or it's created by iOS automatically?

if automatically, how iOS know storyboard name? Using value for special key in Info.plist?

@cakper
Copy link
Author

cakper commented May 18, 2015

Hello Alex,

Storyboard instance is created by extension automatically. It is using NSExtension -> NSExtensionMainStoryboard entry from extension Info.plist file.

@alexgarbarev
Copy link
Contributor

Ok, I'll add support for that soon then

Отправлено с iPhone

18 мая 2015 г., в 20:32, Kacper Gunia [email protected] написал(а):

Hello Alex,

Storyboard instance is created by extension automatically. It is using NSExtension -> NSExtensionMainStoryboard entry from extension Info.plist file.


Reply to this email directly or view it on GitHub.

@cakper
Copy link
Author

cakper commented May 18, 2015

Nice, Thanks ;)

@alexgarbarev
Copy link
Contributor

Hey, @cakper. Can you test latest code with :head version of Typhoon?

@cakper
Copy link
Author

cakper commented May 19, 2015

Hello, @alexgarbarev - sure - I'll have a look in a sec

@cakper
Copy link
Author

cakper commented May 19, 2015

Hi @alexgarbarev

So we had a look at it and it doesn't work as expected. After going though Typhoon code what we found is that setDelegate is replaced in swizzleSetDelegateMethodOnApplicationClass with your implementation that calls [self loadInitialFactory]; which is fine, but the problem is that setDelegate is never called (because app is not instantiated) and in result the initial factory is never loaded.

Trying to think about right place to inject with factory initialisation for extension - what do you think about swizzling storyboardWithName in UIStoryboard and calling load there?

@alexgarbarev
Copy link
Contributor

Hi @cakper

Injection for storyboard doesn't work?

Now, about the code. I appreciate your attention to code and good suggestions.
There is two files you would like to check.

TyphoonStartup.m
There is loading initial factory and trying to inject into AppDelegate if possible.
Loading initial factory done on +(void)load method, using TyphoonInitialAssemblies key in Info.plist (or using [AppDelegate initialFactory] - not this case)

Initial factory loaded at very start of application startup and released after application did finish launching ( at UIApplicationDidFinishLaunchingNotification notification on iOS)

TyphoonInitialStoryboardResolver.m
This class is designed to provide storyboard integration at application startup. As you suggested, it uses swizzling of storyboardWithName method. Inside this method, I'm checking for initial factory which must be provided by TyphoonStartup class - if initial factory exists TyphoonStoryboard will be created instead of UIStoryboard (as class cluster).


Now, back to the problem.
I guess next reasons:

  1. Initial factory was not created (missing TyphoonInitialAssemblies in the plist)
  2. Initial factory was created, but released before UIStoryboard creation

If you have spare time, you can try to debug using information from above and make pull request with fix, I haven't so much time to play with iOS extensions now. (Will fix later)

@cakper
Copy link
Author

cakper commented May 21, 2015

Hello

There is loading initial factory and trying to inject into AppDelegate if possible.

I think problem here is that swizzleSetDelegateMethodOnApplicationClass doesn't work at all because there is no AppDelegate in the Share extension.

I did try to run loadInitialFactory later manually and then it works fine (so it loads Assemblies from the plist file without any problems and is injecting everything fine. So the I still think our ultimate problem here is that there is not AppDelegate for the extension target. Did you try to play with the sample project I've provided?

@jasperblues
Copy link
Member

@cakper We'll get to this ASAP. Meanwhile if you want to tackle this yourself, it sounds like simply a matter of:

  • Find the correct hook point
  • Copy the same approach that TyphoonStartup uses for AppDelegate

We'll happily accept a pull request for this.

@alexgarbarev
Copy link
Contributor

I'll fix that issue. I hope I'll have time at today's evening

@alexgarbarev alexgarbarev self-assigned this May 21, 2015
alexgarbarev added a commit that referenced this issue May 21, 2015
…nil, when application hasn't AppDelegate (in case of iOS Extension), see #352
@alexgarbarev
Copy link
Contributor

@cakper You was totally right. The reason was: TyphoonStartup loads initialFactory only when Application Delegate class exists.
Now fixed and released as 3.1.8. Thanks for catching that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants