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

State tracking based - isa swizzle #492

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

naftaly
Copy link
Contributor

@naftaly naftaly commented May 26, 2024

If we can, we try and swizzle App and Scene delegates.


This is a proposal. What you have already works just fine, but it could be a bit more precise.


Lifecycle delegate and notifications don't happen in the same stack, the stack unwinds after the delegate calls.

run loop cycle 1: Application -> Delegate
run loop cycle 2: Application -> Notification

Due to this, it's very hard for a system to receive lifecycle events before the app it is being installed in. This can lead to mismatched user perception (foreground when the app is actually background). That mismatch leads to wrongly categorizing issues reported by the system.

To fix this, we need to swizzle app a scene delegates. This allows us to receive delegate callbacks before anyone else and correctly record the state of the app before the app has a chance to run any code in those transitions and possibly cause a reliability event.


The swizzle is the same kind of swizzling used in KVC as described here.

@naftaly
Copy link
Contributor Author

naftaly commented May 27, 2024

@GLinnik21 @bamx23 for review, low pri.

@naftaly naftaly marked this pull request as ready for review June 1, 2024 16:20
Copy link
Collaborator

@GLinnik21 GLinnik21 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much!
I think this is a good improvement to KSCrash.

_transitionComplete = YES;
NSLog(@"[AC] %s, completed: %d", ksapp_transition_state_to_string(transitionState), _transitionComplete);

// send delegate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIP?

if (completeOnNextLoop) {
__weak typeof(self)weakMe = self;
CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{
[weakMe _locked_completeState:transitionState];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you ensure that all current processing related to the state change is fully completed before marking the transition as complete, but notify observers right away?


+ (void)load
{
static BOOL sDontSwizzle = [NSProcessInfo.processInfo.environment[@"KSCRASH_APP_SCENE_DELEGATE_SWIZZLE_DISABLED"] boolValue];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this env for debug purposes only? Is there a way to disable it in a production env, for instance in SPM?


@end

@interface Proxier : NSObject
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to move to another file?


static void __KS_CALLING_DELEGATE__(id self, SEL cmd, id arg)
{
std::string name(sel_getName(cmd));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I would avoid C++ if it's needed only for collections

NSLog(@"[MAP] %s", name.c_str());
const auto it = gMappings.find(name);
if (it != gMappings.end()) {
NSLog(@"[MAP:implemented] %s", name.c_str());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can KSLog be used here?


@implementation __KS_CALLING_DELEGATE_TEMPLATE__

static BOOL SwizzleInstanceMethod(Class klass, SEL originalSelector, SEL swizzledSelector)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this function be useful in other parts of the library?

if (sDontSwizzle) {
return;
}
#if KSCRASH_HAS_UIAPPLICATION
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You check it in the beginning of the file. In case this check is needed, maybe there is no point to run +load if the OS does'n support UIApplication?

@naftaly naftaly closed this Jun 3, 2024
@naftaly naftaly reopened this Jun 3, 2024
@naftaly naftaly marked this pull request as draft June 3, 2024 13:18
@GLinnik21
Copy link
Collaborator

@naftaly I noticed that there are conflicts in this pull request. Do you still plan to merge it?

@naftaly
Copy link
Contributor Author

naftaly commented Jul 4, 2024

@naftaly I noticed that there are conflicts in this pull request. Do you still plan to merge it?

I don’t have time in the near future, but I think it’s an improvement to KS so if you want maybe you can commandeer and move it forward?

@GLinnik21
Copy link
Collaborator

@naftaly My apologies for the very delayed response. I've been quite busy lately and have also been focusing on preparing version 2.0. Given that it's been two months, this PR likely has even more conflicts now, which will only worsen over time. Perhaps we should revisit this feature after the 2.0 release? When you have time, it would be great if you could take another look and possibly rebase it. You're more familiar with the initial implementation, so your drive on this would be valuable. Let me know your thoughts on timing and next steps, considering the current state of the PR.​​​​​​​​​​​​​​​​

@naftaly
Copy link
Contributor Author

naftaly commented Sep 5, 2024

@GLinnik21 No issues in the delay, there's really no rush. I look forward to v2.0 being released and hopefully merged into larger toolsets that use it. We can revisit in the future. Ping me when you get around to planning for the next versions and we can discuss.

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

Successfully merging this pull request may close these issues.

2 participants