Clean array by using delegate

lucgian84

I made an AR app that recognize image and show the object recognized in an AlertView. In the AlertView I have 2 buttons: Add and Cancel, I'm using the UIAlertViewDelegate to understand which button the user pressed. If the user press the Add button, the object recognized will be stored in an array. I pass this array to another ViewController, in which I set up a TableView. On the bottom of this TableView there's a button "Pay" to go to another ViewController in which I display the total price of the object recognized. From the last ViewController I can press a button to pay the objects I selected by using the AR. Now when I press this button the app close this ViewController and go back to the first ViewController, but the array in which I stored the object that the AR recognized it's full. To delete the content of this array I thought that the best way is to use the delegation methods, so I made this:

PaymentViewController.h

#import <UIKit/UIKit.h>

@protocol PaymentViewControllerDelegate;

@interface PaymentViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *labelTotal;
- (IBAction)buttonClosePaymentVC:(id)sender;

- (IBAction)buttonPay:(id)sender;

@property(nonatomic,strong)NSString *total;

@property(assign) id<PaymentViewControllerDelegate> delegate;

@end

@protocol PaymentViewControllerDelegate <NSObject>

- (void)cleanReportArray;

@end

PaymentViewController.m

#import "PaymentViewController.h"

@interface PaymentViewController () <UIAlertViewDelegate>

@end

@implementation PaymentViewController
@synthesize delegate = _delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.labelTotal.text = self.total;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)buttonClosePaymentVC:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)buttonPay:(id)sender {
    NSString *pay = [NSString stringWithFormat:@"Stai per pagare %@, procedi?", self.total];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"HelloMS" message:pay delegate:self cancelButtonTitle:@"Si" otherButtonTitles:@"No", nil];
    [alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 0) {
        // Procedura per il pagamento e cancellazione del file plist
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"objects.plist"];
        NSError *error;
        if (![[NSFileManager defaultManager]removeItemAtPath:path error:&error]) {
            NSLog(@"Errore: %@", error);
        }
        __weak UIViewController *vcThatPresentedCurrent = self.presentingViewController;
        [self dismissViewControllerAnimated:YES completion:^{
            [vcThatPresentedCurrent dismissViewControllerAnimated:YES completion:nil];
        }];
        [self.delegate cleanReportArray];
    }
    if (buttonIndex == 1) {
        // Non deve far nulla: fa scomparire l'UIAlertView
    }
}

Here I post to you the method of the class that will use the delegate:

Interface of the ScannerViewController.m

@interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
@property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
@end

In ViewDidLoad I inserted this rows:

PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];

And in the ScannerViewController.m I implemented the method I declared in PaymentViewController.h:

- (void)cleanReportArray {
    [arrayObjectAdded removeAllObjects];
}

I tested my app on my iPhone, the app works fine until I try to pay the objects I scanned by camera, indeed, I tried to pay the object, but it doesn't clean the array in which I stored the objects scanned. What's wrong in my code? I used an tutorial on the web to understand better how the delegation method works. I hope you can help me to fix this issue, thank you

UPDATE: here i will post my ScannerViewController code:

ScannerViewController.h

#import <UIKit/UIKit.h>

@interface ScannerViewController : UIViewController

@end

ScannerViewController.m

#import "ScannerViewController.h"
#import "PaymentViewController.h"
#import "ReportViewController.h"
#import "MSScannerSession.h"
#import "MSResult.h"
#import "XmlReader.h"

static int kMSScanOptions = MS_RESULT_TYPE_IMAGE    |
                            MS_RESULT_TYPE_EAN8     |
                            MS_RESULT_TYPE_EAN13;

@interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
@property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
@end

@implementation ScannerViewController {
    MSScannerSession *_scannerSession;
    NSString *nameOfObjectScanned;
    XmlReader *reader;
    NSMutableArray *arrayObjectAdded;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        _scannerSession = [[MSScannerSession alloc] initWithScanner:[MSScanner sharedInstance]];
        [_scannerSession setScanOptions:kMSScanOptions];
        [_scannerSession setDelegate:self];

    }
    return self;
}

