johnno1962 / HotReloading

Hot reloading as a Swift Package

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Crasing in SwiftInjection

vualeks opened this issue · comments

Hey,

at first it was occasional, now almost every other app build/start, I get crashes in SwiftInjection.swift
Screenshot 2023-03-10 at 22 17 32
Could it be related to some unit test files are not building at this moment? I cann't figure out what could trigger this. Updated to latest version 4.10.3 and latest InjectionIII app too, didn't help.

Do you have "Enable TDD" selected? Are you wanting to use the inject test feature? If not you may want to try the new simpler version https://github.com/johnno1962/InjectionLite which no longer needs the app running.

I don't want to use inject test feature (didn't know it exists :D ), just main code injection. I just tried with Enable TDD with Injection app, same result, then removed the app, added InjetcionLite and also the same crash at the same place.

I have also fixed the unit tests, they build correctly now, but that didn't help anyway.

newClass should be the class you're injecting. What can you tell me about it? Is it a generic or inherit from one?

Yeah, it inherits from a generic one in this case that I just tried.

class SomeCoordinator: NavigationCoordinator<SomeRoute>

I've pushed a new branch generics-tests you could sync to which should avoid this problem. Let me know how you get on.

There is a different error now, I've tried with changes in the same class as before
Screenshot 2023-03-11 at 16 32 08

I've pushed another commit avoiding the newly loaded class in this test. It's strange this hasn't been reported before.

Still looks the same, hope the error output helps
Screenshot 2023-03-11 at 16 50 18

Your output helps a lot. Seems like your class doesn't inherit from NSObject anywhere so a lot of Objective-C run time capabilities surfaced through methods like isSubClass: and superclass are not available. I'll have to look into what can be supported. Are you able to inherit NSObject somewhere to prove the theory? Are you sure you synced to the last commit?

Yep, it recompiles and injects ok now, but those classes are part of a library so I had to edit inside it. Anyway, now I at least know what are some additional caveats.

Yes, I imagine most people are injecting UIViewControllers where NSObject comes for free. Thanks for taking the time to report this. I'll see if I can replicate and find a solution but it might be tricky. Seems like I need to find an alternative for superclass and isSubclass not dependant on Objective-C.

Thank you for your work on HotReloading, still amazing with all the limitations!

Btw, the library in place was https://github.com/QuickBirdEng/XCoordinator so you can see there all the inheritance and from what they started so that you can replicate it.

Thanks, I chip away at the limitations as people report them. I've pushed another commit to the HotReloading branch which moves further away from the runtime apis. Are you able to do a quick check to see if there is anything else that your class trips up?

Pulled and tried again, still looks the same as the last crash

Are you sure you're refreshing the branch? It can't look the same as the code has changed. Try "Reset Package Cache" or "Update Package". The commit is d16e554 which you can also enter.

Yeah, you were right, I did update packages and clean build and now got different error
Screenshot 2023-03-11 at 19 07 01

I've pushed another commit. I thought === would be safer but I've seen it fail before. Can you try f67d5a6 please?

Aha, it seems to be working now! One thing I've noticed is that there are now lots of some gunzip/grep commands going on in the first recompile, but later it injects much faster.

Great, happy to hear it. The greps happen the first time you inject a particular file and after that it is cached in memory. You obviously have quite a large project if you're noticing that. I've pushed another commit which uses the disk cache more if you want to try it. 46b68dd

Tried it, no big difference, but that's ok. Important thing is that now it works. Thanks

Strange, it should have remove the initial scan if you're injecting a file that you've injected before. I'll leave the change in as it should fail-safe and delete the cache entry if a compile fails. Thanks again for raising this issue. This has been one of the more useful ones! Removing those last vestiges of dependency on the Objective-C runtime was worth it. Let me know if anything else crops up otherwise I'll merge the branch later today.

Actually, it does improve compiling the first time, I guess I didn't apply the update properly again. After removing and adding the package, and clean build now I see it injects faster.

I wondered about that... The easiest way to flush the package cache and be sure you have the right version is to select the "commit" 326a5e6 as you add the package instead of the branch or tag. I've pushed another change reverting to using class_getSuperclass() which seems to be a generic-proof api (it doesn't do much). In the new version you can now add a @objc func injected() method to classes that don't inherit from NSObject and have them called on injection. See how you go.

I've merged and tagged this now as 4.11.0. If you could give it a try and let me know if there are any problems I'd appreciate it. Thanks again for taking the time to raise this issue and try the various versions!