Send custom iOS native errors with sentry-expo - ios

I want to capture the iOS native errors to Sentry and also capture some custom messages.
I'm using the sentry-expo library but this only captures javascript errors even with the parameter:
deactivateStacktraceMerging: false
I'v been following the official installation guide https://docs.sentry.io/clients/react-native/ but I'm stuck when trying to configure the AppDelegate.m file
#import "AppDelegate.h"
#import "ExpoKit.h"
#import "EXViewController.h"
#import <Fabric/Fabric.h>
#import <Crashlytics/Crashlytics.h>
#if __has_include(<React/RNSentry.h>)
#import <React/RNSentry.h> // This is used for versions of react >= 0.40
#else
#import "RNSentry.h" // This is used for versions of react < 0.40
#endif
#interface AppDelegate ()
#property (nonatomic, strong) EXViewController *rootViewController;
#end
#implementation AppDelegate
-(EventsObserver*)getEventsObserver
{
return EventsObserver.shared;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Fabric with:#[[Crashlytics class]]];
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor whiteColor];
[[ExpoKit sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
_rootViewController = [ExpoKit sharedInstance].rootViewController;
_window.rootViewController = _rootViewController;
[_window makeKeyAndVisible];
[self getEventsObserver];
[RNSentry installWithRootView:rootView];
return YES;
}
At this point I don't have the rootView object of type RCTRootView. I'm using a EXViewController and the library does not support that type of object to invoke the function installWithRootView. Am I following a wrong path?

Related

Cordova plugin with framework with Appdelegate

I have created a framework with a native sdk that the company I work has for push notifications. I have an Appdelegate inside this framework because there are some files that use it. I have added this framework as a plug in for a Cordova test application but as I see I can use only one of the two AppDelegates that exist now(one in framework and one in cordova app). I am trying to use only the framework's AppDelegate but to do this I must somehow use CDVAppDelegate. The problem is that the app in initialization doesn't run the correct didFinishLaunchingWithOptions function and I can't see the default first page of the cordova app. I have this files inside the plug in:
AppDelegateExtension.m
#import "xxxSDK/AppDelegate.h"
#import "xxxSDK/xxx.h"
#import "MainViewController.h"
#import "MyPlugin.h"
#implementation AppDelegate (MyPlugin)
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
#if (DEBUG == 1)
[xxx launchWithAppUUID:#"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
#else
[xxx launchWithAppUUID:#"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
#endif
[[xxx sharedService].pushManager registerForRemoteNotifications];
[[xxx sharedService].pushManager resetBadge];
MyPlugin.myPlugin.viewController = [[MainViewController alloc] init];
[MyPlugin.myPlugin application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
MyPlugin.h
#import <Cordova/CDVAppDelegate.h>
#interface MyPlugin : CDVAppDelegate
// Public static method
+ (CDVAppDelegate*) myPlugin;
#end
MyPlugin.m:
#import <Foundation/Foundation.h>
#import "MyPlugin.h"
#import "MainViewController.h"
#implementation MyPlugin
// Private static reference
static CDVAppDelegate* myPlugin;
// Public static method
+ (CDVAppDelegate*) myPlugin {
return myPlugin;
}
#end
Inside the framework the AppDelegate.h is this:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#end
I have tried declare MyPlugin as a CDVPlugin too but the problem didnt get solved. Any thoughts?
Because AppDelegateExtension.m is a category of the AppDelegate class it extends the original class rather than implementing a subclass, so any methods you implement in your category which already exist in the main class (i.e. AppDelegate.m auto-generated by Cordova) will be replaced.
So in this case your didFinishLaunchingWithOptions in AppDelegateExtension.m is replacing didFinishLaunchingWithOptions in AppDelegate.m.
TL;DR: You need to swizzle the method to avoid destroying the original method:
#implementation AppDelegate (MyPlugin)
+ (void)load {
Method original = class_getInstanceMethod(self, #selector(application:didFinishLaunchingWithOptions:));
Method swizzled = class_getInstanceMethod(self, #selector(application:swizzledDidFinishLaunchingWithOptions:));
method_exchangeImplementations(original, swizzled);
}
- (BOOL)application:(UIApplication*)application swizzledDidFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
{
#if (DEBUG == 1)
[xxx launchWithAppUUID:#"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
#else
[xxx launchWithAppUUID:#"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
#endif
[[xxx sharedService].pushManager registerForRemoteNotifications];
[[xxx sharedService].pushManager resetBadge];
MyPlugin.myPlugin.viewController = [[MainViewController alloc] init];
[MyPlugin.myPlugin application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
You can see an example of this in cordova-plugin-firebasex.
Ok, i did this:
#implementation AppDelegate (MyPlugin)
+ (void)load {
Method original = class_getInstanceMethod(self, #selector(application:didFinishLaunchingWithOptions:));
Method swizzled = class_getInstanceMethod(self, #selector(application:swizzledDidFinishLaunchingWithOptions:));
method_exchangeImplementations(original, swizzled);
}
- (BOOL)application:(UIApplication*)application swizzledDidFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
#if (DEBUG == 1)
[Warply launchWithAppUUID:#"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
#else
[Warply launchWithAppUUID:#"1256fbeb638b4426a98e4bacbc5f56f5" launchOptions:launchOptions];
#endif
[[Warply sharedService].pushManager registerForRemoteNotifications];
[[Warply sharedService].pushManager resetBadge];
CDVAppDelegate *appDelegate = [[CDVAppDelegate alloc]init];
[appDelegate application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
CDVAppdelegate's didFinishLaunchingWithOptions is running but I can not see in my device index.html view. My sdk runs properly but the cordova app is not running at all.
I assume that the thing is that AppDelegate : UIResponder can not support what I want to do and I am starting to believe that what I want can not be implemented.

React Native call iOS ViewController

How to call native iOS viewController' code when in RN?
Like use RN to push to a native iOS viewController and then let the native code do the job.
You need to use Export Method .
AppDelegate.h
#import <UIKit/UIKit.h>
#import "RCTBridgeModule.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate,RCTBridgeModule>
#property (nonatomic, strong) UIWindow *window;
#end
AppDelegate.m
#implementation AppDelegate
RCT_EXPORT_MODULE()
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//NO Change Here
}
RCT_EXPORT_METHOD(pushVC:(NSString *)vcName){
Class ctrlClass = NSClassFromString(vcName);
UIViewController *newVc = [[ctrlClass alloc] initWithNibName: vcName bundle: nil];
[[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:newVc animated:YES completion:nil];
}
You can call above response in javascript like this:
import { NativeModules } from 'react-native'
NativeModules.AppDelegate.pushVC('viewControllerNameHere')
But I highly recommend to make with external file to bridge like documentation explain here:
https://facebook.github.io/react-native/docs/native-modules-ios

Adding Google Analytics Linker Error when compiling in Xcode5 SDK 3.03

I would like get GA in my apps. I've tried to do this:
I used this Google Analytics SDK for iOS v3 (Beta)- https://developers.google.com/analytics/devguides/collection/ios/v3/
I've followed all the steps of the documentation.
also already tried Linker errors when trying to install new Google Analytics 3.0 Beta
In my AppDelegate.h
#import <UIKit/UIKit.h>
#import "GAI.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property(nonatomic, strong) id<GAITracker> tracker;
#property (strong, nonatomic) UIWindow *window;
#end
In my AppDelegate.m
#import "AppDelegate.h"
#import "GAI.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[GAI sharedInstance].trackUncaughtExceptions = YES;
// Optional: set Google Analytics dispatch interval to e.g. 20 seconds.
[GAI sharedInstance].dispatchInterval = 20;
// Optional: set Logger to VERBOSE for debug information.
[[[GAI sharedInstance] logger] setLogLevel:kGAILogLevelVerbose];
// Initialize tracker.
id<GAITracker> tracker = [[GAI sharedInstance] trackerWithTrackingId:#"UA-47246605-1"];
[GAI sharedInstance].optOut = YES;
[GAI sharedInstance].trackUncaughtExceptions = YES;
[GAI sharedInstance].dispatchInterval = 0;
return YES;
}
ViewController.h
#import <UIKit/UIKit.h>
#import "GAI.h"
#import "GAITrackedViewController.h"
#interface ViewController : GAITrackedViewController
#end
ViewController.m
#import "ViewController.h"
#import "GAI.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.screenName = #"Home Screen";
}
Link for my project test:https://www.dropbox.com/s/j3ufrv55xym82nc/TesteAnalytics.zip
Google Analytics uses the CoreData.framework, and the linker can't find it. (NSManagedEntity, NSManagedContext, etc are CoreData classes)
Did you add the framework to your project?
I change this and work now.
#import <CoreData/CoreData.h>
#import "AppDelegate.h"
#import "GAI.h"
#implementation AppDelegate
static NSString *const kTrackingId = #"UA-47244310-1";
static NSString *const kAllowTracking = #"allowTracking";
- (void)applicationDidBecomeActive:(UIApplication *)application {
[GAI sharedInstance].optOut = ![[NSUserDefaults standardUserDefaults] boolForKey:kAllowTracking];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *appDefaults = #{kAllowTracking: #(YES)};
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
// User must be able to opt out of tracking
[GAI sharedInstance].optOut =
![[NSUserDefaults standardUserDefaults] boolForKey:kAllowTracking];
// Initialize Google Analytics with a 120-second dispatch interval. There is a
// tradeoff between battery usage and timely dispatch.
[GAI sharedInstance].dispatchInterval = 120;
[GAI sharedInstance].trackUncaughtExceptions = YES;
self.tracker = [[GAI sharedInstance] trackerWithName:#"TesteDelegate"
trackingId:kTrackingId];
return YES;
}

Error: missing property on object 'AppDelegate *'

Teaching myself iOS Programming, and starting by following this book.
I ran into error "Property 'MainViewController' not found on object of type 'AppDelegate *'.
I've double and triple checked that I followed the code correctly, even restarted from scratch. I've scoured StackOverflow and tried a few solutions but none worked and few properly match my issue. Any help?
AppDelegate.m (where the error lies)
#import "AppDelegate.h"
#import "WeatherForecast.h"
#import "MainViewController.h"
#implementation AppDelegate
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
WeatherForecast *forecast = [[WeatherForecast alloc] init];
self.MainViewController.forecast = forecast;
// Override point for customization after application launch.
MainViewController *controller = (MainViewController *)self.window.rootViewController;
controller.managedObjectContext = self.managedObjectContext;
return YES;
}
MainViewController.h
#import "FlipsideViewController.h"
#import "WeatherForecast.h"
#import <CoreData/CoreData.h>
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
- (IBAction)showInfo;
- (IBAction)refreshView:(id) sender;
- (void)updateView;
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) WeatherForecast *forecast;
#end
The problem should be in your second line of application:didFinishLaunchingWithOptions. self.MainViewController is expecting a property in your AppDelegate. Just remove this line and add controller.forecast = forecast; before return YES. At this point you got a reference to your MainViewController and can set the property safely (assuming that MainViewController is set up as the current rootViewController through your Storyboard or XIB).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
WeatherForecast *forecast = [[WeatherForecast alloc] init];
// Override point for customization after application launch.
MainViewController *controller = (MainViewController *)self.window.rootViewController;
controller.managedObjectContext = self.managedObjectContext;
controller.forecast = forecast;
return YES;
}

Changing AppDelegate file of example I want to use in my app

Hi all I'm new in creating app for iOS , so sorry if the question stupid a little .
I'm trying to build app where log in to Facebook and getting friend list is only a part, so I want to use the example providing from Facebook to developers , but it have appDelegate file with some methods like this:
#import "FPAppDelegate.h"
#import "FPViewController.h"
#implementation FPAppDelegate
#synthesize window = _window;
#synthesize rootViewController = _rootViewController;
- (BOOL)application:(UIApplication *)application
.......
return [FBSession.activeSession handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FBFriendPickerViewController class];
........
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
[FBSession.activeSession close];
}
And it have xib file for FPViewController with h and m files, so what the better way to use this example in my app, I understand that I can't use two appDelegate files, and I trying to change FPAppDelegate that is UIResponder to UIViewController class to push it from some place in my app like this:
- (IBAction)loginFacebook:(id)sender
{
NSLog(#"Facebook");
delegateViewController *appDelegate = [[delegateViewController alloc] initWithNibName:nil bundle:NULL];
[self.navigationController pushViewController: appDelegate animated:YES];
}
where delegateViewController is FPAppDelegate of example I changing to:
#import "delegateViewController.h"
#import "AppDelegate.h"
#import "FPViewController.h"
#interface delegateViewController ()
#end
#implementation delegateViewController
#synthesize window2=_window2;
#synthesize rootViewController2=_rootViewController2;
- (BOOL)application:(UIApplication *)application
......
return [FBSession.activeSession handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FBFriendPickerViewController class];
......
self.window2 = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window2.rootViewController = navigationController;
[self.window2 makeKeyAndVisible];
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
........
[FBSession.activeSession close];
}
but it's not working, so, if I need to change also xib file? Or to change appDelegate file of my project? Or existing another way to use this example in my app? I would like you to explain this to me.
You should start by working through the Apple tutorials so you can understand the UIKit framework to start developing an iOS app.
http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOS/chapters/Introduction.html

Resources