Discussion Forums  >  Plugins, Customizing, Source Code

Replies: 13    Views: 82

ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
01/11/15 08:12 AM (9 years ago)

Thinking caps on? QR Reader Logic

Working with Chris1's awesome QR Reader plugin for IOS. Generated my own unique QR codes to match each "screen". Below is the code snippet used to list all the screens the QR Scanner finds.That woks fine and does scan the QR Code and opens the corresponding screen. What I need now is to keep track of a certain screen (just one really) and how many times it's scanned and displayed so that if it is displayed more than say 3 times a different screen will appear. The idea is that if the same QR Code is scanned more than 3 times a warning screen will appear. Any ideas how to do this? Thanks:) Code used to get results from QR Reader: //loop through every screen in the applications list of screens for(int i = 0; i < [[appDelegate.rootApp screens] count]; i++){ BT_item *thisScreen = [[appDelegate.rootApp screens] objectAtIndex:i]; // [BT_debugger showIt:self message:[NSString stringWithFormat:@"thisScreen:%@", thisScreen.itemId]]; if ([thisScreen.itemId isEqualToString:result] ) { [self handleTapToLoadScreen:thisScreen theMenuItemData:nil]; return;
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/11/15 10:39 AM (9 years ago)
Maybe using an array? Playing around. It counts it as "1" so far but resets when continuing another QR scan hmmmmmm.....maybe a persistant data thingy like we learned at BT code camp? NSDictionary? BT_item *countScreenOne = [appDelegate.rootApp getScreenDataByItemId:@"2402E58B73513EFEE08F5DE"]; if (thisScreen == countScreenOne ) { NSArray *countQR = [NSArray arrayWithObjects:countScreenOne, nil]; NSCountedSet *set = [[NSCountedSet alloc] initWithArray:countQR]; for (id item in set) { NSLog(@"countQR=%@, Count=%lu", item, (unsigned long)[set countForObject:item]); } }
 
Niraj
buzztouch Evangelist
Profile
Posts: 2943
Reg: Jul 11, 2012
Cerritos
37,930
like
01/11/15 03:13 PM (9 years ago)
NSUserDefaults is your friend :-) Look for that in the BT code, then you can use the BT method. Think it might be named setPrefs and getPrefs. Otherwise, PM me and I can send you my QR code app that uses NSUserDefaults (in the raw) to save the items scanned for later emailing. You can modify it to check for repetition on the scans. -- Niraj
 
SmugWimp
Smugger than thou...
Profile
Posts: 6316
Reg: Nov 07, 2012
Tamuning, GU
81,410
like
01/11/15 07:20 PM (9 years ago)
I'm with Niraj; you can read and write to the User Defaults as a temporary (or long term) bucket of values. Cheers! -- Smug
 
Niraj
buzztouch Evangelist
Profile
Posts: 2943
Reg: Jul 11, 2012
Cerritos
37,930
like
01/11/15 09:08 PM (9 years ago)
To refresh my memory, I went into my badgeReader project, which uses Chris R's QR Scan plugin. For those who want to read along, this is the gist of what I did. (I've sent to Ian a zipped copy of my Xcode project) 1. We need an array to hold the items that are scanned. I put that property in the appDelegate.h @property (nonatomic) NSMutableArray *scannedNumbers; ------------------------- 2. Remember to synthesize the property in the appDelegate.m @synthesize scannedNumbers; ------------------------- 3. Have to initialize the array holding the scanned items within the didFinishLaunchingWithOptions method of the appDelegate.m -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ .... etc ..... //setup global property for barcode scanning if (!self.scannedNumbers){ self.scannedNumbers = [[NSMutableArray alloc] init]; } } // END didFinishLaunchingWithOptions ------------------------- 4. We need a way to clear out the object within NSUserDefaults. I defined that method in the appDelegate.h -(void)clearUserDefaults:(NSString *)key; ------------------------- 5. The method to clear the object within NSUserDefaults is as such: //clear out the data in userDefaults file -(void)clearUserDefaults:(NSString *)key{ // setup pointer to the saved data file NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; // remove all the scanned data [userDefaults removeObjectForKey:key]; [userDefaults synchronize]; //self.scannedNumbers = [[NSMutableArray alloc] initWithCapacity:30]; [self.scannedNumbers removeAllObjects]; } ------------------------- 6. Now that we have an array into which scanned items can be deposited, we should load it from the NSUserDefaults file within viewDidLoad of the Cr_rr_qrreader.m file (the QR plugin) - (void)viewDidLoad{ .... etc ... // setup pointer to the saved data file NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; // read data from file into immutable array NSArray *myArray = [userDefaults objectForKey:@"scannedNumbers"]; [BT_debugger showIt:self message:[NSString stringWithFormat:@"After reading scannedNumbers: %@", myArray]]; if (myArray){ // Copy into a mutable array to add more scans onto it badgereader_appDelegate *appDelegate = (badgereader_appDelegate *) [[UIApplication sharedApplication] delegate]; appDelegate.scannedNumbers = [myArray mutableCopy]; } // ENDIF } // END viewDidLoad ------------------------- 7. Each time an item is scanned, we need to insert it's value into the array and also save the value into the NSUserDefaults within the doSomethingWithResult method of the Cr_rr_qrreader.m file (the QR plugin) -(void)doSomethingWithResult: (NSString *)result { [BT_debugger showIt:self message:[NSString stringWithFormat:@"doSomethingWithResult:%@", result]]; badgereader_appDelegate *appDelegate = (badgereader_appDelegate *) [[UIApplication sharedApplication] delegate]; [appDelegate.scannedNumbers addObject:result]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:appDelegate.scannedNumbers forKey:@"scannedNumbers"]; [userDefaults synchronize]; ... etc. } // END doSomethingWithResult ------------------------- 8. When a User taps a button to clear the scanned items, we have to specify the name (key) to reference it within NSUserDefaults: badgereader_appDelegate *appDelegate = (badgereader_appDelegate *) [[UIApplication sharedApplication] delegate]; [appDelegate clearUserDefaults:@"scannedNumbers"]; ------------------------- Have fun! -- Niraj
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/11/15 09:21 PM (9 years ago)
Thanks Niraj! Chris1 just updated the Qr plugin for iOS and it's sweet. Using ur code it would be cool for the plugin to actually have the option in the control panel for how many scans saved before "doing something" that would be sweet! Hey Chris1 when u see this, what u think:)? Cheers and thanks everyone!!
 
