Skip to content

Commit

Permalink
Merge 7d04382 into e79ead7
Browse files Browse the repository at this point in the history
  • Loading branch information
denrase authored Mar 27, 2023
2 parents e79ead7 + 7d04382 commit 7614270
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## 8.3.3

### Features

- Add `name` and `geo` to User (#2710)

### Fixes

- View hierarchy not sent for crashes (#2781)
Expand Down
12 changes: 12 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,9 @@
8ED2D28026A6581C00CA8329 /* NSURLProtocolSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED2D27F26A6581C00CA8329 /* NSURLProtocolSwizzle.m */; };
8ED3D306264DFE700049393B /* SwiftDescriptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ED3D305264DFE700049393B /* SwiftDescriptorTests.swift */; };
8EE017A126704CD500470616 /* SentryUIViewControllerPerformanceTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EA1ED0E2669152F00E62B98 /* SentryUIViewControllerPerformanceTrackerTests.swift */; };
9286059529A5096600F96038 /* SentryGeo.h in Headers */ = {isa = PBXBuildFile; fileRef = 9286059429A5096600F96038 /* SentryGeo.h */; settings = {ATTRIBUTES = (Public, ); }; };
9286059729A5098900F96038 /* SentryGeo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9286059629A5098900F96038 /* SentryGeo.m */; };
9286059929A50BAB00F96038 /* SentryGeoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9286059829A50BAA00F96038 /* SentryGeoTests.swift */; };
A2475E1325FB63A3007D9080 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = A2475E1225FB63A3007D9080 /* fishhook.h */; };
A2475E1725FB63AF007D9080 /* SentryHook.h in Headers */ = {isa = PBXBuildFile; fileRef = A2475E1625FB63AF007D9080 /* SentryHook.h */; };
A2475E1B25FB63D7007D9080 /* SentryHook.c in Sources */ = {isa = PBXBuildFile; fileRef = A2475E1A25FB63D7007D9080 /* SentryHook.c */; };
Expand Down Expand Up @@ -1589,6 +1592,9 @@
8ED2D27E26A6581C00CA8329 /* NSURLProtocolSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSURLProtocolSwizzle.h; sourceTree = "<group>"; };
8ED2D27F26A6581C00CA8329 /* NSURLProtocolSwizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSURLProtocolSwizzle.m; sourceTree = "<group>"; };
8ED3D305264DFE700049393B /* SwiftDescriptorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftDescriptorTests.swift; sourceTree = "<group>"; };
9286059429A5096600F96038 /* SentryGeo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryGeo.h; path = Public/SentryGeo.h; sourceTree = "<group>"; };
9286059629A5098900F96038 /* SentryGeo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryGeo.m; sourceTree = "<group>"; };
9286059829A50BAA00F96038 /* SentryGeoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryGeoTests.swift; sourceTree = "<group>"; };
A2475E1225FB63A3007D9080 /* fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fishhook.h; sourceTree = "<group>"; };
A2475E1625FB63AF007D9080 /* SentryHook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryHook.h; sourceTree = "<group>"; };
A2475E1A25FB63D7007D9080 /* SentryHook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryHook.c; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1836,6 +1842,8 @@
639FCF9B1EBC7F9500778193 /* SentryThread.m */,
639FCFAA1EBC811400778193 /* SentryUser.h */,
639FCFAB1EBC811400778193 /* SentryUser.m */,
9286059429A5096600F96038 /* SentryGeo.h */,
9286059629A5098900F96038 /* SentryGeo.m */,
63B818F71EC34639002FDF4C /* SentryDebugMeta.h */,
63B818F81EC34639002FDF4C /* SentryDebugMeta.m */,
6360850B1ED2AFE100E8599E /* SentryBreadcrumb.h */,
Expand Down Expand Up @@ -2507,6 +2515,7 @@
7B6D98E824C6D336005502FA /* SentrySdkInfo+Equality.m */,
7B82D54824E2A2D400EE670F /* SentryIdTests.swift */,
7B04A9AA24EA5F8D00E710B1 /* SentryUserTests.swift */,
9286059829A50BAA00F96038 /* SentryGeoTests.swift */,
7BB42EEF24F3B7B700D7B39A /* SentrySession+Equality.h */,
7BB42EF024F3B7B700D7B39A /* SentrySession+Equality.m */,
7B0A5451252311CE00A71716 /* SentryBreadcrumbTests.swift */,
Expand Down Expand Up @@ -3519,6 +3528,7 @@
63FE714F20DA4C1100CDBAE8 /* NSError+SentrySimpleConstructor.h in Headers */,
7BC5B6FA290BCDE500D99477 /* SentryHttpStatusCodeRange+Private.h in Headers */,
7B04A9AF24EAC02C00E710B1 /* SentryRetryAfterHeaderParser.h in Headers */,
9286059529A5096600F96038 /* SentryGeo.h in Headers */,
7DC83100239826280043DD9A /* SentryIntegrationProtocol.h in Headers */,
7B98D7BC25FB607300C5A389 /* SentryWatchdogTerminationTracker.h in Headers */,
7BA61CB9247BC57B00C130A8 /* SentryCrashDefaultBinaryImageProvider.h in Headers */,
Expand Down Expand Up @@ -3974,6 +3984,7 @@
7B98D7CF25FB650F00C5A389 /* SentryWatchdogTerminationTrackingIntegration.m in Sources */,
8E5D38DD261D4A3E000D363D /* SentryPerformanceTrackingIntegration.m in Sources */,
7B4E23C2251A2C2B00060D68 /* SentrySessionCrashedHandler.m in Sources */,
9286059729A5098900F96038 /* SentryGeo.m in Sources */,
7B42C48227E08F4B009B58C2 /* SentryDependencyContainer.m in Sources */,
7BA61E9225F21AF80008CAA2 /* SentryLogOutput.m in Sources */,
639FCFAD1EBC811400778193 /* SentryUser.m in Sources */,
Expand Down Expand Up @@ -4076,6 +4087,7 @@
0A5370A128A3EC2400B2DCDE /* SentryViewHierarchyTests.swift in Sources */,
D8FFE50C2703DBB400607131 /* SwizzlingCallTests.swift in Sources */,
7BFAA6E7297AA16A00E7E02E /* SentryCrashMonitor_CppException_Tests.mm in Sources */,
9286059929A50BAB00F96038 /* SentryGeoTests.swift in Sources */,
D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */,
A8AFFCD22907DA7600967CD7 /* SentryHttpStatusCodeRangeTests.swift in Sources */,
7BE2C7F8257000A4003B66C7 /* SentryTestIntegration.m in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Sources/Sentry/Public/Sentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ FOUNDATION_EXPORT const unsigned char SentryVersionString[];
#import "SentryEvent.h"
#import "SentryException.h"
#import "SentryFrame.h"
#import "SentryGeo.h"
#import "SentryHttpStatusCodeRange.h"
#import "SentryHub.h"
#import "SentryId.h"
Expand Down
2 changes: 1 addition & 1 deletion Sources/Sentry/Public/SentryDebugMeta.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ NS_SWIFT_NAME(DebugMeta)
/**
* Name of the image. Use @c codeFile when using "macho" as the @c type .
*/
@property (nonatomic, copy) NSString *_Nullable name;
@property (nullable, nonatomic, copy) NSString *name;

