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

Inject View Controller which conforms to protocol #38

Closed
romaHerman opened this issue May 24, 2022 · 23 comments
Closed

Inject View Controller which conforms to protocol #38

romaHerman opened this issue May 24, 2022 · 23 comments

Comments

@romaHerman
Copy link

First Thanks for the great tool!!!

Here is my question:
I have a view controller which conforms to protocol "MyProtocol"
then I do let calendar = Inject.ViewControllerHost(CalendarViewController())
and try to pass this calendar to the SideMenu which expects VC of MyProtocol type
but calendar returns nil, when I do calendar as? MyProtocol

are there any workarounds of this ?

@johnno1962
Copy link
Collaborator

johnno1962 commented May 24, 2022

Where is MyProtocol defined? Is it in its own file or is it being injected as well? Or, you could also try setting the environment variable INJECTION_DYNAMIC_CAST in your scheme.

@romaHerman
Copy link
Author

romaHerman commented May 24, 2022

It's In it's own file
Will try with env var now and let you know
P.S. Thanks for such fast reply!

@romaHerman
Copy link
Author

unfortunately it didn't help

@johnno1962
Copy link
Collaborator

Any chance of a small example project so I could look into what's going on?

@romaHerman
Copy link
Author

Yes
Let me try to construct one

@romaHerman
Copy link
Author

Here is a sample project
https://github.com/romaHerman/InjectTest
It has TestComponents xCodeProject and main xCodeProject
in SceneDelegate you can find test invocations of methods

it's similar to my setup in main project

@johnno1962
Copy link
Collaborator

johnno1962 commented May 24, 2022

Thanks for the example project. Injection aside, I can see that Inject.ViewControllerHost(CalendarViewController()) has type Inject._ViewControllerHost<CalendarViewController> not CalendarViewController which even though it is defined as a subclass of CalendarViewController does not acquire the conformance to TestProtocol. This seems to be a Swift thing. @krzysztofzablocki?

@johnno1962
Copy link
Collaborator

johnno1962 commented May 24, 2022

... Perhaps you need to do something like:

        if let vc = vc.instance as? TestProtocol {
            vc.testPrint()
        }

@romaHerman
Copy link
Author

Thanks!

It does work in this case with vc.TestPrint()

but unfortunately it won't solve problem with passing this view to side menu

I have SideMenu which does navigationController.pushViewcontroller(<VC>)
and in order Inject to work in should push vc not vc.instance

problem is here

let calendar = Inject.ViewControllerHost(CalendarViewController())
sideMenu.view = calendar.instance

@johnno1962
Copy link
Collaborator

How do you mean "for inject to work"? If you save the file containing CalendarViewController, its methods will have been overridden for the next time they are called again.

@romaHerman
Copy link
Author

romaHerman commented May 25, 2022

here is what I'm trying to do

let calendar = Inject.ViewControllerHost(CalendarViewController())

viewControllers = [NewsViewController(), calendar.instance]
menu.viewcontrollers = viewControllers

inside menu viewControllers variable is declared like this
var viewControllers: [MenuProtocol] = []
and when I do
menu.selectedIndex = 1
inside it does following
navigationController.setViewcontrollers[viewControllers[selectedIndex]
so it sets calendar.instance not the calendar itself and I think this the problem why Inject doesn't hot reload it for me

@johnno1962
Copy link
Collaborator

It's possible the "Hosting" model Inject uses may not be for you in this instance. When you save the file containing NewsViewController it will have been "swizzled" correctly. Perhaps you just need a way to force it to redraw. Have you looked at creating an `@objc func injected()' method which should be called when the class is injected inside which you call viewDidLoad() or configure() or something to force the redraw so you can see the hot reload.

@romaHerman
Copy link
Author

Thanks

I've overlooked this
How I can do that ?

@johnno1962
Copy link
Collaborator

johnno1962 commented May 25, 2022

create an @objc func injected() function in your class and see if it gets called. If it does, then you can do some stuff in it.

@romaHerman
Copy link
Author

Maybe I will have to change SideMenu somehow to accept viewControllers
injected doesn't get called

@johnno1962
Copy link
Collaborator

I can zoom if you get stuck.

@romaHerman
Copy link
Author

wow, thanks a lot!
if it works for you I'm ready
Tell me when you have time for that

@johnno1962
Copy link
Collaborator

Or TeamView. Send an invite/login to github at johnholdsworth.com

@johnno1962
Copy link
Collaborator

Actually, TeamView if you can thanks.

@romaHerman
Copy link
Author

well
I've changed my setup and now I don't need to solve this problem but somehow InjectionIII just quit working

I can see
InjectionIII connected /Users//Documents/App.xcworkspace
💉 Watching files under /Users//Documents/App.xcworkspace
and when I open debug view hierarchy in Xcode I can sett that there is InjectionHostVC
also I gave access to all files and folders in mac's security

But when I change view and save nothing happens

I've tried reinstalling app and installing again, installing from Mac App Store and also restarting Mac

@johnno1962
Copy link
Collaborator

You seem to be watching the workspace file instead of watching the directory containing the workspace file. Use menu item "Open Project" to set it again.

@romaHerman
Copy link
Author

romaHerman commented May 25, 2022

Ohhh
I somehow thought that I should select workspace

It's working now
Thanks a lot!!!

BTW here is how I hacked thing that I can't add this view to menu directly because of protocol
added this line in viewWillAppear so view controller will re-instantiate itself and thus re-add itself with Injected host
I will have to remove this code once I'm done working with this VC but it solves the issue

if injectSelf {
            let eventVC = Inject.ViewControllerHost(EventsViewController())
            eventVC.injectSelf = false
            navigationController?.setViewControllers([eventVC], animated: false)
        }

@krzysztofzablocki
Copy link
Owner

for passing specific type only .instance can work, but in that scenario I'd recommend probably not commiting host changes, I usually just do host swap in separate commit I can easily delete at the end of feature work

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

No branches or pull requests

3 participants