Giter Club home page Giter Club logo

dbdebugtoolkit's Introduction

DBDebugToolkit

Swift version Xcode - Build Version Carthage compatible Swift Package Manager compatible License Platform

DBDebugToolkit is a debugging library written in Objective-C and Swift. It is meant to provide as many easily accessible tools as possible while keeping the integration process seamless.

Features

  • Performance
    • CPU usage (current, max, chart)
    • Memory usage (current, max, chart)
    • FPS (current, min, chart)
    • Widget displaying current CPU usage, memory usage and FPS that stays on top of the screen
    • Simulating memory warning
  • User interface
    • Showing all view frames
    • Slowing down animations
    • Showing touches on screen (useful for recording and screen sharing)
    • Displaying customizable grid overlay on top of the screen
    • Autolayout trace
    • Current view description
    • View controllers hierarchy
    • List of available fonts with preview
    • Showing UIDebuggingInformationOverlay
  • Network
    • List of all the requests sent by the application
    • Request and response preview
  • Resources
    • File system: browsing and removing selected files
    • User defaults: browsing, removing selected item and clearing all the data
    • Keychain: browsing, removing selected item and clearing all the data
    • Core Data: browsing all the managed objects and their relationships with sorting and filtering options
    • Cookies: browsing, removing selected cookie and clearing all the data
  • Console
    • Displaying console output in text view
    • Sending console output by email with device and system information
  • Simulating location
  • Crash reports
    • List of all the crashes
    • Crash reports containing details, stack trace, console output and a screenshot
    • Sending crash reports by system actions
  • Modifying custom variable values from the menu
  • Adding custom actions to the menu
  • Opening application settings
  • Application shortcut item for clearing data
  • Showing version & build number
  • Showing device model & iOS version

Example

To run the example project, clone the repo, and run pod install from the Example directory first. The example project is written in Objective-C. The code examples in this README are written in Swift 3.0.

Requirements

DBDebugToolkit requires iOS 13.0 or later.

Usage

Setup

DBDebugToolkit was meant to provide as many useful debugging tools as possible. However, the second equally important goal was to keep the setup seamless for all the iOS projects. A good place for setting up DBDebugToolkit is in the AppDelegate, as it allows it to start as quickly as possible. The simplest setup consists of only one line:

import DBDebugToolkit

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    DBDebugToolkit.setup()
    return true
}

After such setup, simply shake the device to present the menu with all the debugging options:

Read more about triggers to find out how to customize menu presentation.

Triggers

Triggers are the objects that tell DBDebugToolkit to present the menu. There are 3 predefined triggers:

  • DBShakeTrigger - reacts to shaking the device.
  • DBTapTrigger - reacts to tapping the screen.
  • DBLongPressTrigger - reacts to long pressing the screen.

By default, DBDebugToolkit is set up with DBShakeTrigger. You can also provide your own array of triggers:

import DBDebugToolkit

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let tapTrigger = DBTapTrigger(numberOfTouchesRequired: 3)
    let longPressTrigger = DBLongPressTrigger(minimumPressDuration: 1.0)
    let shakeTrigger = DBShakeTrigger()
    DBDebugToolkit.setup(with: [tapTrigger, longPressTrigger, shakeTrigger])
    return true
}

These are just examples. Both DBTapTrigger and DBLongPressTrigger have more customization options.

You can also create your own trigger. To do this, create a class that conforms to protocol DBDebugToolkitTrigger. Then create an instance of this class and pass it to the setup method.

Features

The complete list of features with examples can now be found here: Features.

Installation

CocoaPods

DBDebugToolkit is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "DBDebugToolkit"

However, to provide some of its features, DBDebugToolkit does use private API. The code that uses it is obfuscated to minimize the risk of rejecting your application on the App Store, but it can not be guaranteed that it is enough. That being said, here are some safer ways to install DBDebugToolkit:

  • Adding it only to debug builds

    It is now possible to specify the build configuration for a given pod:

    pod "DBDebugToolkit", :configurations => ['Debug']

    After such setup, all your code using DBDebugToolkit needs to be placed in preprocessor macros:

    #if DEBUG
        import DBDebugToolkit
    #endif
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        #if DEBUG
            DBDebugToolkit.setup()
        #endif
        return true
    }

    The one major drawback of such setup is the fact that it won't include DBDebugToolkit in the builds that you send to the testers.

  • Creating a separate target for App Store releases

    After creating a separate target for App Store releases, your podfile could be defined this way:

    def common_pods
      # Here are all the pods that will be used in both targets.
    end
    
    target 'YourApplication' do
        common_pods
    end
    
    target 'YourApplicationAppStore' do
        common_pods
        pod "DBDebugToolkit"
    end

    Then you will have to differentiate between the targets in code. To do this, you could add a custom flag to your App Store target build configuration. Assuming that you named the flag APPSTORE, all the code using DBDebugToolkit will be placed in preprocessor macros:

    #if !(APPSTORE)
        import DBDebugToolkit
    #endif
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        #if !(APPSTORE)
            DBDebugToolkit.setup()
        #endif
        return true
    }

