Using a function in NSSetUncaughtExceptionHandler - objective-c

I want to reference some state in a NSSetUncaughtExceptionHandler, and so don't want to pass in a function but a method instead. But how?? The state I need to reference is a callback from a react native app. So far i have:
#import "RNUncaughtExceptionReporter.h"
#implementation RNUncaughtExceptionReporter
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(listen:(RCTResponseSenderBlock)listener)
{
callback = listener;
NSSetUncaughtExceptionHandler(/* what goes here? */);
}
- (void) unhandledExceptionHandler(NSException *exception) {
callback(#[#"something went wrong..."]);// todo: send the detail of the exception
}
#end

try this !
NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler);
void UncaughtExceptionHandler(NSException* exception)
{
/* do anything u want with the exception */
}

Related

Bind Method With Delegate

I'm creating a binding library to bind native Objective-C framework.
I have the following delegate which I need to add it's declaration to ApiDefinition file and then I need to implement it using my Xamarin.iOS app:
- (void)Initialize:(id <MMSDKDelegate> _Nullable)pDelegate;
MMSDKDelegate:
#protocol MMSDKDelegate <IMMDelegate>
- (void)Started;
#end
IMMDelegate:
#protocol IMMDelegate
- (void)Inserted;
- (void)Removed;
- (void)ReaderConnected;
- (void)ReaderRemoved;
#end
I need the required definition in ApiDefinition file and I need a sample code to call this method from my Xamarin.iOS app.
Update
The Framework I'm dealing with is communicating with card reader device attached with iPhone to read ID card info, it has methods to be called on reader inserted / removed & card inserted / removed..
I have implemented the answer by #cole-xia, but the issue is the methods inside IMMDelegate are never called when I insert card reader or ID. When I call ReadCardData(), it should call Started() which will display information saved by Inserted(), but the current result is that Started() method is called after calling ReadCardData(), but Inserted() and ReaderConnected() are never called in any stage.
In the demo app of Framework, it is used as the following (and works properly):
// Demo app -> ViewController.m
#interface ViewController () <MMSDKDelegate>
#end
#implementation ViewController {
MMSDK *sdkInstance;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
sdkInstance = [MMSDK SharedInstance];
[sdkInstance Initialize:self];
}
- (void)Started
{
// Update UI by: reading in progress ..
}
- (void)Inserted
{
// Update UI by: card inserted
// And read card data
[self readData:self];
}
- (void)Removed
{
// Update UI by: card removed
}
- (void)ReaderConnected
{
// Update UI by: card reader connected
}
- (void)ReaderRemoved
{
// Update UI by: card reader removed
}
- (IBAction)readData:(id)sender
{
var *data = [sdkInstance ReadCardData:YES pWithSignatureImage:YES pWithAddressData:YES];
if (data.hasError) {
// No data fetched
return;
}
if (data) {
// return card data
}
}
All suggestions are welcome and appreciated.
In summary, I just need to do same functionality of demo app in Xamarin.iOS app.
Use Sharpie to create ApiDefinition
The result on my side :
// #protocol IMMDelegate
[BaseType (typeof (NSObject))]
[Protocol, Model]
interface IMMDelegate
{
// #required -(void)Inserted;
[Abstract]
[Export ("Inserted")]
void Inserted ();
// #required -(void)Removed;
[Abstract]
[Export ("Removed")]
void Removed ();
}
// #protocol MMSDKDelegate <IMMDelegate>
[BaseType (typeof (NSObject))]
[Protocol, Model]
interface MMSDKDelegate : IMMDelegate
{
// #required -(void)Started;
[Abstract]
[Export ("Started")]
void Started ();
}
// #interface ACR : NSObject
[BaseType (typeof(NSObject))]
interface YourClass
{
// -(void)Initialize:(id<MMSDKDelegate> _Nullable)pDelegate;
[Export ("Initialize:")]
void Initialize ([NullAllowed] MMSDKDelegate pDelegate);
}
Usage:
class MyDelegate : MMSDKDelegate {
public void Started()
{
}
public override void Removed()
{
}
public override void Inserted()
{
}
}
//In ViewController
public override void ViewDidLoad()
{
base.ViewDidLoad();
YourClass yourClass = new YourClass();
yourClass.Initialize(new MyDelegate());
}
Along with Cola Xia's answer you may also need to make sure that, such third party device SDK integration requires some entries in the info.plist file's "Supported external accessory protocols" key.
Please check XCode sample and check if there is an entry for the "Supported external accessory protocols" key. If it is there, then you should add them in your Xamarin.iOS project's info.plist file.
I hope this may help!

Release block or cancel block objc

