diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cab2f4..3d9621e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.5.0 +- The API endpoint can now be configured through the Raygun client +- Fix: A bad access exception when logging response codes from the Raygun API + ## 1.4.2 - Updated crash report property name for the stack trace - Additional guards against the provider generating exceptions diff --git a/Sources/Raygun/RaygunClient.h b/Sources/Raygun/RaygunClient.h index 4f8c12b..d70c5fe 100644 --- a/Sources/Raygun/RaygunClient.h +++ b/Sources/Raygun/RaygunClient.h @@ -44,6 +44,10 @@ typedef BOOL (^RaygunBeforeSendMessage)(RaygunMessage *message); @property (nullable, nonatomic, copy) NSString *applicationVersion; +@property (nullable, nonatomic, copy) NSString *crashReportingApiEndpoint; + +@property (nullable, nonatomic, copy) NSString *realUserMonitoringApiEndpoint; + @property (nullable, nonatomic, strong) NSArray *tags; @property (nullable, nonatomic, strong) NSDictionary *customData; diff --git a/Sources/Raygun/RaygunClient.m b/Sources/Raygun/RaygunClient.m index 46db176..ffa38b3 100644 --- a/Sources/Raygun/RaygunClient.m +++ b/Sources/Raygun/RaygunClient.m @@ -57,6 +57,7 @@ @implementation RaygunClient static RaygunLoggingLevel sharedLogLevel = RaygunLoggingLevelWarning; @synthesize userInformation = _userInformation; +@synthesize crashReportingApiEndpoint = _crashReportingApiEndpoint; // ============================================================================ #pragma mark - Getters & Setters - @@ -80,6 +81,27 @@ - (void)setApplicationVersion:(nullable NSString *)applicationVersion { [self updateCrashReportUserInformation]; } +- (void)setCrashReportingApiEndpoint:(nullable NSString *)crashReportingApiEndpoint { + _crashReportingApiEndpoint = crashReportingApiEndpoint; +} + +- (nullable NSString*)crashReportingApiEndpoint { + if (_crashReportingApiEndpoint != nil) + { + return _crashReportingApiEndpoint; + } + + return kDefaultApiEndPointForCR; +} + +- (void)setRealUserMonitoringApiEndpoint:(nullable NSString *)realUserMonitoringApiEndpoint { + [RaygunRealUserMonitoring sharedInstance].realUserMonitoringApiEndpoint = realUserMonitoringApiEndpoint; +} + +- (nullable NSString*)realUserMonitoringApiEndpoint { + return [RaygunRealUserMonitoring sharedInstance].realUserMonitoringApiEndpoint; +} + - (void)setTags:(nullable NSArray *)tags { _tags = tags; [self updateCrashReportUserInformation]; @@ -356,7 +378,7 @@ - (void)sendCrashData:(NSData *)crashData [RaygunLogger logDebug:@"--------------------------------------------"]; } - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kApiEndPointForCR]]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self crashReportingApiEndpoint]]]; request.HTTPMethod = @"POST"; [request setValue:sharedApiKey forHTTPHeaderField:@"X-ApiKey"]; diff --git a/Sources/Raygun/RaygunDefines.h b/Sources/Raygun/RaygunDefines.h index 5eacadc..3f4720a 100644 --- a/Sources/Raygun/RaygunDefines.h +++ b/Sources/Raygun/RaygunDefines.h @@ -41,16 +41,25 @@ #define RAYGUN_CAN_USE_UIKIT 0 #endif -static NSString *_Nonnull const kRaygunClientVersion = @"1.4.2"; +static NSString *_Nonnull const kRaygunClientVersion = @"1.5.0"; static NSString *_Nonnull const kRaygunIdentifierUserDefaultsKey = @"com.raygun.identifier"; static NSString *_Nonnull const kRaygunSessionLastSeenDefaultsKey = @"com.raygun.session.lastseen"; -static NSString *_Nonnull const kApiEndPointForCR = @"https://api.raygun.com/entries"; -static NSString *_Nonnull const kApiEndPointForRUM = @"https://api.raygun.com/events"; +static NSString *_Nonnull const kDefaultApiEndPointForCR = @"https://api.raygun.com/entries"; +static NSString *_Nonnull const kDefaultApiEndPointForRUM = @"https://api.raygun.com/events"; static NSString *_Nonnull const kValueNotKnown = @"Unknown"; +/* +* Full text descriptions of the RaygunResponseStatusCode values. +*/ +static NSString *_Nonnull const kStatusCodeDescriptionAccepted = @"Request succeeded"; +static NSString *_Nonnull const kStatusCodeDescriptionBadMessage = @"Bad message - could not parse the provided JSON. Check all fields are present, especially both occurredOn (ISO 8601 DateTime) and details { } at the top level"; +static NSString *_Nonnull const kStatusCodeDescriptionInvalidApiKey = @"Invalid API Key - The value specified in the header X-ApiKey did not match with an application in Raygun"; +static NSString *_Nonnull const kStatusCodeDescriptionLargePayload = @"Request entity too large - The maximum size of a JSON payload is 128KB"; +static NSString *_Nonnull const kStatusCodeDescriptionRateLimited = @"Too Many Requests - Plan limit exceeded for month or plan expired"; + static double const kSessionExpiryPeriodInSeconds = 30.0 * 60.0; // 30 minutes static NSInteger const kMaxCrashReportsOnDeviceUpperLimit = 64; static NSInteger const kMaxRecordedBreadcrumbs = 32; diff --git a/Sources/Raygun/RaygunLogger.m b/Sources/Raygun/RaygunLogger.m index e76421e..a38ab5f 100644 --- a/Sources/Raygun/RaygunLogger.m +++ b/Sources/Raygun/RaygunLogger.m @@ -74,39 +74,37 @@ + (void)logDebug:(NSString *)message, ... { + (void)logResponseStatusCode:(NSInteger)statusCode { @try { - NSString *message = [self ResponseStatusCodeMessage:statusCode]; - - switch ((RaygunResponseStatusCode)statusCode) { - case RaygunResponseStatusCodeAccepted: { - [self logDebug:message]; - } break; - - case RaygunResponseStatusCodeBadMessage: // fall through - case RaygunResponseStatusCodeInvalidApiKey: // fall through - case RaygunResponseStatusCodeLargePayload: // fall through - case RaygunResponseStatusCodeRateLimited: { - [self logError:message]; - } break; - - default: [self logDebug:message]; break; - } + switch ((RaygunResponseStatusCode)statusCode) { + case RaygunResponseStatusCodeAccepted: + [self logDebug:kStatusCodeDescriptionAccepted]; + break; + + case RaygunResponseStatusCodeBadMessage: + [self logError:kStatusCodeDescriptionBadMessage]; + break; + + case RaygunResponseStatusCodeInvalidApiKey: + [self logError:kStatusCodeDescriptionInvalidApiKey]; + break; + + case RaygunResponseStatusCodeLargePayload: + [self logError:kStatusCodeDescriptionLargePayload]; + break; + + case RaygunResponseStatusCodeRateLimited: + [self logError:kStatusCodeDescriptionRateLimited]; + break; + + default: + [self logDebug:[NSString stringWithFormat:@"Response status code: %ld", (long)statusCode]]; + break; + } } @catch (NSException *exception) { // Ignore } } -+ (NSString * _Nonnull)ResponseStatusCodeMessage:(NSInteger)statusCode { - switch ((RaygunResponseStatusCode)statusCode) { - case RaygunResponseStatusCodeAccepted: return @"Request succeeded"; break; - case RaygunResponseStatusCodeBadMessage: return @"Bad message - could not parse the provided JSON. Check all fields are present, especially both occurredOn (ISO 8601 DateTime) and details { } at the top level"; break; - case RaygunResponseStatusCodeInvalidApiKey: return @"Invalid API Key - The value specified in the header X-ApiKey did not match with an application in Raygun"; break; - case RaygunResponseStatusCodeLargePayload: return @"Request entity too large - The maximum size of a JSON payload is 128KB"; break; - case RaygunResponseStatusCodeRateLimited: return @"Too Many Requests - Plan limit exceeded for month or plan expired"; break; - default: [NSString stringWithFormat:@"Response status code: %ld",(long)statusCode]; break; - } -} - + (void)log:(NSString *)message withLevel:(RaygunLoggingLevel)level { if (RaygunClient.logLevel >= level) { NSLog(@"Raygun - %@:: %@", RaygunLoggingLevelNames[level], message); diff --git a/Sources/Raygun/RaygunRealUserMonitoring.h b/Sources/Raygun/RaygunRealUserMonitoring.h index 4aa14b0..fee02e9 100644 --- a/Sources/Raygun/RaygunRealUserMonitoring.h +++ b/Sources/Raygun/RaygunRealUserMonitoring.h @@ -30,11 +30,14 @@ @class RaygunUserInformation; +NS_ASSUME_NONNULL_BEGIN + @interface RaygunRealUserMonitoring : NSObject @property (nonatomic) bool enabled; @property (nonatomic, readonly, copy) NSDictionary *viewEventTimers; -@property (nonatomic, readonly, copy) NSSet *ignoredViews; +@property (nonatomic, readonly, copy) NSSet * ignoredViews; +@property (nullable, nonatomic, copy) NSString *realUserMonitoringApiEndpoint; + (instancetype)sharedInstance; @@ -61,3 +64,5 @@ - (NSNumber *)viewEventStartTimeForKey:(NSString *)key; @end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Raygun/RaygunRealUserMonitoring.m b/Sources/Raygun/RaygunRealUserMonitoring.m index 7593cb0..2d661a8 100644 --- a/Sources/Raygun/RaygunRealUserMonitoring.m +++ b/Sources/Raygun/RaygunRealUserMonitoring.m @@ -61,6 +61,10 @@ @implementation RaygunRealUserMonitoring static RaygunRealUserMonitoring *sharedInstance = nil; +@synthesize realUserMonitoringApiEndpoint = _realUserMonitoringApiEndpoint; + +#pragma mark - Getters & Setters - + + (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -69,8 +73,6 @@ + (instancetype)sharedInstance { return sharedInstance; } -#pragma mark - Getters & Setters - - - (NSDictionary *)viewEventTimers { return [[NSDictionary alloc] initWithDictionary:_mutableViewTimers]; } @@ -79,6 +81,19 @@ - (NSSet *)ignoredViews { return [NSSet setWithSet:_mutableIgnoredViews]; } +- (nullable NSString*)realUserMonitoringApiEndpoint { + if (_realUserMonitoringApiEndpoint != nil) + { + return _realUserMonitoringApiEndpoint; + } + + return kDefaultApiEndPointForRUM; +} + +- (void)setRealUserMonitoringApiEndpoint:(nullable NSString *)realUserMonitoringApiEndpoint { + _realUserMonitoringApiEndpoint = realUserMonitoringApiEndpoint; +} + #pragma mark - Initialising Methods - - (id)init { @@ -336,7 +351,7 @@ - (void)sendData:(NSData *)data completionHandler:(void (^)(NSData *, NSURLRespo [RaygunLogger logDebug:@"--------------------------------------------"]; } - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kApiEndPointForRUM]]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self realUserMonitoringApiEndpoint]]]; request.HTTPMethod = @"POST"; [request setValue:RaygunClient.apiKey forHTTPHeaderField:@"X-ApiKey"]; diff --git a/raygun4apple.podspec b/raygun4apple.podspec index 79885b6..bce68d1 100644 --- a/raygun4apple.podspec +++ b/raygun4apple.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'raygun4apple' - s.version = '1.4.2' + s.version = '1.5.0' s.summary = 'Raygun client for Apple platforms' s.homepage = 'https://raygun.com' s.authors = { 'Raygun' => 'hello@raygun.com' } diff --git a/raygun4apple.xcodeproj/project.pbxproj b/raygun4apple.xcodeproj/project.pbxproj index dc10732..c98a93e 100644 --- a/raygun4apple.xcodeproj/project.pbxproj +++ b/raygun4apple.xcodeproj/project.pbxproj @@ -2121,7 +2121,7 @@ isa = XCBuildConfiguration; buildSettings = { BITCODE_GENERATION_MODE = marker; - CURRENT_PROJECT_VERSION = 1.4.2; + CURRENT_PROJECT_VERSION = 1.5.0; GCC_PREPROCESSOR_DEFINITIONS = "Raygun_KSLogger_Level=Raygun_KSLogger_Level_None"; OTHER_CFLAGS = "-fembed-bitcode-marker"; SDKROOT = iphoneos; @@ -2132,7 +2132,7 @@ isa = XCBuildConfiguration; buildSettings = { BITCODE_GENERATION_MODE = bitcode; - CURRENT_PROJECT_VERSION = 1.4.2; + CURRENT_PROJECT_VERSION = 1.5.0; GCC_PREPROCESSOR_DEFINITIONS = "Raygun_KSLogger_Level=Raygun_KSLogger_Level_None"; OTHER_CFLAGS = "-fembed-bitcode"; SDKROOT = iphoneos;