The setup with a separate target for App Store releases will help you prevent sending the build containing the private API calls included in DBDebugToolkit to the App Store review. However, you would have to remember about adding all the files to both targets during development. You will have to decide which way is the best for your project. Perhaps it will be easier to manually remove DBDebugToolkit from the podfile before each App Store release.

Carthage

To integrate DBDebugToolkit into your Xcode project using Carthage, specify it in your Cartfile:

github "dbukowski/DBDebugToolkit" ~> 0.7.0

Run carthage update to build the framework and drag the built DBDebugToolkit.framework into your Xcode project.

Author

Maintained by Gamada-d, [email protected]

Created by Dariusz Bukowski, [email protected]

License

DBDebugToolkit is available under the MIT license. See the LICENSE file for more info.

dbdebugtoolkit's People

Contributors

dbukowski avatar deub27 avatar gamada-de avatar jcavar avatar m-chojnacki avatar m1entus avatar marian-sobczyk avatar qkzhu avatar tayyab-spay avatar westacular avatar zhugexiaobo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dbdebugtoolkit's Issues

App crash when turning off "Logging enabled" at Network Settings screen

When you turn off "Logging enabled" at network setting screen, while it still receiving networking logging, it will crashed, because it tries to access DBNetworkTookit's requests list even after the list is empty.

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index ****5807 beyond bounds for empty array'

Dismissing Two Successive Popups Crashes the Device

After installing DBDebugToolkit, the phone crashes every time two successive popups were created (shown at the same time) and then when dismissing both (one after the other) causes the app to crash. Uninstalling DBDebugToolkit causes the crash not to happen. It is replicable within all scenarios whereby two popups were created and then dismissed.

keyWindow should be used from main thread only

