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

deps(react-native): Update bugsnag-cocoa to v6.6.0 #1252

Merged
merged 3 commits into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## TBD

## Changed

- (react-native): Update bugsnag-cocoa to v6.6.0
- The NSError `userInfo` property is now included in reports. [bugsnag-cocoa#974](https://github.com/bugsnag/bugsnag-cocoa/pull/974)

### Fixed

- (react-native): Ensure plugin usage is compatible with running an app in a remote debugger [#1250](https://github.com/bugsnag/bugsnag-js/pull/1250)
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/ios/.bugsnag-cocoa-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f9930364f4dc7c488dafdef977d6bcfc67f3c233
b834068ab0e12ffb31b9e2dc7d4116553d86b5ff
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
01E5EA7D25B5F2950066EA8A /* BugsnagReactNativePlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 65ED539523D86A45006E3DC2 /* BugsnagReactNativePlugin.m */; };
65AE6AA923D89BDD00301CC1 /* BugsnagReactNativeEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 65AE6AA423D89BDC00301CC1 /* BugsnagReactNativeEmitter.m */; };
8AD256171D6DE5F600C7D842 /* BugsnagReactNative.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8AD256161D6DE5F600C7D842 /* BugsnagReactNative.h */; };
8AD256191D6DE5F600C7D842 /* BugsnagReactNative.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AD256181D6DE5F600C7D842 /* BugsnagReactNative.m */; };
Expand All @@ -19,6 +20,13 @@
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
01E5EA5525B5F0920066EA8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = E72B3217241FC479005FB2CA /* React.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 83CBBA2D1A601D0E00E9B192;
remoteInfo = React;
};
E72B322A241FC479005FB2CA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = E72B3217241FC479005FB2CA /* React.xcodeproj */;
Expand Down Expand Up @@ -344,6 +352,7 @@
buildRules = (
);
dependencies = (
01E5EA5625B5F0920066EA8A /* PBXTargetDependency */,
);
name = BugsnagReactNative;
productName = BugsnagReactNative;
Expand Down Expand Up @@ -562,6 +571,7 @@
buildActionMask = 2147483647;
files = (
E7A8E9D624602C9800CCBBD1 /* BugsnagEventDeserializer.m in Sources */,
01E5EA7D25B5F2950066EA8A /* BugsnagReactNativePlugin.m in Sources */,
65AE6AA923D89BDD00301CC1 /* BugsnagReactNativeEmitter.m in Sources */,
8AD256191D6DE5F600C7D842 /* BugsnagReactNative.m in Sources */,
E7819C5C2459C7A100A7EBDD /* BugsnagConfigSerializer.m in Sources */,
Expand All @@ -570,6 +580,14 @@
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
01E5EA5625B5F0920066EA8A /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = React;
targetProxy = 01E5EA5525B5F0920066EA8A /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
8AD2561A1D6DE5F600C7D842 /* Debug */ = {
isa = XCBuildConfiguration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

#import "BugsnagConfigSerializer.h"
#import "BugsnagCollections.h"

@implementation BugsnagConfigSerializer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
#import "BugsnagThread+Private.h"
#import "BugsnagUser+Private.h"

@interface BugsnagEvent ()
- (void)attachCustomStacktrace:(NSArray *)frames withType:(NSString *)type;
@end

@implementation BugsnagEventDeserializer

- (BugsnagEvent *)deserializeEvent:(NSDictionary *)payload {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
#import "BugsnagConfigSerializer.h"
#import "BugsnagEventDeserializer.h"

@interface Bugsnag ()
+ (void)updateCodeBundleId:(NSString *)codeBundleId;
+ (void)notifyInternal:(BugsnagEvent *_Nonnull)event
block:(BOOL (^_Nonnull)(BugsnagEvent *_Nonnull))block;
+ (void)addRuntimeVersionInfo:(NSString *)info
withKey:(NSString *)key;
@end

@interface BugsnagReactNative ()
@property (nonatomic) BugsnagConfigSerializer *configSerializer;
@end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
#import "BugsnagReactNativeEmitter.h"

#import "Bugsnag+Private.h"
#import "BugsnagClient.h"
#import "BugsnagClient+Private.h"
#import "BugsnagStateEvent.h"

typedef void (^BugsnagObserverBlock)(BugsnagStateEvent *_Nonnull event);

@interface BugsnagClient ()
- (void)addObserverWithBlock:(BugsnagObserverBlock _Nonnull)block;
- (void)removeObserverWithBlock:(BugsnagObserverBlock _Nonnull)block;
@end

@interface BugsnagMetadata ()
- (NSDictionary *)toDictionary;
@end

@interface BugsnagReactNativeEmitter ()
@property BugsnagObserverBlock observerBlock;
@end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#import "BugsnagReactNativePlugin.h"

#import "Bugsnag.h"
#import "BugsnagClient+Private.h"
#import "BugsnagConfiguration.h"
#import "BugsnagError.h"

@interface BugsnagReactNativePlugin () <BugsnagPlugin>
Expand Down
11 changes: 11 additions & 0 deletions packages/react-native/ios/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# BugsnagReactNative contributing guide

`BugsnagReactNative.xcodeproj` is a convenience, and not used during the build.

It can be used to quickly verify that the `BugsnagReactNative` sources build against the latest bugsnag-cocoa release.

It relies on `React.xcodeproj` which was removed in React Native 0.60, so to be able to build the Xcode project you must install React Native 0.59 from within the parent (`react-native`) directory;

```
npm install [email protected]
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Bugsnag",
"version": "6.5.1",
"version": "6.6.0",
"summary": "The Bugsnag crash reporting framework for Apple platforms.",
"homepage": "https://bugsnag.com",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
},
"source": {
"git": "https://github.com/bugsnag/bugsnag-cocoa.git",
"tag": "v6.5.1"
"tag": "v6.6.0"
},
"frameworks": [
"Foundation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
008967122486D43700DC48C2 /* BugsnagEventTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B32486D43500DC48C2 /* BugsnagEventTests.m */; };
008967132486D43700DC48C2 /* BugsnagEventTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B32486D43500DC48C2 /* BugsnagEventTests.m */; };
008967142486D43700DC48C2 /* BugsnagEventTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B32486D43500DC48C2 /* BugsnagEventTests.m */; };
008967152486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B42486D43500DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m */; };
008967162486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B42486D43500DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m */; };
008967172486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B42486D43500DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m */; };
008967152486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B42486D43500DC48C2 /* BugsnagCollectionsTests.m */; };
008967162486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B42486D43500DC48C2 /* BugsnagCollectionsTests.m */; };
008967172486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B42486D43500DC48C2 /* BugsnagCollectionsTests.m */; };
008967182486D43700DC48C2 /* BugsnagErrorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B52486D43500DC48C2 /* BugsnagErrorTest.m */; };
008967192486D43700DC48C2 /* BugsnagErrorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B52486D43500DC48C2 /* BugsnagErrorTest.m */; };
0089671A2486D43700DC48C2 /* BugsnagErrorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966B52486D43500DC48C2 /* BugsnagErrorTest.m */; };
Expand Down Expand Up @@ -1056,7 +1056,7 @@
008966B02486D43500DC48C2 /* BugsnagSwiftPublicAPITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugsnagSwiftPublicAPITests.swift; sourceTree = "<group>"; };
008966B12486D43500DC48C2 /* BugsnagSwiftConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugsnagSwiftConfigurationTests.swift; sourceTree = "<group>"; };
008966B32486D43500DC48C2 /* BugsnagEventTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagEventTests.m; sourceTree = "<group>"; };
008966B42486D43500DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagCollectionsBSGDictMergeTest.m; sourceTree = "<group>"; };
008966B42486D43500DC48C2 /* BugsnagCollectionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagCollectionsTests.m; sourceTree = "<group>"; };
008966B52486D43500DC48C2 /* BugsnagErrorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagErrorTest.m; sourceTree = "<group>"; };
008966B62486D43500DC48C2 /* BugsnagSessionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagSessionTest.m; sourceTree = "<group>"; };
008966B72486D43500DC48C2 /* report.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = report.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1669,7 +1669,7 @@
008966CA2486D43600DC48C2 /* BugsnagClientMirrorTest.m */,
008966A52486D43400DC48C2 /* BugsnagClientPayloadInfoTest.m */,
008966BE2486D43500DC48C2 /* BugsnagClientTests.m */,
008966B42486D43500DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m */,
008966B42486D43500DC48C2 /* BugsnagCollectionsTests.m */,
00896A432486DBF000DC48C2 /* BugsnagConfigurationTests.m */,
008966A42486D43400DC48C2 /* BugsnagDeviceTest.m */,
008966CB2486D43600DC48C2 /* BugsnagEnabledBreadcrumbTest.m */,
Expand Down Expand Up @@ -2619,7 +2619,7 @@
008967332486D43700DC48C2 /* BugsnagClientTests.m in Sources */,
004E353F2487B3BD007FBAE4 /* BugsnagSwiftConfigurationTests.swift in Sources */,
008967542486D43700DC48C2 /* BugsnagOnCrashTest.m in Sources */,
008967152486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */,
008967152486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */,
01E8765E256684E700F4B70A /* URLSessionMock.m in Sources */,
008967AB2486D43700DC48C2 /* KSMach_Tests.m in Sources */,
0089672A2486D43700DC48C2 /* BugsnagStacktraceTest.m in Sources */,
Expand Down Expand Up @@ -2754,7 +2754,7 @@
004E353D2487B3B8007FBAE4 /* BugsnagSwiftTests.swift in Sources */,
008967192486D43700DC48C2 /* BugsnagErrorTest.m in Sources */,
016875C7258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */,
008967162486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */,
008967162486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */,
008967582486D43700DC48C2 /* BugsnagClientMirrorTest.m in Sources */,
0089676A2486D43700DC48C2 /* BugsnagSessionTrackerTest.m in Sources */,
008967792486D43700DC48C2 /* KSMachHeader_Tests.m in Sources */,
Expand Down Expand Up @@ -2913,7 +2913,7 @@
008967472486D43700DC48C2 /* BugsnagTests.m in Sources */,
008967A72486D43700DC48C2 /* KSString_Tests.m in Sources */,
0089671A2486D43700DC48C2 /* BugsnagErrorTest.m in Sources */,
008967172486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */,
008967172486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */,
008967532486D43700DC48C2 /* BSGOutOfMemoryTests.m in Sources */,
008967592486D43700DC48C2 /* BugsnagClientMirrorTest.m in Sources */,
0089676B2486D43700DC48C2 /* BugsnagSessionTrackerTest.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ NS_ASSUME_NONNULL_BEGIN

#pragma mark Methods

+ (void)addRuntimeVersionInfo:(NSString *)info withKey:(NSString *)key; // Used in BugsnagReactNative

+ (void)notifyInternal:(BugsnagEvent *)event block:(BOOL (^)(BugsnagEvent *))block; // Used in BugsnagReactNative

+ (void)purge;

+ (void)removeOnBreadcrumbBlock:(BugsnagOnBreadcrumbBlock)block;

+ (void)updateCodeBundleId:(NSString *)codeBundleId; // Used in BugsnagReactNative

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <Foundation/Foundation.h>

#import "BSG_KSCrashReportWriter.h"
#import "BSG_KSCrashType.h"
#import "BugsnagConfiguration.h"
#import "BugsnagErrorReportApiClient.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#define SYSTEMSTATE_APP_WAS_TERMINATED @"wasTerminated"
#define SYSTEMSTATE_APP_IS_ACTIVE @"isActive"
#define SYSTEMSTATE_APP_IS_IN_FOREGROUND @"inForeground"
#define SYSTEMSTATE_APP_LAST_LOW_MEMORY_WARNING @"lowMemory"
#define SYSTEMSTATE_APP_VERSION @"version"
#define SYSTEMSTATE_APP_BUNDLE_VERSION @"bundleVersion"
#define SYSTEMSTATE_APP_DEBUGGER_IS_ACTIVE @"debuggerIsActive"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
NSMutableDictionary *app = state[SYSTEMSTATE_KEY_APP];

// KV-store versions of these are authoritative
app[SYSTEMSTATE_APP_LAST_LOW_MEMORY_WARNING] = [kvstore stringForKey:SYSTEMSTATE_APP_LAST_LOW_MEMORY_WARNING defaultValue:@""];
app[SYSTEMSTATE_APP_WAS_TERMINATED] = [kvstore NSBooleanForKey:SYSTEMSTATE_APP_WAS_TERMINATED defaultValue:false];
app[SYSTEMSTATE_APP_IS_ACTIVE] = [kvstore NSBooleanForKey:SYSTEMSTATE_APP_IS_ACTIVE defaultValue:false];
app[SYSTEMSTATE_APP_IS_IN_FOREGROUND] = [kvstore NSBooleanForKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND defaultValue:false];
Expand Down Expand Up @@ -84,7 +83,6 @@ id blankIfNil(id value) {
isActive = appState == UIApplicationStateActive;
#endif

[kvstore deleteKey:SYSTEMSTATE_APP_LAST_LOW_MEMORY_WARNING];
[kvstore deleteKey:SYSTEMSTATE_APP_WAS_TERMINATED];
[kvstore setBoolean:isActive forKey:SYSTEMSTATE_APP_IS_ACTIVE];
[kvstore setBoolean:isInForeground forKey:SYSTEMSTATE_APP_IS_IN_FOREGROUND];
Expand All @@ -110,7 +108,6 @@ id blankIfNil(id value) {
NSMutableDictionary *device = [NSMutableDictionary new];
device[SYSTEMSTATE_DEVICE_BOOT_TIME] = [BSG_RFC3339DateTool stringFromDate:systemInfo[@BSG_KSSystemField_BootTime]];
device[@"id"] = systemInfo[@BSG_KSSystemField_DeviceAppHash];
// device[@"lowMemory"] is initially unset
device[@"osBuild"] = systemInfo[@BSG_KSSystemField_OSVersion];
device[@"osVersion"] = systemInfo[@BSG_KSSystemField_SystemVersion];
device[@"osName"] = systemInfo[@BSG_KSSystemField_SystemName];
Expand Down Expand Up @@ -210,12 +207,6 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)config {
[strongSelf.kvStore setBoolean:NO forKey:SYSTEMSTATE_APP_IS_ACTIVE];
[strongSelf setValue:@NO forAppKey:SYSTEMSTATE_APP_IS_ACTIVE];
}];
[center addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
__strong __typeof__(self) strongSelf = weakSelf;
NSString *date = [BSG_RFC3339DateTool stringFromDate:[NSDate date]];
[strongSelf.kvStore setString:date forKey:SYSTEMSTATE_APP_LAST_LOW_MEMORY_WARNING];
[strongSelf setValue:date forAppKey:SYSTEMSTATE_APP_LAST_LOW_MEMORY_WARNING];
}];
#endif
[center addObserver:self selector:@selector(sessionUpdateNotification:) name:BSGSessionUpdateNotification object:nil];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#import <Bugsnag/BugsnagClient.h>

#import "BugsnagMetadata+Private.h" // For BugsnagObserverBlock

@class BugsnagBreadcrumbs;
@class BugsnagConfiguration;
@class BugsnagCrashSentry;
Expand Down Expand Up @@ -76,6 +78,8 @@ NS_ASSUME_NONNULL_BEGIN

- (void)addBreadcrumbWithBlock:(void (^)(BugsnagBreadcrumb *))block;

- (void)addObserverWithBlock:(BugsnagObserverBlock)block; // Used in BugsnagReactNative

- (void)addRuntimeVersionInfo:(NSString *)info withKey:(NSString *)key;

- (NSDictionary *)collectAppWithState; // Used in BugsnagReactNative
Expand All @@ -88,6 +92,8 @@ NS_ASSUME_NONNULL_BEGIN

- (void)notifyInternal:(BugsnagEvent *)event block:(BugsnagOnErrorBlock)block;

- (void)removeObserverWithBlock:(BugsnagObserverBlock)block; // Used in BugsnagReactNative

- (BOOL)shouldReportOOM;

- (void)start;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -741,20 +741,22 @@ - (BOOL)appendNSErrorInfo:(NSError *)error
block:(BugsnagOnErrorBlock)block
event:(BugsnagEvent *)event {
event.originalError = error;
[event addMetadata:@{
@"code" : @(error.code),
@"domain" : error.domain,
BSGKeyReason : error.localizedFailureReason ?: @""
}
toSection:@"nserror"];

NSMutableDictionary *metadata = [NSMutableDictionary dictionary];
metadata[@"code"] = @(error.code);
metadata[@"domain"] = error.domain;
metadata[BSGKeyReason] = error.localizedFailureReason;
metadata[@"userInfo"] = BSGJSONDictionary(error.userInfo);
[event addMetadata:metadata toSection:@"nserror"];

if (event.context == nil) { // set context as error domain
event.context = [NSString stringWithFormat:@"%@ (%ld)", error.domain, (long)error.code];
}

if (block) {
return block(event);
}
return true;
return YES;
}

- (void)notify:(NSException *_Nonnull)exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@
* @param destination a dictionary or nil
*/
NSDictionary *BSGDictMerge(NSDictionary *source, NSDictionary *destination);

/// Returns a representation of the dictionary that contains only valid JSON.
/// Any dictionary keys that are not strings will be ignored.
/// Any values that are not valid JSON will be replaced by a string description.
NSDictionary * BSGJSONDictionary(NSDictionary *dictionary);
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#import "BugsnagCollections.h"

#import "BSGJSONSerialization.h"

NSDictionary *BSGDictMerge(NSDictionary *source, NSDictionary *destination) {
if ([destination count] == 0) {
return source;
Expand All @@ -41,3 +43,27 @@
}
return dict;
}

NSDictionary * BSGJSONDictionary(NSDictionary *dictionary) {
if (!dictionary) {
return nil;
}
if ([BSGJSONSerialization isValidJSONObject:dictionary]) {
return dictionary;
}
NSMutableDictionary *json = [NSMutableDictionary dictionary];
for (id key in dictionary) {
if (![key isKindOfClass:[NSString class]]) {
continue;
}
const id value = dictionary[key];
if ([BSGJSONSerialization isValidJSONObject:@{key: value}]) {
json[key] = value;
} else if ([value isKindOfClass:[NSDictionary class]]) {
json[key] = BSGJSONDictionary(value);
} else {
json[key] = ((NSObject *)value).description;
}
}
return json;
}
Loading