- (void)session:(MSScannerSession *)scanner didScan:(MSResult *)result {
    if (!result) {
        return;
    }
    [_scannerSession pause];

    NSString *resultStr = nil;

    if (result) {
        switch ([result getType]) {
            case MS_RESULT_TYPE_IMAGE:
                resultStr = [NSString stringWithFormat:@"Immagine trovata: %@", [result getValue]];
                break;
            case MS_RESULT_TYPE_EAN8:
            case MS_RESULT_TYPE_EAN13:
                resultStr = [NSString stringWithFormat:@"EAN trovato: %@", [result getValue]];
                break;
            default:
                break;
        }
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        UIActionSheet *asView = [[UIActionSheet alloc]initWithTitle:resultStr delegate:self cancelButtonTitle:@"OK" destructiveButtonTitle:nil otherButtonTitles:nil, nil];
        asView.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
        [asView showInView:self.view];
        [self addObjectToList:resultStr];
    });

}

- (void)addObjectToList:(NSString *)objectName {
    // Ricerca dell'oggetto
    NSString *object = [objectName substringFromIndex:18];
    if ([object isEqualToString:@"Binario_con_coppia"]) {
        [self showAlert:object];
    }
    if ([object isEqualToString:@"Dadi_colorati"]) {
        [self showAlert:object];
    }
    if ([object isEqualToString:@"Dadi_rossi"]) {
        [self showAlert:object];
    }
    if ([object isEqualToString:@"Bici_da_corsa"]) {
        [self showAlert:object];
    }
}

- (void)showAlert:(NSString*)name {
    name = [name stringByReplacingOccurrencesOfString:@"_" withString:@" "];
    nameOfObjectScanned = name;
    NSString *message = [NSString stringWithFormat:@"Ho riconosciuto questo oggetto: %@, vuoi aggiungerlo al carrello?", name];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"HelloMS" message:message delegate:self cancelButtonTitle:@"Aggiungi" otherButtonTitles:@"Annulla", nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 0) {
        NSLog(@"Aggiungi");
        for (int i = 0; i < [reader.objArray count]; i++) {
            if ([[reader.objArray[i]objectForKey:@"name"] isEqualToString:nameOfObjectScanned]) {
                // Salvo il nome dell'oggetto trovato, il prezzo e la descrizione
                NSString *name = [reader.objArray[i]objectForKey:@"name"];
                NSString *desc = [reader.objArray[i]objectForKey:@"desc"];
                NSString *price = [reader.objArray[i]objectForKey:@"price"];
                NSDictionary *newObjectAdded = [[NSDictionary alloc]init];
                newObjectAdded = @{@"name": name,
                                   @"desc": desc,
                                   @"price": price};
                [arrayObjectAdded addObject:newObjectAdded];
            }
        }
    } else {
        NSLog(@"Annulla");
    }
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    [_scannerSession resume];
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    arrayObjectAdded = [[NSMutableArray alloc]init];
    CALayer *videoPreviewLayer = [self.videoPreview layer];
    [videoPreviewLayer setMasksToBounds:YES];

    CALayer *captureLayer = [_scannerSession previewLayer];
    [captureLayer setFrame:[self.videoPreview bounds]];

    [videoPreviewLayer insertSublayer:captureLayer below:[[videoPreviewLayer sublayers] objectAtIndex:0]];
    reader = [[XmlReader alloc]init];
    [reader parseXml];
    [_scannerSession startCapture];
    PaymentViewController *pay = [[PaymentViewController alloc]init];
    [pay setDelegate:self];
}

- (void)cleanReportArray {
    [arrayObjectAdded removeAllObjects];
}

- (void)dealloc {
    [_scannerSession stopCapture];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)stopScanner:(id)sender {
    ReportViewController *reportVC = [[ReportViewController alloc]initWithNibName:@"ReportViewController" bundle:nil];
    reportVC.reportArray = arrayObjectAdded;
    [reportVC setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:reportVC animated:YES completion:nil];
}

@end

To recognize picture I'm using this AR SDK. I hope you can help me to understand where's my issue

Wain

Your problem is that in viewDidLoad you have the code:

PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];

this is the last thing you do in that method. So the instance of PaymentViewController that you create and set the delegate on is immediately destroyed (by ARC).

You need to modify your code so that you call setDelegate: on the actual instance of PaymentViewController that is presented on screen as this is the instance that needs to use the delegate (it receives the callback from the alert view).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related