- (void)saveCrashReportWithName:(NSString *)name
                         reason:(NSString *)reason
                       userInfo:(NSDictionary *)userInfo
               callStackSymbols:(NSArray<NSString *> *)callStackSymbols {
    NSDate *date = [NSDate date];
    NSString *consoleOutput = self.consoleOutputCaptor.consoleOutput;
    UIImage *screenshot = [[UIApplication sharedApplication].keyWindow snapshot];
-[UIApplication keyWindow] must be used from main thread only

This is sometimes called on a thread that isn't main and prevents crash reports from being saved.

Invalid Network Table View Management

In a scenario I can reproduce every time, it seems there is an improper management of the table view’s rows:

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (39) must be equal to the number of rows contained in that section before the update (38), plus or minus the number of rows inserted or deleted from that section (1 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

The scenario is go in the Requests screen, and do a scroll to bottom. Then quickly open the debug menu and go in the Network screen. The requests are being updated, and the crash occurs in this method:

- (void)networkDebugToolkit:(DBNetworkToolkit *)networkToolkit didUpdateRequestAtIndex:(NSInteger)index {
    dispatch_async(dispatch_get_main_queue(), ^{
        DBRequestModel *requestModel = self.networkToolkit.savedRequests[index];
        if (requestModel == self.openedRequest) {
            [self.requestDetailsViewController configureWithRequestModel:requestModel];
        }
        [self updateRequests];
        NSInteger updatedRequestIndex = [self.filteredRequests indexOfObject:requestModel];
        if (updatedRequestIndex != NSNotFound) {
            [self.tableView reloadRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:self.filteredRequests.count - 1 - updatedRequestIndex inSection:0] ]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    });
}

Feature request: replace default locations

hello,

I would find useful to have the possibility to replace the locations inserted by default, with a list of locations useful to the context of my project. Is it possible to do this?

Simulator Screen Shot - iPhone 13 - 2022-02-22 at 17 38 49

Broken Basic Authentication

My project is kind of a legacy and uses a library called MKNetworkKit https://github.com/MugunthKumar/MKNetworkKit
It uses NSURLConnection, and like in this ticket #68, swizzling with such library is causing the debug tool kit to fail to read the network calls.

Solution is to downgrade to any version below 0.9.0. However, a new issue will come up. And that is the broken basic authentication.

App crash if call NSURLSessionConfiguration before DBDebgToolkit.setup()

version 0.7.0 crash if any network request triggered before DBDebugToolkit.setup():

file name: NSURLSessionConfiguration+DBURLProtocol.m
[originalProtocols insertObject:DBNetworkURLProtocolClass atIndex:0];
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

The cause is from the update for issue #50.

In this update, NSURLSessionConfiguration+DBURLProtocol.m:
[originalProtocols insertObject:DBNetworkURLProtocolClass atIndex:0]

  1. NSURLSessionConfiguration's swizzing happens in +(void)load, which is when app starts, even before appDelegate.didFinishLaunchingWithOptions.
  2. DBNetworkURLProtocolClass is initialised in + (void)initialize, which will be triggered by DBDebgToolkit.setup().

So, without executing DBDebgToolkit.setup(), DBNetworkURLProtocolClass will not be initialed, and it will be crashed.

We can use load to initialise DBNetworkURLProtocolClass, or ask user to run DBDebgToolkit.setup() before any network calls that involved NSURLSessionConfiguration.

Measuring CPU, Memory and FPS on main thread is not accurate

Hello,

Very nice toolkit!
One thing I’ve noticed is, the more blocked the main thread is, the less accurate the measurements are. Especially the FPS measurement, it is possible to lose entire CPU spikes (60 fps -> quick ramp up of a CPU spike for some time -> 60 fps). I have found that the CADisplayLink strategy for measuring FPS is not the most accurate if main thread spikes exist.

One challenge with moving the measurements to a background queue is updating the widget and table view. This can be solved by using a CATextLayer to update the text in a background queue (CALayer and CATransation are thread safe as of iOS 4).

Would you be interested in a PR that accomplishes this?

SPM Support

Does this framework support Swift Package Manager?

DBURLProtocol breaks text/event-stream requests

text/event-stream requests are "chunked" requests with double newline breaks. Because of the way DBURLProtocol intercepts requests, what ends up happening is all response chunks are batched up until the end and then forwarded to the original response handler. Any ideas how to fix this other than disabling interception altogether?

Weird behavior with URLCache

There is a weird bug related to custom URLSession and URLCache.

Project setup

Here is my AppDelegate that enables DBDebugToolkit.

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        DBDebugToolkit.setup()

        let window = UIWindow(frame: UIScreen.main.bounds)
        self.window = window
        window.backgroundColor = UIColor.white
        window.rootViewController = ViewController()

        window.makeKeyAndVisible()
        return true
    }
}

In my ViewController, I have a button that loads an url with Cache-Control header set, meaning the system should cache the response.

class ViewController: UIViewController {

    private lazy var button: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Load", for: .normal)
        button.addTarget(self, action: #selector(load), for: .touchUpInside)
        return button
    }()

    // Custom URLSession with custom cache and custom diskPath
    private lazy var session: URLSession = {
        let memoryCapacity = 500 * 1024 * 1024 // 500 MB
        let diskCapacity = 500 * 1024 * 1024 // 500 MB

        let cache = URLCache(
            memoryCapacity: memoryCapacity,
            diskCapacity: diskCapacity,
            diskPath: "com.xxxxx.yyyyy"
        )

        let configuration = URLSessionConfiguration.default
        configuration.urlCache = cache

        return URLSession(
            configuration: configuration,
            delegate: self,
            delegateQueue: nil
        )
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(button)
        button.frame = view.bounds
    }

    // MARK: - Private

    @objc private func load() {
        // A ~130 KB image, small enough to be cached by the default URLSession session
        let url = URL(string: "https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80")!
        session.dataTask(with: url).resume()
    }
}

extension ViewController: URLSessionDataDelegate {

    // MARK: - URLSessionDataDelegate

    func urlSession(_ session: URLSession,
                    dataTask: URLSessionDataTask,
                    willCacheResponse proposedResponse: CachedURLResponse,
                    completionHandler: @escaping (CachedURLResponse?) -> Void) {
        print("session:willCacheResponse:")
        completionHandler(proposedResponse)
    }

