Incase, your development language is swift, use the SWIFT documentation for integration.
Finotes framework supports iOS projects with minimum deployment target version 8 or above.
1. Sign Up using the button below.
2. Use "Add App" option in dashboard to link iOS app to Finotes.
You need to add cocoa pods to your project. You can find more information here
Incase, your development language is swift, use the SWIFT documentation for integration.
After integrating cocoa pods, add FinotesCore to your Podfile.
pod 'FinotesCore', '2.5.5'
The –repo-update option should be used the first time pod install is run from terminal.
Then install the same by executing the following command from terminal where your Podfile resides.
Here the —repo-update is added incase your local cocoa pods repository is not up to date.
pod install --repo-update
You can import the FinotesCore to your code using the import statement below.
#import <FinotesCore/Fn.h></FinotesCore>
You need to call the [Fn initialize:application] function in your appDelegate didFinishLaunchingWithOptions:
#import <FinotesCore/Fn.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fn initialize:application];
}
Now that the basic integration of Finotes framework is complete,
Lets make sure that the dashboard and SDK are in sync.
Add
[Fn reportIssueAt:self withDescription:@"iOS TEST Issue" withSeverity:MINOR];
under
[Fn initialize:application withDryRun:NO withVerbose:YES];
#import <FinotesCore/Fn.h>
#import <FinotesCore/Severity.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fn initialize:application withDryRun:NO withVerbose:YES];
//[Fn reportIssueAt:] allows you to raise custom issues.
//Refer Custom Issue section by the end of this documentation for more details.
[Fn reportIssueAt:self withDescription:@"iOS TEST Issue" withSeverity:MINOR];
}
Now run the application in a simulator or real iOS device (with active network connection).
Once the application opens up, open Finotes dash.
The test issue that we raised should be reported.
In-case the issue is not listed, make sure the right app and platform is selected at the top of the dashboard.
If issue is still not synced in Finotes dashboard, Click Here.
Remember to remove the [Fn reportIssueAt]; call, else every time the app is run, an issue will be reported.
Once you are ready to release the application, if you have activated crash reporting using Finotes, you need to back up the dSYM file to symbolicate the crashes as they are reported. Locating dSYM file.
Activity markers are events that occur in an application during runtime. Extending UIViewControllers from ObservableViewController helps Finotes track application life cycle events.
@interface ViewController : UIViewController
@end
@interface ViewController : ObservableViewController
@end
You can set custom activity markers in the project using [Fn setActivityMarkerAt]. These markers will be shown along with the activity trail when an issue is reported.
Markers are displayed in their chronological order.
Only when an issue is raised, the activity markers are sent to the server.
[Fn setActivityMarkerAt:self marker:@"clicked on payment_package_two"];
AppDelegate:finishLaunchingOptions 11:19:24:469 45.79% FREE MEMORY
ViewController:viewDidLoad 11:19:24:708 44.39%
ViewController:viewWillAppear 11:19:27:012 45.19%
ViewController:viewDidAppear 11:19:28:515 44.53%
ViewController:clicked on payment_package_two 11:20:24:235 55.20%
Finotes will be able to notify of any errors in API calls with just a single line.
If you are using NSURLSession with sharedSession then issues in all REST api calls will be reported automatically.
NSURLSession *session = [NSURLSession sharedSession];
Incase you are using AFNetworking, then you need to add the below code in your NSURLSessionConfiguration. The part we are interested is
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration
defaultSessionConfiguration];
configuration.protocolClasses = [Fn getProtocols:[configuration.protocolClasses mutableCopy] ];
If you try to use ‘AFHTTPRequestOperationManager’, your app might crash. ‘AFHTTPRequestOperationManager’ is outdated in AFNetworking 3.x, we suggest you migrate to ‘NSURLSessionConfiguration’. You can find out, how to migrate to ‘NSURLSessionConfiguration’ here.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration
defaultSessionConfiguration];
configuration.protocolClasses = [Fn getProtocols:[configuration.protocolClasses mutableCopy] ];
Incase, you need more clarity on getting notified of network errors, Please initiate a chat with our development team directly using chat widget at the bottom right corner.
We will help you overcome any roadbloacks that you may have.
As Finotes reports API call issues, each issue is tagged with corresponding request response headers, request body and assosiated parameters.
If header fields contain any sensitive data, Finotes provides a global and easy mechanism to mask such header fields using maskHeaders in info.plist file as shown in code snippet.
You may provide 1 or more header keys in the 'maskHeaders' field.
Open info.plist as Source Code, then add the below snippet
<key>MaskHeaders</key>
<array>
<string>Header-Key</string>
<string>Another-Header-Key</string>
</array>
Lets say API calls from the app has header field 'X-Key' which contains the authentication token.
It can be masked by providing the 'X-Key' in the field as shown above, masked header fields are filtered out from the app itelf as is not sent to the Finotes dashboard, if any issues are raised.
The maskHeaders field is case insensitive and is optional.
In-order to catch uncaught exceptions that causes app to force close, use [Fn catchExceptions].
#import <FinotesCore/Fn.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fn initialize:application];
[Fn catchExceptions];
}
You may extend the UIViewController classes from ObservableViewController. This will report any UIViewController level memory issues that may arise in the application.
@interface ViewController : UIViewController
@end
@interface ViewController : ObservableViewController
@end
Any exceptions that may have already been caught using @try{}@catch{} needs to be reported as they might prevent the application from crashing, but at the same time can make app unstable if gone unreported.
@try{
[self fetchUserDetails];
}@catch(NSException *exception){
[Fn reportExceptionAt:self withException:exception
withSeverity:FATAL];
}
You can report custom issues using the [Fn reportIssueAt:] API.
//Payment gateway delegate methods.
-(void) paymentCompleted:(NSString *) userIdentifier forType:(NSInteger) type{
}
-(void) paymentFailed:(NSString *) userIdentifier forReason:(NSString *) reason{
[Fn setActivityMarkerAt:self marker:[NSString stringWithFormat:@"User id %@", userIdentifier]];
[Fn reportIssueAt:self withDescription:
[NSString stringWithFormat:@"Payment failed for %@", reason]
withSeverity:FATAL];
}
In cases where the fail situations can be anticipated, they may be reported using [Fn reportIssueAt].
You may pass a string as parameter to the anticipated issue.
As in custom exceptions, you will be able to make use of activity markers to aid reproducing the issue when reported.
Finotes will report all return value issues, exceptions and execution delays that may arise during function execution using [Fn call].
[self getUserNameFromDb:@"123-sd-12"]
}
-(NSString *) getUserNameFromDb:(NSString *) userId {
NSString *userName = [[User findById:userId] name];
return userName;
}
#import <FinotesCore/Observer.h>
#import <FinotesCore/Fn.h>
[Fn call:@selector(getUserNameFromDb:) target:self withParameters:@"123-sd-12"];
}
-(NSString *) getUserNameFromDb:(NSString *) userId {
NSString *userName = [[User findById:userId] name];
return userName;
}
You can make use of expectedExecutionTime, severity, expectNull fields in Observer parameter of
Incase, we have a function that may take more than 1000 milliseconds(default value) for execution then use this field in Observer to provide an ideal execution time.
Supplying proper values in Observer parameter will help Finotes raise better issue reports.
#import <FinotesCore/Observer.h>
#import <FinotesCore/Fn.h>
Observer *observer = [[Fn observe] expectedExecutionTime:1400];
NSString *userName = [Fn call:@selector(getUserNameFromDb:) target:self
observer:observer withParameters:@"123-sd-12"];
}
-(NSString *) getUserNameFromDb:(NSString *) userId {
NSString *userName = [[User findById:userId] name];
return userName;
}
If function returns an object and return value could be NULL, then set this field to true to prevent Finotes from raising an issue when function returns NULL.
By default field is false, and issue will be raised if function returns NULL.
Sets severity level of issues reported from a function using this field.
All issues raised from a function will have the same severity level, set to it using Observer parameter.
By default severity is MAJOR.
Finotes has the ability to invoke code level functions and report any issues that may arise from it.
Feature tracking allows developers to track a particular feature in iOS app by chaining 2 or more functions invoked by Finotes.
Lets take the example of Chat feature in a typical iOS application.
The function at the time of clicking the send button 'sendChat' and 'onChatSent' success function after the items as been added to the cart needs to be invoked using Finotes.
The Finotes looks for 'onChatSent' function execution after the execution of 'sendChat', if the 'onChatSent' is not executed within in 10000 milliseconds then a corresponding issue will be raised.
#import <FinotesCore/Observer.h>
#import <FinotesCore/Fn.h>
- (void) sendChatClicked:(UITapGestureRecognizer *)recognizer {
// Here function 'onChatSent:' is
// expected to be called in under '10000' milliseconds.
Observer *observer = [[[Fn observe] expectedChainedExecutionTime:10000]
nextFunctionSignature:
@selector(onChatSent:)
inClass:[self class]];
[Fn call:@selector(sendChat:) target:self observer:observer withParameters:chatMessage];
}
- (Boolean) sendChat:(NSString *) message {
if([self isValid:message]){
[self syncMessage:message];
}
return false;
}
- (void) onChatSent:(NSString *)chatMessageId {
[self chatSyncConfirmed:chatMessageId];
}
You can make use of nextFunctionSignature, inClass, expectedChainedExecutionTime fields in Observer parameter to chain 2 or more functions.
Overrides time needed to execute second function after execution of first function.
By default the time between function executions is set to 2000 milliseconds.
Signature of the second function that is to be chained with the current function.
Class where second function is defined that is to be chained with the current function.
You can listen for and access every issue in realtime using the Fn.listenForIssue() API.
You need to add the listener in your AppDelegate class.
[Fn listenForIssues:@selector(issueFound:) atTarget:self];
}
(void) issueFound:(Issue *) issue {
}
You will be provided with an Issue object that contains all the issue properties that are being synced to the server, making the whole process transparent.
This callback is triggered right after an issue occurrence.
During development, you can set the dryRun mode, so that the issues raised will not be sent to the server. Every other feature except the issue sync to server will work as same.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fn initialize:application withDryRun:YES withVerbose:NO];
}
When preparing for production release, you need to unset the DryRun flag.
You can toggle logging using third parameter.
Activating verbose will print all logs in LogCat including error and warning logs.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fn initialize:application withDryRun:NO withVerbose:YES];
}