Niraj
buzztouch Evangelist
Profile
Posts: 2943
Reg: Jul 11, 2012
Cerritos
37,930
like
01/11/15 09:43 PM (9 years ago)
If you come up with something brilliant on how to have the Control Panel specify the "doing something" aspect, please let us know. That's the one the one that always puzzles me when writing a plugin. As plugin developers, we try to insulate folks from having to write code. Yet the "do something after a set of scans has completed" always results in writing custom actions in software. For my scanner app, I opted to let the User email a list of scanned items. Then the email recipient can do a myriad of things with that data on their own computer. Another option is to POST that scanned data into a Server. Which then could result in database entries, save the list as a file, etc. -- Niraj
 
SmugWimp
Smugger than thou...
Profile
Posts: 6316
Reg: Nov 07, 2012
Tamuning, GU
81,410
like
01/11/15 10:04 PM (9 years ago)
If you don't mind playing with the code, you can always add your own json key/value manually in the "Json Configuration Data (configurable)" section of the plugin screen control panel. add something like: "savedScanTrigger" : "3", adding, or not, the end of line comma as needed. The rest of course, would be an if statement in the code somewhere. Just my 2¢ Cheers! -- Smug
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/11/15 10:05 PM (9 years ago)
Thanks Niraj! Chris1 just updated the Qr plugin for iOS and it's sweet. Using ur code it would be cool for the plugin to actually have the option in the control panel for how many scans saved before "doing something" that would be sweet! Hey Chris1 when u see this, what u think:)? Cheers and thanks everyone!!
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/11/15 11:37 PM (9 years ago)
Thanks smug! I think we posted the same time! I'm sure I'll be back with questions
 
Niraj
buzztouch Evangelist
Profile
Posts: 2943
Reg: Jul 11, 2012
Cerritos
37,930
like
01/12/15 05:29 AM (9 years ago)
Just be careful when adding custom JSON fields into the Advanced JSON section of the Control Panel. When modifying another field in that same Control Panel screen, the Custom field gets wiped out. I had notified David Book of the problem a few months ago. I assume it has not yet been fixed since he had not asked me to re-test. -- Niraj
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/15/15 09:32 AM (9 years ago)
Hey Guys! Slow going with figuring out how to separate my array data. Is NSCountedSet the right path? Niraj's tutorial above worked perfectly now i need to get the # of times each scan happens and do stuff with that. hmmmm...thanks everyone NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray:appDelegate.scannedNumbers]; NSLog(@"%@",countedSet);
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/15/15 11:55 AM (9 years ago)
So I'm a little further along. I think? Following the code below is the console output. Now how would I go about using the info to "do something"? If statement? hmmm? NSCountedSet *totalScans = [NSCountedSet setWithArray:appDelegate.scannedNumbers]; NSMutableArray *dictArray = [NSMutableArray array]; for (NSNumber *num in totalScans) { NSDictionary *dict = @{@"screenId":num, @"count":@([totalScans countForObject:num])}; [dictArray addObject:dict]; } NSArray *final = [dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"ScreenId" ascending:YES]]]; NSLog(@"%@",final); Output: count = 7; screenId = 2402E58B73513EFEE08F5DE; }, { count = 6; screenId = 9DBC162802A290BD31107B6; }, { count = 4; screenId = 9729C8A8C7DCFCBFEE1BFD6; }
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
01/15/15 12:30 PM (9 years ago)
Now I added an If statement. snails pace but think I'm progressing. Not sure the best way to pic a specific screenId to "do something" with? Right now NSLog prints whenever any one of the screenId's is greater than 3 NSCountedSet *totalScans = [NSCountedSet setWithArray:appDelegate.scannedNumbers]; NSMutableArray *dictArray = [NSMutableArray array]; for (NSNumber *num in totalScans) { NSDictionary *dict = @{@"screenId":num, @"count":@([totalScans countForObject:num])}; [dictArray addObject:dict]; if ([totalScans countForObject:num] > 3) { NSLog(@"YOOOOO!!!!OoO!!!"); } } NSArray *final = [dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"ScreenId" ascending:YES]]]; NSLog(@"%@",final);
 

Login + Screen Name Required to Post

pointerLogin to participate so you can start earning points. Once you're logged in (and have a screen name entered in your profile), you can subscribe to topics, follow users, and start learning how to make apps like the pros.