    func urlSession(_ session: URLSession,
                    dataTask: URLSessionDataTask,
                    didReceive response: URLResponse,
                    completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
        print("dataTask:didReceive response")
        completionHandler(.allow)
    }

    func urlSession(_ session: URLSession,
                    dataTask: URLSessionDataTask,
                    didReceive data: Data) {
        print("data = \(data)")
    }
}

With DBDebugToolKit activated

When I first clic on the load button, the request is sent to the server, and the logs are the following :

dataTask:didReceive response
data = 129408 bytes

When I clic a second time, the request is not sent to the server, the cached image is used and the logs are the same.

We can note that the log print("session:willCacheResponse:") is never called even it should be.

The cache folder structure is : Wrong cache structure

Note the duplication of the Cache.db files. What's more the fsCachedData folder, that contains the cached image, is at the wrong location. That means the image is saved in the default URLCache and not in the custom one I defined in my sesssion.

Without DBDebugToolKit activated

If I trash the app and remove the line DBDebugToolkit.setup() in the AppDelegate, when I first clic on the image, the request is sent to the server and the logs are the following:

dataTask:didReceive response
data = 16384 bytes
data = 16384 bytes
data = 16384 bytes
data = 16383 bytes
data = 16384 bytes
data = 16384 bytes
data = 16384 bytes
data = 14721 bytes
session:willCacheResponse:

Note that this time the logs are correct and session:willCacheResponse: is printed !

The cache folder structure is Correct cache structure
This time there is only one Cache.db file, and the fsCachedData folder is under the com.xxxxx.yyyyy directory. Which is the expected behavior.

Issue

So the issue is that a custom url session with a custom url cache is never taken into account with DBDebugToolkit activated. What's more the URLSessionDataDelegate method urlSession(_:, dataTask:, willCacheResponse:, completionHandler:) is not called.

Unable to pull latest version of pod

In cocoapods.org when I search for DBDebugToolKit Pod it shows version 0.5.0 as latest. I am unable to pull the latest version 0.5.1 .
Screen Shot 2020-06-24 at 1 07 12 PM

When I try to pull the latest version I see this error on my terminal
[!] CocoaPods could not find compatible versions for pod "DBDebugToolkit":
In Podfile:
DBDebugToolkit (~> 0.5.1)

None of your spec sources contain a spec satisfying the dependency: DBDebugToolkit (~> 0.5.1).

(0.9.0) App is Crashing on App Store / Test Flight

Hello!
Version: 0.9.0 installed by cocoapods
App works fine in debug mode, but crashes app immediately on Test Flight/App Store without crash logs.
iOS 15.4.1
Xcode 13.3.1
OS X Monterey
I've experienced similar crashes when external dynamic library was not embedded into the target.

Trouble with view

The same was fixed in other app when I removed NSLogs. This way don't work here.
Have you any ideas how to resolve it?

Снимок экрана 2020-12-10 в 11 51 58

App Extension related error

Снимок экрана 2021-03-05 в 7 37 55 PM

I'm getting this error since I added an target for my app extension to the pod file. Is there any workaround that would allow me to keep using it with this error?

Error: Undefined symbols for architecture x86_64

I got the following error detail when I tried the library in a Objective C project with deployment target 8.0.

Undefined symbols for architecture x86_64:
"OBJC_CLASS$_DBDebugToolkit", referenced from:
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

How to overcome this issue ?

crash when the app send requests

A crash occurred when my app continued to send requests while the Network section was open

__71-[DBNetworkViewController networkDebugToolkit:didUpdateRequestAtIndex:]_block_invoke (DBNetworkViewController.m:210)
__29-[DBMainQueueOperation start]_block_invoke (DBMainQueueOperation.m:72)

DBDebugToolkit (0.6.0)
iOS 15.5
MacOS 12
Xcode 13.4.1

0.9.0 Not working with Alamofire

Bumping from 0.8.0 to 0.9.0 completely breaks all network requests that are done through Alamofire.

This is what I see in the console:

API MISUSE: NSURLSession delegate Alamofire.SessionDelegate: <Alamofire.SessionDelegate: 0x600000e609b0> (0x600000e609b0)
API MISUSE: dataTask:didReceiveResponse:completionHandler: completion handler not called

Feels like methods are not correctly swizzled anymore?

main thread is blocked

