Latest 1.0.0
Homepage https://github.com/google/resumable-assert
License Apache
Platforms ios 9.0, osx 10.10, tvos 9.0

ApacheLicense

Resumable Assert

ResumableAssert

Assert replacement to continue execution in debugger

In any large app, it’s entirely possible some assert is failing in code you
don’t currently care about, and blocking the entire team from being able to run
the app until the issue is fixed is not the best workflow. So we usually end up
moving the execution marker past the assert line in IDE or debugger, or even
comment the assert out, recompile and relaunch. With ResumableAssert, you can
finally ignore or disable asserts that you are not interested in.

Disclaimer: be careful with that power though, since execution of potentially
broken code may lead to unrecoverable errors in future.

C/C++/Objective-C

First, include or import the header:

#import "ResumableAssert.h"

Then, use the RESUMABLE_ASSERT() or RESUMABLE_ASSERT_WITH_FORMAT() macros
instead of the standard ones:
assert(),
NSAssert(),
etc.

Once RESUMABLE_ASSERT() variant is hit in debug mode, you can ignore or
disable it, or even disable all asserts permanently with corresponding lldb
commands when prompted.

For example, the code:

RESUMABLE_ASSERT(2 + 2 == 5);
// Or:
RESUMABLE_ASSERT_WITH_FORMAT(2 + 2 == 5, "Calculation failure");

Leads to the following debugger console output:

ViewController.m:-[ViewController viewDidLoad]:42
2 + 2 == 5
Calculation failure
Type the following lldb commands to resolve and continue:
e ignore = 1   # ignore this assert this time
e disable = 1  # disable this assert permanently
e unleash = 1  # disable all asserts permanently

Where you can choose an option and continue:

(lldb) e ignore = 1
(volatile int) $1 = 1
(lldb) c
Process 11193 resuming

Custom logging

RESUMABLE_ASSERT() macro in C use stdout to print the failure message by
default. To change this behavior and use something else for logging,
(e.g. NSLog())
redefine the RESUMABLE_ASSERT_LOG() macro in C like so:

#import <Foundation/Foundation.h>

#include "ResumableAssert.h"

#undef RESUMABLE_ASSERT_LOG
#define RESUMABLE_ASSERT_LOG(__condition__, __format__, ...)            
  do {                                                                  
    NSLog(@"%s:%un%sn" __format__,                                    
          __PRETTY_FUNCTION__, __LINE__, __condition__, ##__VA_ARGS__); 
  } while (0)

Swift

For Swift and other languages we provide resumableAssertDebugTrap()
function that implements the core loop of resumable assert. You can then
implement a custom assert function which would use it internally:

import ResumableAssert

public func assert(
  _ condition: @autoclosure () -> Bool,
  _ message: @autoclosure () -> String = "",
  file: StaticString = #file,
  function: StaticString = #function,
  line: UInt = #line
) {
#ifdef DEBUG
  if !condition() {
    print("Assertion failed: " + (message.isEmpty ? "" : "(message): ") +
          "file (file.description), function (function.description), line (line)")
    resumableAssertDebugTrap()
  }
#endif
}

Latest podspec

{
    "name": "ResumableAssert",
    "version": "1.0.0",
    "authors": "Google Inc.",
    "license": {
        "type": "Apache",
        "file": "LICENSE"
    },
    "homepage": "https://github.com/google/resumable-assert",
    "source": {
        "git": "https://github.com/google/resumable-assert.git",
        "tag": "1.0.0"
    },
    "summary": "Assert replacement to continue execution in debugger",
    "description": "ResumableAssert allows to ignore or disable assertion failure and continue execution in debugger.",
    "platforms": {
        "ios": "9.0",
        "osx": "10.10",
        "tvos": "9.0"
    },
    "swift_version": "4.0",
    "prefix_header_file": false,
    "public_header_files": "Sources/ResumableAssert/include/**/*.h",
    "source_files": "Sources/ResumableAssert/**/*.{h,m,swift}",
    "xcconfig": {
        "HEADER_SEARCH_PATHS": ""${PODS_TARGET_SRCROOT}/Sources/ResumableAssert/include""
    }
}

Pin It on Pinterest

Share This