/**
* The size of the image in virtual memory. If missing, Sentry will assume that the image spans up
Expand Down
43 changes: 43 additions & 0 deletions Sources/Sentry/Public/SentryGeo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#import "SentryDefines.h"
#import "SentrySerializable.h"
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/// Approximate geographical location of the end user or device.
///
/// Example of serialized data:
/// {
/// "geo": {
/// "country_code": "US",
/// "city": "Ashburn",
/// "region": "San Francisco"
/// }
/// }
NS_SWIFT_NAME(Geo)
@interface SentryGeo : NSObject <SentrySerializable, NSCopying>

/**
* Optional: Human readable city name.
*/
@property (nullable, atomic, copy) NSString *city;

/**
* Optional: Two-letter country code (ISO 3166-1 alpha-2).
*/
@property (nullable, atomic, copy) NSString *countryCode;

/**
* Optional: Human readable region name or code.
*/
@property (nullable, atomic, copy) NSString *region;

- (BOOL)isEqual:(id _Nullable)other;

- (BOOL)isEqualToGeo:(SentryGeo *)geo;

- (NSUInteger)hash;

@end

NS_ASSUME_NONNULL_END
13 changes: 13 additions & 0 deletions Sources/Sentry/Public/SentryUser.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#import "SentryDefines.h"
#import "SentryGeo.h"
#import "SentrySerializable.h"

NS_ASSUME_NONNULL_BEGIN

@class SentryGeo;

NS_SWIFT_NAME(User)
@interface SentryUser : NSObject <SentrySerializable, NSCopying>

Expand Down Expand Up @@ -31,6 +34,16 @@ NS_SWIFT_NAME(User)
*/
@property (atomic, copy) NSString *_Nullable segment;

/**
* Optional: Human readable name
*/
@property (atomic, copy) NSString *_Nullable name;

/**
* Optional: Geo location of user
*/
@property (nullable, nonatomic, strong) SentryGeo *geo;

/**
* Optional: Additional data
*/
Expand Down
84 changes: 84 additions & 0 deletions Sources/Sentry/SentryGeo.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#import "SentryGeo.h"

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@implementation SentryGeo

- (id)copyWithZone:(nullable NSZone *)zone
{
SentryGeo *copy = [[[self class] allocWithZone:zone] init];

if (copy != nil) {
copy.city = self.city;
copy.countryCode = self.countryCode;
copy.region = self.region;
}

return copy;
}

- (NSDictionary<NSString *, id> *)serialize
{
return @{
@"city" : self.city,
@"country_code" : self.countryCode,
@"region" : self.region
};
}