In my application, progress stops updating during synchronization. I decided to dig in and found that the main thread from which uiview is updated is busy almost all the time with the same thing.

Can you have any ideas on how to fix this?

DBConsoleOutputCaptor m 2020-07-29 18-33-20

'sharedApplication' is unavailable with XCode9.0

/Pods/DBDebugToolkit/DBDebugToolkit/Classes/DBDebugToolkit.m:100 : 42: 'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.

Version 0.9.0 Crash

image

Steps:

  1. Integrated the SDK with Cocoapods
  2. Does not call DBDebugToolkit.setup()
  3. Run and then crash.

Version: 0.9.0
Xcode Version: 12.5.1
iOS Version: 15.2

Typo in block replacement of [UIView initWithFrame]?

// UIView+DBUserInterfaceToolkit.h

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __block IMP originalInitWithCoderIMP = [self replaceMethodWithSelector:@selector(initWithCoder:)
                                                                         block:^UIView * (UIView *blockSelf, NSCoder *aDecoder) {
                                                                            UIView *res = ((UIView * (*)(id, SEL, NSCoder *))originalInitWithCoderIMP)(blockSelf, @selector(initWithCoder:), aDecoder);
                                                                            [res db_refreshDebugBorders];
                                                                            [res db_registerForNotifications];
                                                                            return res;
                                                                         }];
        __block IMP originalInitWithFrameIMP = [self replaceMethodWithSelector:@selector(initWithFrame:)
                                                                         block:^UIView * (UIView *blockSelf, CGRect frame) {
                                                                             UIView *res = ((UIView * (*)(id, SEL, CGRect))originalInitWithFrameIMP)(blockSelf, @selector(initWithCoder:), frame);
                                                                             [res db_refreshDebugBorders];
                                                                             [res db_registerForNotifications];
                                                                             return res;
                                                                         }];
        __block IMP originalDeallocIMP = [self replaceMethodWithSelector:NSSelectorFromString(@"dealloc")
                                                                   block:^(__unsafe_unretained UIView *blockSelf) {
                                                                       [[NSNotificationCenter defaultCenter] removeObserver:blockSelf];
                                                                       ((void (*)(id, SEL))originalDeallocIMP)(blockSelf, NSSelectorFromString(@"dealloc"));
                                                                   }];
    });
}

Is there a bug with this line:

UIView *res = ((UIView * (*)(id, SEL, CGRect))originalInitWithFrameIMP)(blockSelf, @selector(initWithCoder:), frame);

You pass @selector(initWithCoder:) but shouldn't you pass @selector(initWithFrame:)?

using DBDebugToolkit will cause bugs when uploading files with AFNetworking

AFURLRequestSerialization.m

- (NSInteger)read:(uint8_t *)buffer
        maxLength:(NSUInteger)length
{
    if ([self streamStatus] == NSStreamStatusClosed) {
        return 0;
    }

    NSInteger totalNumberOfBytesRead = 0;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
    while ((NSUInteger)totalNumberOfBytesRead < MIN(length, self.numberOfBytesInPacket)) {
        if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) {
            if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) {
                break;
            }
        } else {
            NSUInteger maxLength = MIN(length, self.numberOfBytesInPacket) - (NSUInteger)totalNumberOfBytesRead;
            NSInteger numberOfBytesRead = [self.currentHTTPBodyPart read:&buffer[totalNumberOfBytesRead] maxLength:maxLength];
            if (numberOfBytesRead == -1) {
                self.streamError = self.currentHTTPBodyPart.inputStream.streamError;
                break;
            } else {
                totalNumberOfBytesRead += numberOfBytesRead;

                if (self.delay > 0.0f) {
                    [NSThread sleepForTimeInterval:self.delay];
                }
            }
        }
    }
#pragma clang diagnostic pop

    return totalNumberOfBytesRead;
}

qq20170404-175231 2x

feature: copy button for request and response body

Could you add a button that allows to copy the entire request and response body? Often they are huge, and scrolling and selecting is very inconvenient. cmd+A not always works in simulator

Thank you

Crash Reporting

My initial setup for DBDebugToolkit is:

let shakeTrigger = DBShakeTrigger()
            DBDebugToolkit.setup(with: [shakeTrigger])
            DBDebugToolkit.setupCrashReporting()
            DBDebugToolkit.addClearDataShortcutItem()
            let clearDefaultsAction = DBCustomAction(name: "Clear User Defaults") {
                DBDebugToolkit.clearUserDefaults()
            }
            DBDebugToolkit.add(clearDefaultsAction)

