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

"FetchWithCompletion" is never called during network loss #19

Open
cafedeichi opened this issue Apr 5, 2023 · 4 comments
Open

"FetchWithCompletion" is never called during network loss #19

cafedeichi opened this issue Apr 5, 2023 · 4 comments

Comments

@cafedeichi
Copy link

Expected Behavior

"FetchWithCompletion" is never called in any case of errors.

Current Behavior

"FetchWithCompletion" is never called during network loss. This behavior can be reproduced by enabling Airplane mode on iOS.

Possible Solution

Steps to Reproduce

  1. Enable Airplane mode on iOS.
  2. Call Variables.fetch(completion:)
  3. Confirm whether the completion block is called.

SDK Version

  • KarteCore 2.21.0
  • KarteCrashReporting 2.5.0
  • KarteInAppMessaging 2.13.0
  • KarteRemoteNotification 2.8.0
  • KarteVariables 2.4.1
  • KarteVisualTracking x.x.x
  • KarteUtilities 3.7.0
  • KarteNotificationServiceExtension x.x.x

iOS Version

16.0 or later

Build Environment

  • macOS Version 13.2.1
  • Xcode Version 14.3.0
  • CocoaPods Version 1.11.3
  • Carthage Version x.x.x

Context Details

Cannot handle the error at all is some cases.

Logs

Possible Implementation

@SojiroNishimura
Copy link
Contributor

Thank you for your report. We have investigated the behavior you reported and were unable to reproduce it on a physical device, but a similar one was reproduced on a simulator.

It seems the following events are causing the issue:

  1. When an App is launched on a simulator in a disconnected network state, the event that should be sent when the app starts is not sent and is queued instead.
  2. When explicitly executing Variables.fetch(), it attempts to send the queued events.
  3. The retransmission process for queued events is executed multiple times.
  4. The callback for Variables.fetch() is not executed until the above retransmission process is completed.

As a result, the execution of the callback becomes extremely slow (up to 1-2 minutes), and it appears that the callback is not being executed.
The queuing mentioned above does not occur during Airplane mode on a physical device, so it was not reproduced in the following environments.

macOS: 13.3(22E252)
Xcode: Version 14.3 (14E222b)
iPhone13 Pro: iOS 16.0.2
KarteCore: 2.21.0
KarteVariables: 2.4.1
KarteUtilities: 3.7.0


Could you please provide the following information for a more detailed investigation?

  • Is the execution environment a physical device or a simulator?
  • When the phenomenon occurs, does the callback not execute even after approximately 2 minutes?
  • If it occurs on a physical device, please provide specific codes to reproduce the issue.

@cafedeichi
Copy link
Author

In our case, the issue occurred on our app on physical devices, such as the iPhone 12 Pro (iOS 16.4) and iPhone 14 Pro (iOS 16.3), whereas it worked fine on iOS simulators. Although we checked if the completion handler would be called a few minutes later, it didn't even after 5 minutes.
By the way, the issue occurs only once immediately after launching the app; the second attempt to call the procedure successfully returns the completion handler.

The usage might be a bit different from what you expected us to do, since we don't call Variables.fetch() in AppDelegate, but in the ViewController that loads when launching the app. This is because Variables.fetch() often fails to fetch the data needed to compose crucial parts of the screen, and the app needs to be refreshed manually in that case.

The followings are excerpt from the code.

    // KARTE Utility
    func fetchVariables(completion: ((_ isSuccessful: Bool) -> Void)? = nil) {
        Variables.fetch(completion: completion)
    }
    // View Model
    dispatchGroup.enter()
    KarteUtils.shared.fetchVariables { isSuccessful in
        if isSuccessful {
            // Create model data using the fetched variables.
        } else {
            // Record errors
        }
        dispatchGroup.leave()
    }

    dispatchGroup.enter()
    api.fetchSomething (
        error: { err in
            // Do something
            dispatchGroup.leave()
        }, success: { entity in
            // Do something
            dispatchGroup.leave()
        })

    dispatchGroup.enter()
    api.fetchSomething2 (
        error: { err in
            // Do something
            dispatchGroup.leave()
        }, success: { entity in
            // Do something
            dispatchGroup.leave()
        })
    .
    .
    dispatchGroup.notify(queue: .main) {
        // Wrap up something
    }

@SojiroNishimura
Copy link
Contributor

SojiroNishimura commented Apr 14, 2023

Thank you for providing the detailed information. Based on the information, we were able to reproduce the issue on our end as well. We are still investigating the details, but since it only occurs once after launching and does not occur afterward, it seems the following possibilities are highly likely:

  1. Execute Variables.fetch() in viewDidLoad(or similar lifecycle methods).
  2. When the network is disconnected, viewDidLoad ends before the callback is executed.
  3. As a result, the callback is not executed.

Although it is not yet confirmed, we think that the reason why this phenomenon does not occur when the network is active is that a separate thread is launched during communication execution(Variables.fetch()), and the callback is executed in that thread.

Based on the above hypothesis, we confirmed that the callback is executed even when the network is disconnected by executing Variables.fetch() within DispatchQueue.main.async. While we will consider this issue for future improvements, could you please try using a workaround such as using DispatchQueue for the time being?

We apologize for any inconvenience this may cause, and thank you for your cooperation.

@cafedeichi
Copy link
Author

cafedeichi commented Apr 21, 2023

Speaking of which, this issue can be reproduced in the case of using a content blocker app, such as AdGuard. We actually realized the malfunction the first time we enabled its DNS protection features.

Although the following guide says that the kind of apps don't affect KARTE features, they actually do in some cases as we discovered this time. It would be helpful if the guide could elaborate on these cases.

https://support.karte.io/faq/3sYYNDdIOBgfeEtWly62H9

Thanks.

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

2 participants