- (BOOL)isEqual:(id _Nullable)other
{
if (other == self) {
return YES;
}
if (!other || ![[other class] isEqual:[self class]]) {
return NO;
}

return [self isEqualToGeo:other];
}

- (BOOL)isEqualToGeo:(SentryGeo *)geo
{
if (self == geo) {
return YES;
}
if (geo == nil) {
return NO;
}

NSString *otherCity = geo.city;
if (self.city != otherCity && ![self.city isEqualToString:otherCity]) {
return NO;
}

NSString *otherCountryCode = geo.countryCode;
if (self.countryCode != otherCountryCode
&& ![self.countryCode isEqualToString:otherCountryCode]) {
return NO;
}

NSString *otherRegion = geo.region;
if (self.region != otherRegion && ![self.region isEqualToString:otherRegion]) {
return NO;
}

return YES;
}

- (NSUInteger)hash
{
NSUInteger hash = 17;

hash = hash * 23 + [self.city hash];
hash = hash * 23 + [self.countryCode hash];
hash = hash * 23 + [self.region hash];

return hash;
}

@end

NS_ASSUME_NONNULL_END
16 changes: 16 additions & 0 deletions Sources/Sentry/SentryUser.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ - (id)copyWithZone:(nullable NSZone *)zone
copy.username = self.username;
copy.ipAddress = self.ipAddress;
copy.segment = self.segment;
copy.name = self.name;
copy.geo = self.geo.copy;
copy.data = self.data.copy;
}

Expand All @@ -44,6 +46,8 @@ - (id)copyWithZone:(nullable NSZone *)zone
[serializedData setValue:self.username forKey:@"username"];
[serializedData setValue:self.ipAddress forKey:@"ip_address"];
[serializedData setValue:self.segment forKey:@"segment"];
[serializedData setValue:self.name forKey:@"name"];
[serializedData setValue:[self.geo serialize] forKey:@"geo"];
[serializedData setValue:[self.data sentry_sanitize] forKey:@"data"];

return serializedData;
Expand Down Expand Up @@ -96,6 +100,16 @@ - (BOOL)isEqualToUser:(SentryUser *)user
return NO;
}

NSString *otherName = user.name;
if (self.name != otherName && ![self.name isEqualToString:otherName]) {
return NO;
}

SentryGeo *otherGeo = user.geo;
if (self.geo != otherGeo && ![self.geo isEqualToGeo:otherGeo]) {
return NO;
}

NSDictionary<NSString *, id> *otherUserData = user.data;
if (self.data != otherUserData && ![self.data isEqualToDictionary:otherUserData]) {
return NO;
Expand All @@ -113,6 +127,8 @@ - (NSUInteger)hash
hash = hash * 23 + [self.username hash];
hash = hash * 23 + [self.ipAddress hash];
hash = hash * 23 + [self.segment hash];
hash = hash * 23 + [self.name hash];
hash = hash * 23 + [self.geo hash];
hash = hash * 23 + [self.data hash];

return hash;
Expand Down
62 changes: 62 additions & 0 deletions Tests/SentryTests/Protocol/SentryGeoTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import XCTest

class SentryGeoTests: XCTestCase {
func testSerializationWithAllProperties() {
let geo = TestData.geo.copy() as! Geo
let actual = geo.serialize()

// Changing the original doesn't modify the serialized
geo.city = ""
geo.countryCode = ""
geo.region = ""

XCTAssertEqual(TestData.geo.city, actual["city"] as? String)
XCTAssertEqual(TestData.geo.countryCode, actual["country_code"] as? String)
XCTAssertEqual(TestData.geo.region, actual["region"] as? String)
}

func testHash() {
XCTAssertEqual(TestData.geo.hash(), TestData.geo.hash())

let geo2 = TestData.geo
geo2.city = "Berlin"
XCTAssertNotEqual(TestData.geo.hash(), geo2.hash())
}

func testIsEqualToSelf() {
XCTAssertEqual(TestData.geo, TestData.geo)
XCTAssertTrue(TestData.geo.isEqual(to: TestData.geo))
}

func testIsNotEqualToOtherClass() {
XCTAssertFalse(TestData.geo.isEqual(1))
}

func testIsEqualToCopy() {
XCTAssertEqual(TestData.geo, TestData.geo.copy() as! Geo)
}

func testNotIsEqual() {
testIsNotEqual { geo in geo.city = "" }
testIsNotEqual { geo in geo.countryCode = "" }
testIsNotEqual { geo in geo.region = "" }
}

func testIsNotEqual(block: (Geo) -> Void ) {
let geo = TestData.geo.copy() as! Geo
block(geo)
XCTAssertNotEqual(TestData.geo, geo)
}

func testCopyWithZone_CopiesDeepCopy() {
let geo = TestData.geo
let copiedGeo = geo.copy() as! Geo

// Modifying the original does not change the copy
geo.city = ""
geo.countryCode = ""
geo.region = ""

XCTAssertEqual(TestData.geo, copiedGeo)
}
}
Loading

0 comments on commit 7614270

Please sign in to comment.