The issue i have: no crash reports are being made.

I have intentionally crashed the app, and even purposefully loaded large images and created OOM errors and there have been no crash logs being logged.

Did i miss some obvious configuration setup?

DBDebugToolkit' contains mixed language source files; feature not supported

xcodebuild: error: Could not resolve package dependencies:
target at '.../Library/Developer/Xcode/DerivedData/../SourcePackages/checkouts/DBDebugToolkit/DBDebugToolkit' contains mixed language source files; feature not supported

Using Tuist with version 0.8.0 and 0.9.0 is failing with above error

Xcode 14.2

Exception: "UISearchDisplayController is no longer supported on iOS 13

I tried to integrate this toolkit into my project (supported from iOS 13) and I got this crash when I chose the Network.
Thread 1: Exception: "UISearchDisplayController is no longer supported when linking against this version of iOS. Please migrate your application to UISearchController."

DBDebugToolkit breaks progress callbacks on multipart upload tasks

Due to the way DBRequestModel intercepts requests progress block is never called when using file upload task for a multi-part request from AFNetworking.

Example code:

NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];
    } error:nil];

AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
              uploadTaskWithStreamedRequest:request
              progress:^(NSProgress * _Nonnull uploadProgress) {
                  // This block is never called after installing DBDebugToolkit
                  dispatch_async(dispatch_get_main_queue(), ^{
                      //Update the progress view
                      [progressView setProgress:uploadProgress.fractionCompleted];
                  });
              }
              completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                  if (error) {
                      NSLog(@"Error: %@", error);
                  } else {
                      NSLog(@"%@ %@", response, responseObject);
                  }
              }];

[uploadTask resume];

This issue caused us a lot of problems related to disappearing file upload progress bars etc. and we tracked the problem to be related with DBDebugToolkit. We can't use it anymore because just calling [DBDebugToolkit setup]; results in our app being unstable and behaving differently than it used to.

In my opinion, if it's impossible to intercept multi-part upload request without breaking its documented behavior, such a requests shouldn't be intercepted and logged at all (logging such requests should be opt-in), or at least we should have a way to disable it.

Last console messages are missing before crash

For debugging purposes I've written

@objc public func onPlayButtonTapped() { 
  logger.warning("`last message before crashing`")
  assert(false)
}

so that I can log to the console and trigger a crash by tapping on a button.

Generally a crash report gets generated as expected:
Screen Shot 2021-05-13 at 3 47 25 PM

Also a screenshot is generated and I can see some of the console output.
However, the last messages, in this case "last message before crashing" is missing.

How can I ensure that the console output is always persisted before the app crash handling terminates?

Edit: I'm using the latest version 0.6.0

DBDebugToolkit not compatible with ATS and self-signed certificate

Hi,

For first, very good job, I'm trying to use your library and it appears that it's not compatible with URLSessionDelegate, in my app i'm using https with a self-signed certificate and I use URLSessionDelegate for debug and when i'm setup your library, delegate are not fired and make me errors.

Steps for reproducing:
AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        #if DEBUG
            DBDebugToolkit.setup() // <-- if I comment network works good
        #endif

        ...

SSLDebugSessionDelegate.swift

class SSLDebugSessionDelegate: NSObject, URLSessionDelegate {
    
    /// The host to allow a self-signed SSL certificate for.
    let host: String
    
    
    /** Designated initializer.
     
     - parameter host: The host to which the exception should apply
     */
    public init(host: String) {
        self.host = host
    }
    
    open func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge,
                         completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        Log.debug("----DEBUG SESSION DELEGATE----")
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            if challenge.protectionSpace.host == host, let trust = challenge.protectionSpace.serverTrust {
                let credential = URLCredential(trust: trust)
                completionHandler(.useCredential, credential)
                return
            }
        }
        completionHandler(.performDefaultHandling, nil)
    }

}
let sessionDelegate = SSLDebugSessionDelegate(host:"xxxxxxx")
URLSession(configuration: config, delegate: sessionDelegate, delegateQueue: nil)

And use a self-signed certificate.

Allow to register subclass of DBURLProtocol on to NSURLSessionConfiguration

Hey, i have i case where i would like to register our subclass of DBURLProtocol as a default protocol of db_defaultSessionConfiguration and db_ephemeralSessionConfiguration in addition to that i would love to allow to have it also here:

