ios 8.3 BLE Device keeps disconnecting after connecting objective-c - ios

I have a Shearwell stick reader, which reads in cattle tags, sheep tags and goat tags via BLE. When connecting the BLE device, the device list shows up in the tableView of the SDLBluetoothConnectViewController then disappears. I am also not able to grab the information from the device using a segue. The bluetooth icon flashes 3 times and does not pair with the device. Can anyone see where my error is i've looked for hours!! thanks in advance!
here is the SDLStickreader.m
// A StickReader is a wrapper for a CBPeripheral that has been discovered using a filter for StickReader UUID.
#import "SDLStickReader.h"
#import "SDLStickReaderManager.h"
#import "SDLStickReaderPrivate.h"
#import "SDLSerialPort.h"
//#import "SDLIdentifier.h"
#interface SDLStickReader () <SerialPortDelegate>
#property (strong, nonatomic) CBPeripheral *peripheral;
#end
#implementation SDLStickReader
static SDLStickReaderManager * _manager;
NSMutableData *_data;
SDLSerialPort *serialPort;
BOOL waitingForConfigInfo = YES;
NSMutableString *configString;
+(SDLStickReaderManager *)manager {
if (nil == _manager) {
_manager = [[SDLStickReaderManager alloc] init];
}
return _manager;
}
+ (instancetype)forPeripheral: (CBPeripheral *)peripheral {
return [[self alloc] initWithPeripheral:peripheral];
}
- (instancetype)initWithPeripheral: (CBPeripheral *)peripheral {
self = [super init];
if (self) {
_detail = #"";
self.peripheral = peripheral;
//peripheral.delegate = self;
__tagReadService = [CBUUID UUIDWithString:SDL_STICKREADER_TAGREAD_UUID];
if (peripheral.state == CBPeripheralStateConnected) {
NSLog(#"periperal is connected");
} else {
NSLog(#"periperal is NOT connected");
}
_data = [[NSMutableData alloc] init];
serialPort = [[SDLSerialPort alloc] initWithPeripheral:peripheral andDelegate:self];
peripheral.delegate = self;
[serialPort open ];
}
return self;
}
-(BOOL)hasPeripheral: (CBPeripheral *)peripheral {
return [self.peripheral isEqual: peripheral];
}
-(NSUUID *)identifier {
return self.peripheral.identifier;
}
-(NSString *)name {
return self.peripheral.name;
}
-(NSString *)description {
return [NSString stringWithFormat: #"Peripheral: %#", self.name];
}
-(NSString *)state {
switch (self.peripheral.state) {
case CBPeripheralStateConnected:
return SDL_STICKREADER_STATE_CONNECTED;
case CBPeripheralStateConnecting:
return SDL_STICKREADER_STATE_CONNECTING;
case CBPeripheralStateDisconnected:
return SDL_STICKREADER_STATE_DISCONNECTED;
}
}
// Every time the peripheral sends new data, it calls the delegate peripheral:didUpdateValueForCharacteristic:error: method. The second argument contains the characteristic that you can read.
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic: (CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(#"Error");
return;
}
if ([self.characteristics containsObject: characteristic.UUID]) {
NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
// Have we got everything we need?
NSUInteger startOfEom = [stringFromData rangeOfString: SDL_STICKREADER_EOM].location;
if (NSNotFound == startOfEom) {
// it is not the EOM so append the data to what we have so far and wait for more.
[_data appendData: characteristic.value];
} else {
// contains EOM, so remove the
NSString *lastPart = [stringFromData substringToIndex:startOfEom];
NSString *message = [[NSString alloc] initWithData: _data encoding:NSUTF8StringEncoding];
if (nil != lastPart && lastPart.length > 0) {
message = [message stringByAppendingString:lastPart];
}
if (nil != self.listener) {
[self.listener stickReader:self didReadTag:message];
}
[_data setLength:0];
}
}
}
// Method that ensures that the CBCentral knows when a notification state for a given characteristic changes. Track it in order to understand when a characteristic state changes (update app values). You should check if the characteristic notification has stopped. If it has, you should disconnect from it:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (![self.characteristics containsObject: characteristic.UUID]) {
return;
}
if (characteristic.isNotifying) {
NSLog(#"Notification began ");
} else {
// Notification has stopped
NSLog(#"Notification stopped ");
//[_manager cancelPeripheralConnection:peripheral];
}
}
/////////////////////////////////////////////////////////////////////////////////////
- (void) port: (SDLSerialPort*) serialPort event : (SPEvent) ev error: (NSInteger)err {
if (SP_EVT_OPEN == ev) {
//NSLog(#"serialPortOpened");
configString = [[NSMutableString alloc] init];
[serialPort write: [#"c\r" dataUsingEncoding: NSUTF8StringEncoding]];
} else {
NSLog(#"serialPortClosed");
}
}
- (void) writeComplete: (SDLSerialPort*) serialPort withError: (NSInteger)err {
NSLog(#"writeComplete");
}
- (void) port: (SDLSerialPort*) serialPort receivedData: (NSData*)data {
if (data.length > 0) {
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString: #"|()#"];
NSString *str = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"receivedData: %#", str);
if ([str hasPrefix: #"Shearwell"]) {
_detail = str;
//NSLog(#"updating: %#", str);
[[SDLStickReader manager] addedShearwellStickReader: self];
} else if (NSNotFound != [str rangeOfCharacterFromSet: charSet].location ) {
// Data
if (waitingForConfigInfo) {
[configString appendString:str];
if (NSNotFound != [configString rangeOfString: #"(cS)"].location) {
// got end of config string, parse config.
NSRange found = [configString rangeOfString: #"#18|"];
if (NSNotFound != found.location) {
NSRange getRange = NSMakeRange(found.location + found.length, 1);
NSString *str = [configString substringWithRange: getRange];
self.eidFormat = [str integerValue];
NSLog(#"StickReader format: %d", self.eidFormat);
}
waitingForConfigInfo = NO;
[serialPort write: [#"v\r" dataUsingEncoding: NSUTF8StringEncoding]];
}
} else {
// Users data
[self.listener stickReader:self didReadData: str];
}
} else {
// Tag
if (nil != self.listener) {
[self.listener stickReader:self didReadTag: str];
}
}
}
}
and my SDLBluetoothConnectViewController.m
#import "SDLBluetoothConnectViewController.h"
#import "SDLStickReaderManager.h"
#import "SDLStickReader.h"
#import "SDLViewController.h"
#interface SDLBluetoothConnectViewController () <UITableViewDataSource, UITableViewDelegate, SDLStickReaderManagerListener>
#property (weak, nonatomic) IBOutlet UITableView *stickReaderListView;
#property (strong, nonatomic) IBOutlet UILabel *stickReaderNameLabel;
#property (strong, nonatomic) IBOutlet UILabel *stickReaderDescLabel;
#end
/*
This class starts the process of scanning in the 'viewDidLoad' method by setting the SDLStickReaderManager 'singleton' to self. When the scan button is pressed the SDLStickReaderManager scan is called, and each stick reader found is returned via the listener call. This listener call is used to refresh the table view.
When a user selects a stick reader from the list the StickReader view is started and passed the selected stick reader.
*/
#implementation SDLBluetoothConnectViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.stickReaderListView setDelegate: self];
[self.stickReaderListView setDataSource: self];
[SDLStickReader manager].listener = self;
[self.stickReaderListView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)scanButtonPressed:(id)sender {
[SDLStickReader.manager scan];
}
- (IBAction)cancelButtonPressed:(id)sender {
SDLStickReader.manager.listener = nil;
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)viewWillDisappear:(BOOL)animated {
/*
Every time the view disappears, you should stop the scanning process.
*/
[SDLStickReader.manager stopScan];
}
/////////////////////////////////////////////////////////////////////////////////
/////// Table handling //////////////////////////////////////////////////////////
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *stickReaders = SDLStickReader.manager.discoveredStickReaders;
SDLStickReader * stickReader = [stickReaders objectAtIndex: indexPath.row];
[SDLStickReader.manager stopScan];
[self performSegueWithIdentifier:#"deviceInfoSegue" sender:self];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *stickReaders = SDLStickReader.manager.discoveredStickReaders;
return stickReaders.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: simpleTableIdentifier];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: simpleTableIdentifier];
}
NSArray *stickReaders = SDLStickReader.manager.discoveredStickReaders;
SDLStickReader * stickReader = [stickReaders objectAtIndex: indexPath.row];
NSString *desc = [stickReader name];
cell.textLabel.text = desc;
return cell;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"deviceInfoSegue"]) {
//some additional info here
}
}
////////////////////////////////////////////////////////////////////////////////// /
/// SDLStickReaderManager callbacks ///////////////////////////////////////////////
-(void)stickReader: (SDLStickReader *)stickReader addedToList: (NSArray *)discoveredStickReaders {
//NSLog(#"View StickReaderAdded");
[self.stickReaderListView reloadData];
//[SDLStickReader.manager connect: stickReader];
}
-(void)connectedStickReader: (SDLStickReader *)stickReader {
//NSLog(#"View StickReader connected");
[self.stickReaderListView reloadData];
}
-(void)disconnectedStickReader: (SDLStickReader *)stickReader {
//NSLog(#"View StickReader disconnected");
[self.stickReaderListView reloadData];
}

Related

How to debug "unrecognized selector sent to instance"

I want to check if the user has an open basket if so send them to the menu if not then send send them to my open basket view but i m getting an error.
So my question is how to get rid of this problem ? and is my logic right ?
'NSInvalidArgumentException', reason: '-[Merchant merchantId]: unrecognized selector sent to instance 0x7fad19529490'.
i m using this method to check for open baskets when the button addToOrderButtonTapped is press in the menuview
[[OrderManager sharedManager]getBasketsForMerchant:merchant success:^(NSArray *baskets) {
for (Basket *basket in baskets){
if ([basket.status isEqualToString:kBasketStatusOpen]) {
[self.openBaskets addObject:basket];
}
}if (self.openBaskets.count > 0){
self.openBaskets = self.openBaskets;
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:kSegueMenu sender:self];
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:KSegueOpenBasket sender:self];
});
}
} failure:^(NSError *error, NSHTTPURLResponse *response) {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *localizedString = NSLocalizedString(#"Order.ErrorLoadingOpenOrders", "Get error message");
[self showMessage:localizedString withTitle:MessageTypeError];
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
});
}];
The menuview
//
// MenuItemViewController.m
// BaseApp
//
#import "MenuItemViewController.h"
#import "RoundedButton.h"
#import "MenuOptionCell.h"
#import "MenuItem.h"
#import "MenuOptionButton.h"
#import "MenuChoice.h"
#import "OrderManager.h"
#import "TypeOfChoiceCell.h"
#import "MenuOption.h"
#import "OrderPricingTableViewCell.h"
#import "RKManagedObjectStore.h"
#import "NSManagedObjectContext+RKAdditions.h"
#import "MerchantManager.h"
#import "Merchant.h"
#import "OrdersViewController.h"
#import "MenuItem.h"
#import "MenuViewController.h"
#import "OrderConfirmationViewController.h"
#import "OrderManager.h"
#import "APIClient.h"
#import "MenuManager.h"
#import "DiscoverViewController.h"
#import "DiscoverCollectionViewCell.h"
#import "MerchantManager.h"
#import "MenuViewController.h"
#import "MenuManager.h"
#import "MerchantDetailsViewController.h"
#import "OpenOrdersViewController.h"
typedef NS_ENUM(NSUInteger, MenuOptionsSection) {
MenuOptionsSectionRequired = 0,
MenuOptionsSectionOptional = 1
};
static NSString *const OpenBasketsSegue = #"OpenBaskets";
static NSString *const kSegueMenu = #"ShowMenu";
static NSString *const KSegueOpenBasket = #"OpenBaskets";
#interface MenuItemViewController () <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, weak) IBOutlet UILabel *menuItemName;
#property (nonatomic, weak) IBOutlet UILabel *quantityLabel;
#property (nonatomic, weak) IBOutlet UILabel *menuItemPrice;
#property (nonatomic, weak) IBOutlet UILabel *subTotalLabel;
#property (nonatomic, weak) IBOutlet UITextView *menuItemDescription;
#property (nonatomic, weak) IBOutlet RoundedButton *addToOrderButton;
#property (nonatomic, weak) IBOutlet UITableView *tableView;
#property (nonatomic, weak) IBOutlet UIView *cartView;
#property (nonatomic, weak) IBOutlet UIButton *subtractButton;
#property (nonatomic) NSDecimalNumber *temporarySubtotal;
#property (nonatomic, strong) NSMutableArray<MenuOption *> *requiredChoices;
#property (nonatomic, strong) NSMutableArray<MenuOption *> *optionalChoices;
#property (nonatomic, strong) NSMutableArray<NSMutableArray *> *optionChoicesSection;
#property (nonatomic, strong) NSMutableArray<NSDictionary *> *options;
#property (nonatomic, strong) NSMutableArray <Basket *>*openBaskets;
#property (nonatomic) BOOL launchViewFirstTime;
#end
#implementation MenuItemViewController
#pragma - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = #"Menu Item";
self.menuItemName.text = self.menuCategory.selectedBasketLine.menuItem.name;
self.menuItemPrice.text = [NSString stringWithFormat:#"%#", [Basket formattedCurrencyStringForAmount:self.menuCategory.selectedBasketLine.menuItem.price]];
self.quantityLabel.text = self.menuCategory.selectedBasketLine.quantity.stringValue;
self.temporarySubtotal = [self calculateTemporarySubtotal:[OrderManager sharedManager].currentBasket.subtotal menuItemPrice:self.menuCategory.selectedBasketLine.menuItem.price];
[self setSubtotalText:self.temporarySubtotal];
self.menuItemDescription.text = self.menuCategory.selectedBasketLine.menuItem.menuItemDescription;
self.subtractButton.alpha = 0.65;
self.requiredChoices = [[NSMutableArray alloc] init];
self.optionalChoices = [[NSMutableArray alloc] init];
self.optionChoicesSection = [[NSMutableArray alloc] init];
self.options = [[NSMutableArray alloc] init];
[self initializeChoiceArrays];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.launchViewFirstTime = YES;
if (self.optionChoicesSection.count > 0) {
[self.tableView reloadData];
} else {
self.tableView.hidden = YES;
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.launchViewFirstTime = NO;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
for (MenuOption *menuOption in self.requiredChoices) {
[menuOption resetNumberOfChoicesSelected];
}
for (MenuOption *menuOption in self.optionalChoices) {
[menuOption resetNumberOfChoicesSelected];
}
self.menuCategory = nil;
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.menuItemDescription setContentOffset:CGPointZero animated:YES];
}
#pragma - IBActions
- (IBAction)addButtonTapped:(id)sender {
NSInteger count = self.quantityLabel.text.integerValue;
count++;
if (count > 1) {
self.subtractButton.alpha = 1;
}
NSDecimalNumber *newSubTotal = [self.temporarySubtotal decimalNumberByAdding:self.menuCategory.selectedBasketLine.menuItem.price];
[self modifyCurrentBasketSubtotal:newSubTotal quantity:count];
}
- (IBAction)subtractButtonTapped:(id)sender {
NSInteger count = self.quantityLabel.text.integerValue;
if (count > 1) {
count--;
NSDecimalNumber *newSubTotal = [self.temporarySubtotal decimalNumberBySubtracting:self.menuCategory.selectedBasketLine.menuItem.price];
[self modifyCurrentBasketSubtotal:newSubTotal quantity:count];
if (count == 1) {
self.subtractButton.alpha = 0.65;
}
}
}
- (IBAction)addToOrderButtonTapped:(id)sender {
MenuOption *menuOption;
Merchant *merchant = [[Merchant alloc]init];
// First check if there are any missing required options that have to be selected
if ((menuOption = [self checkMissingRequiredOptionsHaveBeenSelected])) {
NSString *localizedString = NSLocalizedString(#"AddMenuItem.RequiredChoicesNotSelected", #"Get string for error");
NSString *formattedString = [NSString stringWithFormat:localizedString, menuOption.name];
[self showMessage:formattedString withTitle:MessageTypeError];
return;
}
// Now check if the minimum and maximum choice seletion have been met for the menu options
if ((menuOption = [self validateMinMaxForMenuOptionsHaveBeenMet])) {
NSString *localizedString = NSLocalizedString(#"AddMenuItem.MinMaxNotFulfilled", #"Get string for error");
NSString *formattedString = [NSString stringWithFormat:localizedString, menuOption.name];
[self showMessage:formattedString withTitle:MessageTypeError];
return;
}
// Add the menu item to the basket
if (self.menuItemAddedBlock) {
self.menuItemAddedBlock(self, self.menuCategory);
// [self dismissViewControllerAnimated:YES completion:nil];
//checking for open basket here
[[OrderManager sharedManager]getBasketsForMerchant:merchant success:^(NSArray *baskets) {
for (Basket *basket in baskets){
if ([basket.status isEqualToString:kBasketStatusOpen]) {
[self.openBaskets addObject:basket];
}
}if (self.openBaskets.count > 0){
self.openBaskets = self.openBaskets;
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:kSegueMenu sender:self];
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:KSegueOpenBasket sender:self];
});
}
} failure:^(NSError *error, NSHTTPURLResponse *response) {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *localizedString = NSLocalizedString(#"Order.ErrorLoadingOpenOrders", "Get error message");
[self showMessage:localizedString withTitle:MessageTypeError];
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
});
}];
}
}
- (IBAction)cancelButtonTapped:(UIBarButtonItem *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma - UITableViewDelegate, UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.optionChoicesSection.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.optionChoicesSection[section].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MenuOptionCell *cell = (MenuOptionCell *)[tableView dequeueReusableCellWithIdentifier:[MenuOptionCell reuseIdentifier]];
cell.menuOption = self.optionChoicesSection[indexPath.section][indexPath.row];
cell.menuOptionCellButtonPressedBlock = ^(MenuOptionButton *button, MenuOption *option, MenuChoice *choice) {
[self adjustSelectedOptions:option choice:choice indexPath:indexPath];
};
cell.menuOptionCellDefaultOptionDetectedBlock = ^(MenuOptionButton *button, MenuOption *option, MenuChoice *choice) {
[self adjustSelectedOptions:option choice:choice indexPath:indexPath];
};
cell.menuOptionCellDeselectedBlock = ^(MenuOptionButton *button, MenuOption *option, MenuChoice *choice) {
[self adjustSelectedOptions:option choice:choice indexPath:indexPath];
};
[cell configureCell:self.launchViewFirstTime];
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
TypeOfChoiceCell *cell = (TypeOfChoiceCell *)[tableView dequeueReusableCellWithIdentifier:[TypeOfChoiceCell reuseIdentifier]];
switch ((MenuOptionsSection)section) {
case MenuOptionsSectionRequired:
if (self.requiredChoices.count > 0) {
cell.title = NSLocalizedString(#"AddMenuItem.RequiredChoiceText", #"Get string for title");
return cell;
} else if (self.optionalChoices.count > 0) {
cell.title = NSLocalizedString(#"AddMenuItem.OptionalChoiceText", #"get string for title");
return cell;
}
case MenuOptionsSectionOptional:
if (self.optionalChoices.count > 0) {
cell.title = NSLocalizedString(#"AddMenuItem.OptionalChoiceText", #"Get string for title");
return cell;
}
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
MenuOption *option = self.optionChoicesSection[indexPath.section][indexPath.row];
return [MenuOptionCell heightForMenuOption:option];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return [TypeOfChoiceCell height];
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.01f;
}
#pragma - Helpers
- (void)setSubtotalText:(NSDecimalNumber *)subtotal {
if (!subtotal) {
self.subTotalLabel.text = NSLocalizedString(#"AddMenuItem.SubtotalDefault", #"Get string for subtotal");
} else {
NSString *localizedString = NSLocalizedString(#"AddMenuItem.SubtotalFormatted", #"Get string for subtotal");
self.subTotalLabel.text = [NSString stringWithFormat:localizedString, [Basket formattedCurrencyStringForAmount:subtotal]];
}
}
- (void)modifyCurrentBasketSubtotal:(NSDecimalNumber *)subtotal quantity:(NSInteger)quantity {
self.menuCategory.selectedBasketLine.quantity = [NSNumber numberWithInteger:quantity];
self.menuCategory.selectedBasketLine.subtotal = subtotal;
self.temporarySubtotal = subtotal;
[self setSubtotalText:subtotal];
self.quantityLabel.text = self.menuCategory.selectedBasketLine.quantity.stringValue;
}
- (NSDecimalNumber *)calculateTemporarySubtotal:(NSDecimalNumber *)orderManagerSubTotal menuItemPrice:(NSDecimalNumber *)menuItemPrice {
if (orderManagerSubTotal == 0) {
return menuItemPrice;
} else {
return [orderManagerSubTotal decimalNumberByAdding:menuItemPrice];
}
}
- (MenuOption *)checkMissingRequiredOptionsHaveBeenSelected {
for (MenuOption *menuOption in self.requiredChoices) {
if (!menuOption.selected) {
return menuOption;
}
}
return nil;
}
- (MenuOption *)validateMinMaxForMenuOptionsHaveBeenMet {
for (MenuOption *menuOption in self.requiredChoices) {
if ([menuOption validateIndividualMinMaxForMenuOption]) {
return menuOption;
}
}
for (MenuOption *menuOption in self.optionalChoices) {
if (menuOption.selected) {
if ([menuOption validateIndividualMinMaxForMenuOption]) {
return menuOption;
}
}
}
return nil;
}
- (void)initializeChoiceArrays {
NSArray<MenuOption *> *menuOptions = [self.menuCategory.selectedBasketLine.menuItem.menuOptions allObjects];
for (MenuOption *menuOption in menuOptions) {
if (menuOption.minimumChoices == nil) {
menuOption.minimumChoices = [NSNumber numberWithInt:0];
}
if (menuOption.maximumChoices == nil) {
menuOption.maximumChoices = [NSNumber numberWithInt:0];
}
// For now make an optional choice required if minimumChoices > 0
if (menuOption.isRequired || [menuOption.minimumChoices intValue] > 0) {
menuOption.isRequired = YES;
[self.requiredChoices addObject:menuOption];
} else {
[self.optionalChoices addObject:menuOption];
}
}
if (self.requiredChoices.count > 0) {
[self.optionChoicesSection addObject:self.requiredChoices];
}
if (self.optionalChoices.count > 0) {
[self.optionChoicesSection addObject:self.optionalChoices];
}
}
- (void)adjustSelectedOptions:(MenuOption *)option choice:(MenuChoice *)choice indexPath:(NSIndexPath *)indexPath {
self.menuCategory.selectedBasketLine.subtotal = self.menuCategory.selectedBasketLine.menuItem.price;
if (option.selected && option.menuChoices.count == 0) {
[self.options addObject:#{kOption: option.menuOptionId ?: #"", kChoice: #""}];
if (option.price) {
self.temporarySubtotal = [self.temporarySubtotal decimalNumberByAdding:option.price];
}
if (option.isRequired) {
self.requiredChoices[indexPath.row].selected = option.selected;
self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
} else {
self.optionalChoices[indexPath.row].selected = option.selected;
self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
}
} else {
if (option.menuChoices.count == 0) {
[self.options removeObject:#{kOption: option.menuOptionId ?: #"", kChoice: #""}];
if (option.price) {
self.temporarySubtotal = [self.temporarySubtotal decimalNumberBySubtracting:option.price];
}
if (option.isRequired) {
self.requiredChoices[indexPath.row].selected = option.selected;
self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
} else {
self.optionalChoices[indexPath.row].selected = option.selected;
self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
}
}
}
if (choice.selected && option.menuChoices.count > 0) {
[self.options addObject:#{kOption: choice.menuOption.menuOptionId ?: #"", kChoice: choice.menuChoiceId ?: #""}];
if (choice.price) {
self.temporarySubtotal = [self.temporarySubtotal decimalNumberByAdding:choice.price];
}
if (option.isRequired) {
self.requiredChoices[indexPath.row].selected = choice.selected;
self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
} else {
self.optionalChoices[indexPath.row].selected = choice.selected;
self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
}
} else {
if (option.menuChoices.count > 0) {
[self.options removeObject:#{kOption: choice.menuOption.menuOptionId ?: #"", kChoice: choice.menuChoiceId ?: #""}];
if (choice.price) {
self.temporarySubtotal = [self.temporarySubtotal decimalNumberBySubtracting:choice.price];
}
if (option.isRequired) {
if ([option.numberOfChoicesSelected intValue] == 0) {
self.requiredChoices[indexPath.row].selected = option.selected;
} else {
self.requiredChoices[indexPath.row].selected = !choice.selected;
}
self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
} else {
self.optionalChoices[indexPath.row].selected = choice.selected;
self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
}
}
}
[self setSubtotalText:self.temporarySubtotal];
self.menuCategory.selectedBasketLine.attributes = self.options;
}
#end
This is the line of code thats giving me the error
+ (void)getBasketsForMerchant:(Merchant *)merchant success:(void (^)(NSArray *basket))success failure:(void (^)(NSError *, NSHTTPURLResponse *))failure {
NSMutableDictionary* params = #{#"expand": #"merchant"}.mutableCopy;
if (merchant) {
params[#"merchant"] = merchant.merchantId;
}
[[RKObjectManager sharedManager] getObjectsAtPath:kOrdersEndpoint parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult){
NSArray* items = mappingResult.array;
if (success) {
success(items);
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
if (failure) {
failure(error, operation.HTTPRequestOperation.response);
} else {
_defaultFailureBlock(operation, error);
}
}];
}
This error:
'NSInvalidArgumentException', reason: '-[Merchant merchantId]: unrecognized selector sent to instance 0x7fad19529490'.
Means that you have an object at location 0x7fad19529490 and you tried to call "merchantId" on it. That object does not respond to merchantId.
So, look very carefully at the definition of Merchant. Did you get the spelling of merchantId right in fieldMappings? Is it merchantID with a capital D?
If you are sure that merchant has a property named merchantId exactly, then, the next likely thing is that the object at 0x7fad19529490 is not a Merchant.
The easiest thing to do is to add an exception breakpoint (use the +) at the bottom of the breakpoint navigator. When this exception happens, grab the pointer address from the error (it might be different each time) and see what it is in the debugger. To do that, at the (lldb) prompt, type:
po (NSObject*)(0x7fad19529490)
but use the address from the error. If it's a Merchant, I expect it to say something like:
<Merchant: 0x7fad19529490>
Or, if you have overridden description, it will be the output of that.

IOS dev: Just need help in exc_bad_access error

Help, my app is showing thread 1 error exc_bad_access(code=1, address=0x2000001) on the last curly brace of my PlayViewController.
Note: this happen when I click the continue button on my GuessViewController. The continue button calls the the PlayViewController.
What i already did:
enabled ZOMBIE
close db
my GuessViewController:
#import "GuessViewController.h"
#import "PlayViewController.h"
#import "ViewController.h"
#interface GuessViewController ()
#end
#implementation GuessViewController
#synthesize userInput = _userInput;
#synthesize gword;
#synthesize gletter;
int score = 0;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_userInput.delegate = self;
self.scoreLabel.text = [NSString stringWithFormat:#"%d", score];
// Do any additional setup after loading the view.
}
-(void)touchesBegan:(NSSet*)touches withEvent: (UIEvent *) event{
[_userInput resignFirstResponder];
}
-(BOOL)textFieldShouldReturn: (UITextField*)textField {
if(textField){
[textField resignFirstResponder];
}
return NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)checkAnswer:(id)sender {
NSLog(#"%#", gword);
NSLog(#"%#", gletter);
NSString *temp = self.userInput.text;
unichar temp2 = [temp characterAtIndex: 0];
NSString *userletter= [NSString stringWithFormat:#"%C", temp2];
NSString *message1 = #"The word is ";
NSString *message2= [NSString stringWithFormat:#"%#", gword];
NSString *fm = [message1 stringByAppendingString:message2];
if([userletter isEqualToString:gletter]){
UIAlertView *checkAlert = [[UIAlertView alloc] initWithTitle:#"Got it Right" message:fm delegate:self cancelButtonTitle:#"Continue" otherButtonTitles:#"Back to Main Menu", nil];
score++;
self.scoreLabel.text = [NSString stringWithFormat:#"%d", score];
[checkAlert show];
}else{
UIAlertView *checkAlert = [[UIAlertView alloc] initWithTitle:#"Wrong" message:fm delegate:self cancelButtonTitle:#"Continue" otherButtonTitles:#"Back to Main Menu", nil];
[checkAlert show];
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex ==0){
PlayViewController *playViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Play"];
[self presentViewController:playViewController animated:YES completion: Nil];
} else {
ViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Main"];
[self presentViewController:viewController animated:YES completion: Nil];
}
}
#end
My PlayViewController:
#import "PlayViewController.h"
#import "GuessViewController.h"
#import <sqlite3.h>
#import "Word.h"
#interface PlayViewController ()
#end
#implementation PlayViewController
#synthesize thewords;
NSString *word;
NSTimer *myTimer;
int randomIndex;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[self wordList];
[super viewDidLoad];
// Do any additional setup after loading the view.
self.listChar.text = #" ";
int r = (arc4random()%[self.thewords count]);
word = [self.thewords objectAtIndex:r];
NSLog(#"%#", word);
randomIndex = (arc4random()%word.length);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)startGame:(id)sender {
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(listLetter:) userInfo:nil repeats:YES];
}
- (void)listLetter:(NSTimer *)timer
{
static int i = 0;
unichar letter;
if(randomIndex == i){
letter = ' ';
} else {
letter = [word characterAtIndex: i];
}
self.listChar.text = [NSString stringWithFormat:#"%C", letter];
if (++i == word.length) {
[timer invalidate];
i = 0;
GuessViewController *guessViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Guess"];
//passing some data
guessViewController.word = word;
guessViewController.letter = [NSString stringWithFormat:#"%C", [word characterAtIndex: randomIndex]];
[self presentViewController:guessViewController animated:YES completion: Nil];
}
}
-(NSMutableArray *) wordList {
thewords = [[NSMutableArray alloc] initWithCapacity:26];
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"LetterHunter.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success){
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)){
NSLog(#"An error has occured");
}
const char *sql = "SELECT * FROM WordList";
sqlite3_stmt*sqlStatement;
if(sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL)!=SQLITE_OK){
NSLog(#"Problem with prepare statement1");
} else {
while(sqlite3_step(sqlStatement) == SQLITE_ROW){
Word *word = [[Word alloc]init];
word.wordfromdb = [NSString stringWithUTF8String:(char*)sqlite3_column_text(sqlStatement, 1)];
[thewords addObject: word.wordfromdb];
}
}
sqlite3_finalize(sqlStatement);
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement2");
}
#finally {
sqlite3_close(db);
}
}
#end
As suggested below, I tried doing this instead but still there's the error
while(sqlite3_step(sqlStatement) == SQLITE_ROW){
NSString *temp = #"";
temp = [NSString stringWithUTF8String:(char*)sqlite3_column_text(sqlStatement, 1)];
[thewords addObject: temp;
}
From debug stack, it's a problem about autorelease. And I think the problem maybe in
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)){
I can't find db define. So I think it should be a instance property.
Try this:
DbClass *tempDb = nil;
if(!(sqlite3_open([dbPath UTF8String], &tempDb) == SQLITE_OK)){
self.db = tempDb;
What is wordfromdb? If it is string variable or any other datatype then add directly that into an array...
I think there is not need to create word object here as anyway your are not storing word object in array.
It looks to me an issue with word object. You are crating word object but adding its property only and not entire object.

iOS - Can't add NSString objects to NSMutableSet

For some reason NSString objects just won't go into an NSMutableSet
The set remains empty - count stays 0 and firstInHandler is never called
I have tried everything..!
If anyone has any idea why I would greatly appreciate the help
VCKeySet.h
#import <Foundation/Foundation.h>
#interface VCKeySet : NSObject
{
void (^firstInHandler)();
void (^lastOutHandler)();
}
#property (atomic, readonly, strong) NSMutableSet* keys;
- (id) initWithFirstInHandler:(void(^)()) firstInHandler_ withLastOutHandler:(void(^)()) lastOutHandler_;
- (void) add:(NSString*) key_;
- (void) remove: (NSString*) key_;
- (BOOL) has: (NSString*) key;
#end
VCKeySet.m
#import "VCKeySet.h"
#implementation VCKeySet
#synthesize keys;
- (id) initWithFirstInHandler: (void(^)()) firstInHandler_ withLastOutHandler: (void(^)()) lastOutHandler_
{
if(self=[self init])
{
firstInHandler = firstInHandler_;
lastOutHandler = lastOutHandler_;
}
return self;
}
- (void) add:(NSString*) key_
{
for(NSString* key in self.keys)
{
if([key isEqualToString:key_])
{
return;
}
}
[self.keys addObject:key_];
if([self.keys count] == 1)
{
firstInHandler();
}
}
- (void) remove: (NSString*) key_
{
for(NSString* key in keys)
{
if([key isEqualToString:key_])
{
[keys removeObject:key];
if([keys count] == 0)
{
lastOutHandler();
}
}
}
}
- (BOOL) has: (NSString*) key_
{
for(NSString* key in keys)
{
if([key isEqualToString:key_])
{
return YES;
}
}
return NO;
}
#end
Here is how I try to add a key to the set
VCKeySet* lock = [[VCKeySet alloc] initWithFirstInHandler:^()
{
NSLog(#"Adding UI lock");
[application beginIgnoringInteractionEvents];
}
withLastOutHandler:^()
{
NSLog(#"Removing UI lock");
[application endIgnoringInteractionEvents];
}];
[lock add:#"InitialiseApp"];
Thanks
The problem is, you never allocate and initialize your set.
Refactor your add: method to look something like this:
- (void) add:(NSString*) key_ {
if (!self.keys) {
_keys = [[NSMutableSet alloc] init];
}
[self.keys addObject:key_];
if([self.keys count] == 1) {
firstInHandler();
}
}

Cannot reload table view in IOS7

I am a quite new to IOS development and keep having struggle with it. I would like to display phone list which an user has from my server but tableview does not display items. I have got data from server well and I think settings for UItableView is correct. Here is my code:
STKPhoneHolderViewController.h
#import <UIKit/UIKit.h>
#import "STKSimpleHttpClientDelegate.h"
#interface STKPhoneHolderViewController : UITableViewController <UITableViewDataSource, STKSimpleHttpClientDelegate>
#property (strong, nonatomic) IBOutlet UITableView *phoneTable;
#property (strong, nonatomic) NSMutableArray *phoneArray;
#end
STKPhoneHolderViewController.m
#implementation STKPhoneHolderViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.phoneTable.dataSource = self;
self.phoneArray = [[NSMutableArray alloc]init];
[self loadPhoneList];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.phoneArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PhoneCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
STKPhoneHolder *phoneHolder = [self.phoneArray objectAtIndex:indexPath.row];
[cell.textLabel setText:phoneHolder.userName];
return cell;
}
#pragma Custom method
- (void) loadPhoneList
{
self.phoneArray = [[NSMutableArray alloc]init];
STKSimpleHttpClient *client = [[STKSimpleHttpClient alloc]init];
client.delegate = self;
NSString *userId = #"your_id_h";
NSString *sUrl = [NSString stringWithFormat:#"%#%#?userid=%#",
MOBILE_API_URL,
PHONEHOLDER_URI,
userId];
[client send:sUrl data:#""];
}
#pragma STKSimpleHttpClientDelegate
-(void) complete:(STKHttpResult*) result
{
if (result.ok != YES){
[STKUtility alert:result.message];
return;
}
self.phoneArray = (NSMutableArray*)result.result;
for (STKPhoneHolder *holder in self.phoneArray) {
NSLog(#"%#", [holder description]);
}
[self.phoneTable reloadData];
NSLog(#" isMainThread(%d)", [NSThread isMainThread] );
}
#end
STKSimpleHttpClient.m
#import "STKSimpleHttpClient.h"
#import "STKSimpleHttpClientDelegate.h"
#implementation STKSimpleHttpClient
NSMutableData *responseData;
STKHttpResult *httpResult;
void (^completeFunction)(STKHttpResult *);
- (void) send:(NSString*)url
data:(NSString*)data
{
httpResult = [[STKHttpResult alloc]init];
dispatch_async(dispatch_get_main_queue(), ^{
if ( data == nil) return;
//Get request object and set properties
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: url]];
//set header for JSON request and response
[urlRequest setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[urlRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
//set http method to POST
[urlRequest setHTTPMethod:#"POST"];
//set time out
[urlRequest setTimeoutInterval:20];
NSData *body = [data dataUsingEncoding:NSUTF8StringEncoding];
//set request body
urlRequest.HTTPBody = body;
//connect to server
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
if (conn==nil){
//Do something
}
});
}
#pragma mark - NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
[responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable noow
NSError *error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
BOOL ok = [[json objectForKey:#"ok"] boolValue];
NSString *message = [json objectForKey:#"message"];
if (ok == NO) {
[httpResult setError:message];
} else {
[httpResult setSuccess:[json objectForKey:#"result"]];
}
if (self.delegate !=nil) {
[self.delegate complete:httpResult];
}
responseData = nil;
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
if (self.delegate !=nil) {
[self.delegate complete:[httpResult setError:#"Connection failed."]];
}
}
STKPhoneHolder.m
#import <Foundation/Foundation.h>
#interface STKPhoneHolder : NSObject
#property NSString *deviceId;
#property NSString *userId;
#property NSString *userName;
#property NSString *msn;
- (id) initWithDeviceId:(NSString*)aDeviceId
userId:(NSString*)aUserId
userName:(NSString*)aUserName
msn:(NSString*)aMsn;
#end
Log:
2013-12-17 16:14:23.447 [5323:70b] {
deviceId = 11111;
email = "";
msn = 11111111;
role = "";
userId = aaaaaa;
userName = "Joshua Pak";
}
2013-12-17 16:14:23.448 [5323:70b] {
deviceId = 22222;
email = "";
msn = 2222222;
role = "";
userId = bbbbb;
userName = "Jasdf Pak";
}
2013-12-17 16:14:23.449 Stalker[5323:70b] isMainThread(1)
I can see the log printing phoneArray with two phones in 'complete' method but tableview just display "No record". Tableview does not render again even though I called reloadData method. I made sure that [self.phoneTable reloadData] is called in debugging mode.
What do I have to do more?
Try to call reloadData in main thread
#pragma STKSimpleHttpClientDelegate
-(void) complete:(STKHttpResult*) result
{
if (result.ok != YES){
[STKUtility alert:result.message];
return;
}
self.phoneArray = (NSMutableArray*)result.result;
for (STKPhoneHolder *holder in self.phoneArray) {
NSLog(#"%#", [holder description]);
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.phoneTable reloadData];
}
}
Or you can use performSelectorOnMainThread
[self.phoneTable performSelectorOnMainThread:#selector(reloadData)
withObject:nil
waitUntilDone:NO];
I am guessing STKSimpleHttpClient class is calling complete delegate function on different thread, all user interface interaction suppose to be called from main thread.
Try this code to see which thread you are in from the complete delegate function
NSLog(#" isMainThread(%d)", [NSThread isMainThread] );
check this. does the code load the tableview before you get information from web services. if so then write the statement [tableview Reload]; next to the web services information getting process. This will help
It's not necessary to specify the number of sections, but you might want to do it with this code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
I see you're using a Table View Controller, which already has a tableView reference self.tableView.
Like #rdelmar said, you could use that reference instead of your phoneTable:
[[self tableView] setDataSource:self];
[[self tableView] setDelegate:self];
[[self tableView] reloadData];

how to store NSString in Stack

I create stack class in my program that I want store NSString value in that.
this is stack class :
#interface Stack : NSObject
- (void)push:(id)obj;
- (id)pop;
- (BOOL)isEmpty;
#end
#implementation Stack
{
NSMutableArray *stack;
}
- (id)init
{
self = [super init];
if(self!= nil){
stack = [[NSMutableArray alloc] init];
}
return self;
}
- (void)push:(id)obj
{
[stack addObject:obj];
}
- (id)pop
{
id lastobj = [stack lastObject];
[stack removeLastObject];
return lastobj;
}
- (BOOL)isEmpty
{
return stack.count == 0;
}
#end
also I have another class with name : TableViewController
I want when to click on cell in TableViewController store cell's id that receive from URL
this is my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// I want that xCode value with xCode2 value push in stack
NSLog(#"Row in Tab : %d",indexPath.row);
if ([Folder containsObject:[All objectAtIndex:indexPath.row]]) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.1.%d/mamal/filemanager.php?dir=%#&folder=%d&id",IP,xCode,indexPath.row]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *err = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *responseString = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
xCode2 = responseString; //this is new cell's id.I want to push this value in stack
NSLog(#"xcode : %#", xCode2);
[self performSegueWithIdentifier:#"segue4" sender:self];
}
else
{
[self performSegueWithIdentifier:#"segue3" sender:self];
}
}
in top code I want when to click on cell push two value in stack (xCode & xCode2) but I dont know about to use of stack.
you need a variable that holds your stack.. i'd make it a member var:
#implementation TableViewController {
Stack *_stack;
}
...
then when the cell is clicked, push the value
...
if(!_stack)
_stack = [[Stack alloc] init];
[_stack push:xcode2];
...
In addition to what Daij-Djan has suggested, do the following:
#interface Stack : NSMutableArray
- (void)push:(id)obj;
- (id)pop;
- (BOOL)isEmpty;
#end
#implementation Stack
- (id)init
{
self = [super init];
if(self!= nil){
// Perform any initialization here. If you don't then there is no point in implementing init at all.
}
return self;
}
- (void)push:(id)obj
{
[self addObject:obj];
}
- (id)pop
{
id lastobj = [self lastObject];
[self removeLastObject];
return lastobj;
}
- (BOOL)isEmpty
{
return [self count] == 0;
}
#end

Resources