Am using a Class to make all the network calls to fetch data.
// Helper Class method for network calls
- (void) dataForUser:user withCompletionHandler:(void(^)(id response)) onComplete {
[[webClient sharedObject] fetchDataForUser:user withCompletionHandler:(void(^)(id response)) onComplete {
// do something to get data
onComplete(data);
}];
}
// View Controller's Model Class
- (void) getDataWithCompletionHandler:(void(^)(id)) onComplete {
// helperClassObj is a class variable
[helperClassObj dataForUser:userInfo withCompletionHandler:^(id response) {
// process response and store it as response 1.
onComplete(response1);
}];
}
I cannot make another request until one gets completed. How can I cancel a previous request so that I dont have to wait until I get data. Like I requested data for user1 and request for data for user2 and I need to display user2 data and be able to cancel the previous call.
// Helper Class method for network calls
- (void) dataForUser:user withCompletionHandler:(void(^)(id response)) onComplete {
[webClient fetchDataForUser:user withCompletionHandler:^(id response) {
// do something to get data
if(onComplete) {
onComplete(data);
}
}];
}
// View Controller's Model Class
BOOL isLastRequestCancelled = NO;
- (void) getDataWithCompletionHandler:(void(^)(id)) onComplete {
isLastRequestCancelled = YES;
// helperClassObj is a class variable
[helperClassObj dataForUser:userInfo withCompletionHandler:^(id response) {
// process response and store it as response1
if(!isLastRequestCancelled) {
if(onComplete) {
onComplete(response1);
}
}
isLastRequestCancelled = NO;
}];
}

How to add a completion block to an IOS call

I need to wait for savePhototoImage to complete before moving on in my processing. I assume a completion block is the way to do this.
I have seen a few completion blocks in IOS code, but do not know much about how they are made up.
Can a completion block be added to any function and if so, what would be the correct syntax to add one to this function?
BOOL saved = [Network savePhotoImage:img :self.description :#"Photo"];
ViewController.m
[Network savePhotoImage:img :self.description :#"Photo" withCallback:^(BOOL success)
{
NSLog(#"executing callback");
if (success)
{
NSLog(#"got callback success");
}
else
{
NSLog(#"got callback failure");
}
}];
Network.m
+ (void)savePhotoImage:(UIImage*)PhotoImage :(NSString*)description :(NSString*)imageName withCallback:(ASCompletionBlock)callback
{
add workdone code here...
if (workdone)
callback(YES);
} else {
callback(NO);
}
}
Network.h
typedef void (^ASCompletionBlock)(BOOL success);
+ (void)savePhotoImage:(UIImage*)PhotoImage :(NSString*)description : (NSString*)imageName withCallback:(ASCompletionBlock)callback;

What's wrong with this block formating code?

-(void) vPerformBlockOnAllAutoCompleteHandler:((^)(BGMotherofAutoCompleteHandler * acHandler))block
{
for (BGMotherofAutoCompleteHandler * acHandler in [self arBGKeywordAutoCompleteHandlers]) {
block(acHandler);
}
}
Okay, so block is a block that takes BGMotherofAutoCompleteHandler as argument. I went through the loop and call block(acHandler).
What's wrong?
The error is:
/business/Dropbox/badgers/BadgerNew/BGSearchController3.m:218:49: Expected a type. It seems to me I have to add void before the block.
So this works
-(void) vPerformBlockOnAllAutoCompleteHandler1:(void (^)(BGMotherofAutoCompleteHandler * acHandler))block
{
for (BGMotherofAutoCompleteHandler * acHandler in [self arBGKeywordAutoCompleteHandlers]) {
block(acHandler);
}
}
However I do not need to add that void if the block does not requires parameter. I found this very strange.
The syntax is:
- (void)vPerformBlockOnAllAutoCompleteHandler:(void(^)(BGMotherofAutoCompleteHandler*))block
{
for (BGMotherofAutoCompleteHandler * at in [self arBGKeywordAutoCompleteHandlers]) {
block(at);
}
}
Here's a cheat sheet.

Obj-C function declaration needs semi-colon?

This is really simple but driving me nuts.
I am trying to implement a simple function in my Objective-C code. When I write this,
NSInteger Sort_Function(id id1, id id2, void *context) {
}
I get an error that a semi-colon was expected at the end of the declaration. However, I've seen this type of syntax in many, many examples. What could I possibly be doing wrong? If it matters, this is an iOS app and the function is nested in an if clause. Thanks in advance.
The function definition -- this snippet you posted -- is "nested in a if clause"? That's unfortunately illegal in C (and Obj-C by extension) -- all function declarations and definitions have to be at the top level of the file. Inside an #implementation section is also an option:
// Start of file
// Declaration or definition valid here
void my_func(void); // Declaration
void my_other_func(void);
void my_third_func(void);
void my_func(void) { // Definition
return;
}
#implementation MyClass
// Definition also valid here
void my_other_func(void) {
return;
}
- (void) myMethod {
if( YES ){
void my_third_func(void) { // Invalid here
return;
}
}
}
#end
Is it possible you're confusing the function syntax with block syntax?
// The caret indicates definition of a block, sort of an anonymous function
int (^myBlock)(int);
myBlock = ^int (int my_int) {
return my_int;
};