+ (void)setupURLProtocol {
    [NSURLProtocol registerClass:[DBURLProtocol class]];
}

Can you allow to set custom class as a default URLProtocol ? Can it be as a static Class property.

The use case is that custom library is creating URLSession and we don't want to intercept their network requests and would like to skip logging when they make an request:

+ (instancetype)db_defaultSessionConfiguration {
    NSURLSessionConfiguration *defaultSessionConfiguration = [self db_defaultSessionConfiguration];
    NSMutableArray *originalProtocols = [NSMutableArray arrayWithArray:defaultSessionConfiguration.protocolClasses];
    [originalProtocols insertObject:[DBURLProtocol class] atIndex:0];
    defaultSessionConfiguration.protocolClasses = originalProtocols;
    return defaultSessionConfiguration;
}
``

SPM Support

Is there a possibility for us to get a SPM support? It would be sooo much easier just to use it. Thanks!

must be used from main thread only

        __block IMP originalInitWithCoderIMP = [self replaceMethodWithSelector:@selector(initWithCoder:)
                                                                         block:^UIView * (UIView *blockSelf, NSCoder *aDecoder) {
                                                                            UIView *res = ((UIView * (*)(id, SEL, NSCoder *))originalInitWithCoderIMP)(blockSelf, @selector(initWithCoder:), aDecoder);
                                                                            [res db_refreshDebugBorders];
                                                                            [res db_registerForNotifications];
                                                                            return res;
                                                                         }];

I got crash in this line:

UIView *res = ((UIView * (*)(id, SEL, NSCoder *))originalInitWithCoderIMP)(blockSelf, @selector(initWithCoder:), aDecoder);

error:
-[UIView initWithCoder:] must be used from main thread only

I understand the gist of the error, but I don't call load directly

NSURLSession redirection handling broken

We use AFNetworking and have code like the following

let httpSessionManager = AFHTTPSessionManager(baseURL: baseURL)
httpSessionManager.setTaskWillPerformHTTPRedirectionBlock { urlSession, task, response, request in
  return someCheck
    ? request
    : nil // Stop following redirect
}

After we integrated DBDebugToolkit we noticed that this block was not getting called anymore. Disabling networking logging via DBDebugToolkit.setNetworkRequestsLoggingEnabled(false) fixes the issue.

I looked at AFNetworking's related code (part 1, part 2) and it does not seem to do anything special which leads me to believe that this is a general issue.

Please let me know if additional information is needed to reproduce this behavior.

Cannot remove an observer for the key path "layer.sublayers" from <_UIAlertControllerShimPresenterWindow 0x102cdacd0> because it is not registered as an observer.

  • (void)windowDidResignKey:(UIWindow *)window {
    [window removeObserver:self forKeyPath:@"layer.sublayers"]; // causes exception if UIPickerView is displayed from modal form
    }

*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <DBPerformanceToolkit 0x1741193e0> for the key path "layer.sublayers" from <_UIAlertControllerShimPresenterWindow 0x102cdacd0> because it is not registered as an observer.'

Also wrapping a try-catch around it does not fix the issue.

When application's build being installed to iPhone via Firebase App Distribution, console output in DBDebugToolkit is not complete (many lines are missing)

Hello, dbukowski!

I've faced an issue (bug?) while using DBDebugToolkit with Swift iOS(iPhone) application. If app being built to Simulator, or directly to device using XCode and usb cable, everything works perfectly fine.

But for testing purposes, I upload application to Firebase App Distribution. I do that with Fastlane. Fastlane builds the app, and then loads the build to Firebase App Distribution (through Firebase CLI). After that, the build becomes available for installation on approved devices without a cable, directly from Firebase App Distribution service.

When app installed this way, Console output in DBDebugToolkit is incomplete. Many lines are, for sure, missing. And, sometimes, missing lines appear, but with long delay. Sometimes missing lines don't appear at all.

What I've tried:
1/ Change build configuration from debug to adhoc and build directly to device using usb cable - console output was complete, means issue is not dependant on build configuration.
2/ Change build options in Fastfile and build to Firebase again (available options: include bitcode, include symbols) - nothing changed.

About environment:
Xcode 13.1
Swift 5
DBDebugToolkit 0.6.2
Fastlane 2.205.1

My build settings in fastfile:
Screenshot 2022-03-29 at 12 39 11

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.