Discussion Forums  >  Uncategorized

Replies: 11    Views: 311

Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
07/11/11 01:18 PM (14 years ago)

Search - Binding to RSS Feed.

Am I correct in saying that the Search function uses a JSON feed and RSS uses a JSON feed, has anyone managed to modify/create a new search function for BT which utilises a RSS feed. I have a PHP script which delivers my RSS feed from a remote site and I would like to search this using the search function, I hope this makes sense. I think this facility would be useful to a lot of BT enthusiasts :-)
 
David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
like
07/14/11 02:43 AM (14 years ago)
Hmm... I think I understand your question. There are a few approaches to this. The idea is to 'post' the value in the search box in the mobile app the .PHP script before outputting the RSS data. The 'top' of the script grabs the value entered (it's appended to the end of the dataURL) then queries database or whatever then builds the RSS output. This means you'll need a way to: a) Append the entered value to the end of the dataURL before 'refreshing' b) Grabbing the value and building the results Appending the value and making the request are not part of the existing BT_screen_menuSearch.m file. But, lots and lots of the code is the same as the BT_screen_menuList.m file. This menuList file does request it's data from a URL. This means you could look at these two files and try to understand the differences then add a few methods in the search screen to faciliate the search. Techie? Totally. Doable? Yup. Just take some patience.
 
Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
like
07/14/11 03:36 AM (14 years ago)
I was thinking initially the RSS Feed might be a small list which would display in full as the RSS Feed does now and as with the RSS Search starts with a full list as you type in to the Search bar above it narrows the results. This would literally be a like for like as regards functionality, just wondering how to get the search to use thee RSS feed instead of the menu list. Your idea is great it takes it to another level, just trying to crawl before I can run so to speak.
 
David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
like
07/14/11 03:50 AM (14 years ago)
Ah...yes, makes sense. Something like this: RSS feed reads data. While it's reading the data, it 'builds' an array of titles to search. Next, a search box is used for the title bar. Next, the search box searches in the 'built' array of titles to narrow the list. A matter of combining the existing logic into a new and improved RSS screen.m. If you feel like tackling it, we'de be happy to add it to the list of things to add. As easy as it may be for us to do on this end, we have WAY to many things going on (Android is killing us!) to do it here until we get this darned list narrowed down. The list of to-do's is longer today than ever! LOL. So...see if you can a) Declare a new array property in the .h file (this is the existing RSS screen) b) Init this array in the .m to an 'empty array' This is a (NSMutableArray) b) Fill this array of title while the RSS feed is being parsed c) Add the search bar to the title (See how it's done in the search screen code, it's calling a function in the BT_layout.m file to fetch the navigation bar with the title) d) Add the search method declarations in the .h file, and the actual methods in the .m file (these will be nearly the same as the search screen) Little gotchas like adding the delegate methods for text boxes, etc. may hang you up. It's not too tough but may frustrate you trying? The idea is that the search function would rebuild the list as the title is searched, exactly like it does in the exisiting search screen.
 
Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
like
07/14/11 03:55 AM (14 years ago)
Many thanks I'll give it a go, if I get it working I'll send you the files :-)
 
Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
like
07/14/11 11:55 AM (14 years ago)
Ok, I've got declared new arrays in BT_screen_rssReader.h NSMutableArray *externalItems; UITextField *searchBox; NSTimer *searchTimer; BOOL isSearching; @property (nonatomic, retain) NSMutableArray *externalItems; @property (nonatomic, retain) UITextField *searchBox; @property (nonatomic, retain) NSTimer *searchTimer; @property (nonatomic) BOOL isSearching; In BT_screen_rssReader.h I have the following code: @synthesize externalItems, searchBox, searchTimer, isSearching; //view will appear -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [BT_debugger showIt:self:@viewWillAppear]; //flag this as the current screen *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.rootApp.currentScreenData = self.screenData; //setup navigation bar and background [BT_viewUtilities configureBackgroundAndNavBar:self:[self screenData]]; //custom view for title so we can insert a search bar UIView *titleView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 235, 40)] autorelease]; [titleView setTag:88]; titleView.backgroundColor = [UIColor clearColor]; //left view for search box UIImageView *searchImgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@search.png]] autorelease]; //search hint... NSString *searchHint = NSLocalizedString(@search, search...); if(![[BT_strings getStyleValueForScreen:self.screenData:@searchHint:@] isEqualToString:@]){ searchHint = [BT_strings getStyleValueForScreen:self.screenData:@searchHint:@]; } //if we already searched reset the search hint (happens when coming back to this screen) NSString *searchText = @; if([[BT_strings getPrefString:@currentSearchValue] length] > 0){ searchText = [BT_strings getPrefString:@currentSearchValue]; } //searchBar in title view searchBox = [[[UITextField alloc] initWithFrame:CGRectMake(0, 5, 210, 30)] autorelease]; searchBox.clearButtonMode = UITextFieldViewModeAlways; searchBox.tag = 199; searchBox.text = searchText; searchBox.placeholder = searchHint; searchBox.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; searchBox.textAlignment = UITextAlignmentLeft; searchBox.textColor = [UIColor blackColor]; searchBox.font = [UIFont systemFontOfSize:14]; searchBox.keyboardType = UIKeyboardTypeDefault; searchBox.borderStyle = UITextBorderStyleRoundedRect; searchBox.autocorrectionType = UITextAutocorrectionTypeNo; searchBox.autocapitalizationType = UITextAutocapitalizationTypeNone; searchBox.keyboardAppearance = UIKeyboardAppearanceAlert; searchBox.leftViewMode = UITextFieldViewModeAlways; searchBox.returnKeyType = UIReturnKeyDone; searchBox.leftView = searchImgView; searchBox.delegate = self; [searchBox addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; [titleView addSubview:searchBox]; self.navigationItem.titleView = titleView; //if we have not yet inited data.. if(self.didInit == 0){ [self performSelector:(@selector(loadData)) withObject:nil afterDelay:0.1]; } //show adView? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@includeAds:@0] isEqualToString:@1]){ [self showHideAdView]; } } I commented out the previous viewWillAppear so now I have an RSS Screen with Search Bar, no errors but I'm struggling with the hard part, shocker I know LOL. Now suffering from Can't see the wood for the trees syndrome, any pointers you can give me? And yes I realise I'm pushing things now :-)
 
David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
like
07/14/11 10:48 PM (14 years ago)
You're not pushing anything...no worries. Lets figure out how far you got and where you are now. So, if you have a screen setup, with the search bar, awesome. The next part will be to get the methods implemented that actually do the search. Baby steps I guess. It doesn't sound like you've told your RSS class file (BT_screen_rssReader) how to handle the interactions with the search/text entry box. Handles the interactions is done with 8 methods. textFieldDidBeginEditing textFieldDidEndEditing textFieldShouldBeginEditing textFieldShouldEndEditing textFieldShouldReturn textFieldShouldClear textFieldDidChange This means you'll need to get these methods created in the BT_screen_rssReader.m file. You can copy-n-paste the same methods from the BT_screen_menuSearch.m file. After doing that, have a look at each mehod, it's self explanatory for the most part. Each methods name suggests what interactions it handles. Look at the methods, one by one and try to understand how they call other methods. The textFieldDidChange method is where you'll have the most trouble ( I think ). This is where the array of values assigned to the list changes based on the searches. Your new array is called: externalItems. Maybe re-name it to filteredMenuItems so it matches the name of the array used in the textFieldDidChange method. This is the array you will fill with your values from the RSS feed. See if you can get this far without erros.
 
Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
like
07/15/11 02:47 AM (14 years ago)
Ok, this should give you a giggle. Baby Steps, I might need Pre-Birth Steps LOL :) Ok, despite having no errors yesterday in Xcode, if I ran the app and clicked in the text box I triggered the appDelegate function which halted the app, not surprisingly as the code wasn't complete. I have made a little headway, I have added the code you suggested, tried to do a little digging as to an error relating to: searchBox.delegate = self; which turned out to be the lack of declaration of UITextFieldDelegate for the BT_screen_rssReader : BT_viewController. I currently have the following error: BT_screen_rssReader.m: warning: Semantic Issue: Instance method '-textFieldDidChange:' not found (return type defaults to 'id') which relates to: [self textFieldDidChange:NULL]; Please see amendments commented as //Going-Viral below and any tips you can give I would be much appreciated, apologies for removing the disclaimer for both files, this is just for purposes of this post as I did't want this thread to turn in to War & Peace so to speak: #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import BT_viewController.h #import BT_item.h #import BT_header_image_view.h #import BT_rssParser.h #import BT_downloader.h @interface BT_screen_rssReader : BT_viewController <UITableViewDelegate, BT_downloadFileDelegate, BT_rssParserDelegate, UITableViewDataSource, //Added Going-Viral UITextFieldDelegate, // UIScrollViewDelegate>{ NSMutableArray *menuItems; //Added Going-Viral NSMutableArray *filteredMenuItems; NSMutableArray *displayMenuItems; // NSArray *rssItems; UITableView *myTableView; BT_header_image_view *headerImageView; BT_downloader *downloader; NSString *saveAsFileName; BOOL isLoading; NSOperationQueue *queue; int didInit; //Added Going-Viral UITextField *searchBox; NSTimer *searchTimer; BOOL isSearching; // element names for parser */ NSString *xmlItemTagName; NSString *xmlItemTitleName; NSString *xmlItemDescriptionName; NSString *xmlItemLinkName; NSString *xmlItemImageName; NSString *xmlAppendValueToLinkURL; } @property (nonatomic, retain) NSMutableArray *menuItems; //Added Going-Viral @property (nonatomic, retain) NSMutableArray *filteredMenuItems; @property (nonatomic, retain) NSMutableArray *displayMenuItems; // @property (nonatomic, retain) NSArray *rssItems; @property (nonatomic, retain) UITableView *myTableView; @property (nonatomic, retain) BT_header_image_view *headerImageView; @property (nonatomic, retain) NSString *saveAsFileName; @property (nonatomic, retain) BT_downloader *downloader; @property (nonatomic) BOOL isLoading; @property (nonatomic) int didInit; //Added Going-Viral @property (nonatomic, retain) UITextField *searchBox; @property (nonatomic, retain) NSTimer *searchTimer; @property (nonatomic) BOOL isSearching; // @property (nonatomic, retain) NSOperationQueue *queue; @property (nonatomic, retain) NSString *xmlItemTagName; @property (nonatomic, retain) NSString *xmlItemTitleName; @property (nonatomic, retain) NSString *xmlItemDescriptionName; @property (nonatomic, retain) NSString *xmlItemLinkName; @property (nonatomic, retain) NSString *xmlItemImageName; @property (nonatomic, retain) NSString *xmlAppendValueToLinkURL; -(void)headerImageTap; -(void)loadData; -(void)downloadData; -(void)layoutScreen; -(void)parseScreenData:(NSString *)theData; -(void)checkIsLoading; @end BT_screen_rssReader.m #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #import <CFNetwork/CFNetwork.h> #import JSON.h #import *****_appDelegate.h #import BT_fileManager.h #import BT_color.h #import BT_strings.h #import BT_viewUtilities.h #import BT_downloader.h #import BT_item.h #import BT_debugger.h #import BT_viewControllerManager.h #import BT_cell_menuList.h #import BT_header_image_view.h #import BT_rssParser.h #import BT_rssItem.h #import BT_screen_rssReader.h @implementation BT_screen_rssReader //Modified Going-Viral @synthesize menuItems, filteredMenuItems, displayMenuItems, rssItems, myTableView, didInit; @synthesize saveAsFileName, downloader, isLoading, headerImageView, queue; @synthesize xmlItemTagName, xmlItemTitleName, xmlItemDescriptionName, xmlItemLinkName, xmlItemImageName; @synthesize xmlAppendValueToLinkURL; @synthesize searchBox, searchTimer, isSearching; //viewDidLoad -(void)viewDidLoad{ [BT_debugger showIt:self:@viewDidLoad]; [super viewDidLoad]; //init screen properties [self setDidInit:0]; //flag not loading [self setIsLoading:FALSE]; //appDelegate *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; //////////////////////////////////////////////////////////////////////////////////////// //build the table that holds the menu items. self.myTableView = [BT_viewUtilities getTableViewForScreen:[self screenData]]; self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.myTableView setDataSource:self]; [self.myTableView setDelegate:self]; //prevent scrolling? if([[BT_strings getStyleValueForScreen:self.screenData:@preventAllScrolling:@] isEqualToString:@1]){ [self.myTableView setScrollEnabled:FALSE]; } [self.view addSubview:myTableView]; //fill the element names for parser object self.xmlItemTagName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemTagName:@item]; self.xmlItemTitleName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemTitleName:@title]; self.xmlItemDescriptionName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemDescriptionName:@description]; self.xmlItemLinkName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemLinkName:@link]; self.xmlItemImageName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemImageName:@image]; self.xmlAppendValueToLinkURL = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlAppendValueToLinkURL:@]; //////////////////////////////////////////////////////////////////////////////////////// //if we have a headerImageName, create a BT_image_header_view with this screens data // this is added before the table so the table is on top of it. BOOL addHeaderImage = FALSE; NSString *headerImageName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageNameSmallDevice:@]; NSString *headerImageURL = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageURLSmallDevice:@]; if([appDelegate.rootApp.rootDevice isIPad]){ //use large device header image headerImageName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageNameLargeDevice:@]; headerImageURL = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageURLLargeDevice:@]; } if([headerImageName length] > 3 || [headerImageURL length] > 3){ addHeaderImage = TRUE; } if(addHeaderImage){ //create an image view from the screen data..It will size itself. headerImageView = [[BT_header_image_view alloc] initWithScreenData:self.screenData]; headerImageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; //does header image scroll with the table? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageScrollWithList:@1] isEqualToString:@0]){ //add as sub-view [self.view addSubview:headerImageView]; }else{ //add as table view header [self.myTableView setTableHeaderView:headerImageView]; } [headerImageView release]; } //end if using header image //create adView? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@includeAds:@0] isEqualToString:@1]){ [self createAdBannerView]; } } //Modified Going-Viral //shows nav bar -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [BT_debugger showIt:self:@viewWillAppear]; //flag this as the current screen *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.rootApp.currentScreenData = self.screenData; //setup navigation bar and background [BT_viewUtilities configureBackgroundAndNavBar:self:[self screenData]]; //custom view for title so we can insert a search bar UIView *titleView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 235, 40)] autorelease]; [titleView setTag:88]; titleView.backgroundColor = [UIColor clearColor]; //left view for search box UIImageView *searchImgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@search.png]] autorelease]; //search hint... NSString *searchHint = NSLocalizedString(@search, search...); if(![[BT_strings getStyleValueForScreen:self.screenData:@searchHint:@] isEqualToString:@]){ searchHint = [BT_strings getStyleValueForScreen:self.screenData:@searchHint:@]; } //if we already searched reset the search hint (happens when coming back to this screen) NSString *searchText = @; if([[BT_strings getPrefString:@currentSearchValue] length] > 0){ searchText = [BT_strings getPrefString:@currentSearchValue]; } //searchBar in title view searchBox = [[[UITextField alloc] initWithFrame:CGRectMake(0, 5, 210, 30)] autorelease]; searchBox.clearButtonMode = UITextFieldViewModeAlways; searchBox.tag = 199; searchBox.text = searchText; searchBox.placeholder = searchHint; searchBox.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; searchBox.textAlignment = UITextAlignmentLeft; searchBox.textColor = [UIColor blackColor]; searchBox.font = [UIFont systemFontOfSize:14]; searchBox.keyboardType = UIKeyboardTypeDefault; searchBox.borderStyle = UITextBorderStyleRoundedRect; searchBox.autocorrectionType = UITextAutocorrectionTypeNo; searchBox.autocapitalizationType = UITextAutocapitalizationTypeNone; searchBox.keyboardAppearance = UIKeyboardAppearanceAlert; searchBox.leftViewMode = UITextFieldViewModeAlways; searchBox.returnKeyType = UIReturnKeyDone; searchBox.leftView = searchImgView; searchBox.delegate = self; [searchBox addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; [titleView addSubview:searchBox]; self.navigationItem.titleView = titleView; //if we have not yet inited data.. if(self.didInit == 0){ [self performSelector:(@selector(loadData)) withObject:nil afterDelay:0.1]; } //show adView? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@includeAds:@0] isEqualToString:@1]){ [self showHideAdView]; } } //header image tapped -(void)headerImageTap{ [BT_debugger showIt:self:@headerImageTap]; //appDelegate *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; //get possible itemId of the screen to load NSString *loadScreenItemId = [BT_strings getJsonPropertyValue:screenData.jsonVars:@headerImageTapLoadScreenItemId:@]; //get possible nickname of the screen to load NSString *loadScreenNickname = [BT_strings getJsonPropertyValue:screenData.jsonVars:@headerImageTapLoadScreenNickname:@]; //bail if load screen = none if([loadScreenItemId isEqualToString:@none]){ return; } //check for loadScreenWithItemId THEN loadScreenWithNickname THEN loadScreenObject BT_item *screenObjectToLoad = nil; if([loadScreenItemId length] > 1){ screenObjectToLoad = [appDelegate.rootApp getScreenDataByItemId:loadScreenItemId]; }else{ if([loadScreenNickname length] > 1){ screenObjectToLoad = [appDelegate.rootApp getScreenDataByNickname:loadScreenNickname]; }else{ if([screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject]){ screenObjectToLoad = [[BT_item alloc] init]; [screenObjectToLoad setItemId:[[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject] objectForKey:@itemId]]; [screenObjectToLoad setItemNickname:[[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject] objectForKey:@itemNickname]]; [screenObjectToLoad setItemType:[[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject] objectForKey:@itemType]]; [screenObjectToLoad setJsonVars:[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject]]; } } } //load next screen if it's not nil if(screenObjectToLoad != nil){ //build a temp menu-item to pass to screen load method. We need this because the transition type is in the menu-item BT_item *tmpMenuItem = [[BT_item alloc] init]; //build an NSDictionary of values for the jsonVars property NSDictionary *tmpDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @unused, @itemId, [self.screenData.jsonVars objectForKey:@headerImageTapLoadScreenTransitionType], @transitionType, nil]; [tmpMenuItem setJsonVars:tmpDictionary]; [tmpMenuItem setItemId:@0]; //load the next screen [BT_viewControllerManager handleTapToLoadScreen:[self screenData]:tmpMenuItem:screenObjectToLoad]; [tmpMenuItem release]; [screenObjectToLoad release]; }else{ //show message [BT_debugger showIt:self:[NSString stringWithFormat:@%@,NSLocalizedString(@menuTapError,@The application doesn't know how to handle this action?)]]; } } //load data -(void)loadData{ [BT_debugger showIt:self:@loadData]; //show progress [self showProgress]; //prevent interaction during operation [myTableView setScrollEnabled:FALSE]; [myTableView setAllowsSelection:FALSE]; Screen Data scenarios -------------------------------- a) No dataURL is provided in the screen data - use the info configured in the screen data b) A dataURL is provided and cacheWebData is 0. download button data everytime, do not cache c) A dataURL is provided and cacheWebData is 1. download button data, cache for offline use */ self.saveAsFileName = [NSString stringWithFormat:@screenData_%@.xml, [screenData itemId]]; //flag in progress self.isLoading = TRUE; //we must have a dataURL if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@] length] > 3){ //look for previously used version... if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ [BT_debugger showIt:self:@using cached version of screen data]; NSString *staleData = [BT_fileManager readTextFileFromCacheWithEncoding:self.saveAsFileName:-1]; [self parseScreenData:staleData]; }else{ [self downloadData]; } } } //download data -(void)downloadData{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloading screen data from: %@, [self saveAsFileName]]]; //flag this as the current screen *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.rootApp.currentScreenData = self.screenData; //show progress [self showProgress]; //prevent interaction during operation [myTableView setScrollEnabled:FALSE]; [myTableView setAllowsSelection:FALSE]; NSString *tmpURL = @; if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@] length] > 3){ //merge url variables tmpURL = [BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@]; tmpURL = [tmpURL stringByReplacingOccurrencesOfString:@[screenId] withString:[self.screenData itemId]]; ///merge possible variables in URL NSString *useURL = [BT_strings mergeBTVariablesInString:tmpURL]; NSString *escapedUrl = [useURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //fire downloader to fetch and results downloader = [[BT_downloader alloc] init]; [downloader setSaveAsFileName:[self saveAsFileName]]; [downloader setSaveAsFileType:@text]; [downloader setUrlString:escapedUrl]; [downloader setDelegate:self]; [downloader downloadFile]; } } //parse screen data -(void)parseScreenData:(NSString *)theData{ [BT_debugger showIt:self:@parseScreenData]; //prevent interaction during operation [myTableView setScrollEnabled:FALSE]; [myTableView setAllowsSelection:FALSE]; //the screen data is an XML string... fire the xml parser in the background... //it will tell us it's complete. //convert NSString to NSData for parser. NSData *tmpData = [theData dataUsingEncoding:NSUTF8StringEncoding]; //create the queue to run our parse operation self.queue = [[NSOperationQueue alloc] init]; //pass the data to the parser.. BT_rssParser *parser = [[BT_rssParser alloc] initWithData:tmpData delegate:self]; [parser setXmlItemTagName:self.xmlItemTagName]; [parser setXmlItemTitleName:self.xmlItemTitleName]; [parser setXmlItemDescriptionName:self.xmlItemDescriptionName]; [parser setXmlItemLinkName:self.xmlItemLinkName]; [parser setXmlItemImageName:self.xmlItemImageName]; [parser setXmlAppendValueToLinkURL:self.xmlAppendValueToLinkURL]; //tell parser what elements to look for... [parser setItemsToParse]; //start the parse operation. didFinishParsing is sent an array by the parser when done [queue addOperation:parser]; [parser release]; } //build screen -(void)layoutScreen{ [BT_debugger showIt:self:@layoutScreen]; //reload table [self.myTableView reloadData]; //hideProgress [self hideProgress]; //trigger the search (needed if we have a previously entered value) [self textFieldDidChange:NULL]; //enable interaction again (unless owner turned it off) if([[BT_strings getStyleValueForScreen:self.screenData:@preventAllScrolling:@] isEqualToString:@1]){ [self.myTableView setScrollEnabled:FALSE]; }else{ [myTableView setScrollEnabled:TRUE]; } [myTableView setAllowsSelection:TRUE]; //flag done loading self.isLoading = FALSE; } ////////////////////////////////////////////////////////////// //UITableView delegate methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } // number of rows - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.menuItems count]; } //table view cells - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @Cell; BT_cell_menuList *cell = (BT_cell_menuList *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { //init our custom cell cell = [[[BT_cell_menuList alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } //this menu item BT_item *thisMenuItemData = [self.menuItems objectAtIndex:indexPath.row]; [cell setTheMenuItemData:thisMenuItemData]; [cell setTheParentMenuScreenData:[self screenData]]; [cell configureCell]; //custom background view. Must be done here so we can retain the round corners if this is a round table //this method refers to this screen's listRowBackgroundColor and it's position in the tap. Top and //bottom rows may need to be rounded if this is screen uses listStyle:round [cell setBackgroundView:[BT_viewUtilities getCellBackgroundForListRow:[self screenData]:indexPath:[self.menuItems count]]]; //return return cell; } //on row select - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [BT_debugger showIt:self:@didSelectRowAtIndexPath]; //get the rss BT_rssItem *theRssItem = [self.rssItems objectAtIndex:indexPath.row]; //pass this menu item to the tapForMenuItem method BT_item *thisMenuItem = [self.menuItems objectAtIndex:indexPath.row]; //build a BT_screen_webView to load. Give it an itemId that matches the menuItems //loadScreenWithItemId value so we BT_viewControllManager can find it. NSString *theDynamicScreenItemId = [thisMenuItem itemId]; BT_item *theDynamicScreenObjectToLoad = [[BT_item alloc] init]; [theDynamicScreenObjectToLoad setItemId:theDynamicScreenItemId]; [theDynamicScreenObjectToLoad setItemType:@BT_screen_webView]; //dictionary for menu row tapped NSDictionary *menuDict = [NSDictionary dictionaryWithObjectsAndKeys: theDynamicScreenItemId, @itemId, @BT_menuItem, @itemType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemRowTapTransitionType:@], @transitionType, nil]; [thisMenuItem setJsonVars:menuDict]; //create a dictionary for the dynamic screen. NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: theDynamicScreenItemId, @itemId, @BT_screen_webView, @itemType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@navBarTitleText:@], @navBarTitleText, theRssItem.linkURL, @dataURL, //these are the optional properties the BT_screen_webView will look for [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarBackgroundColor:@], @navBarBackgroundColor, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarStyle:@], @navBarStyle, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemToolBarStyle:@], @toolBarStyle, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemBackButtonText:@], @navBarBackButtonText, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemBackgroundColor:@], @backgroundColor, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemShowBrowserBarBack:@0], @showBrowserBarBack, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemShowBrowserRefresh:@0], @showBrowserBarRefresh, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemShowBrowserBarLaunchInNativeApp:@0], @showBrowserBarLaunchInNativeApp, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarRightButtonType:@], @navBarRightButtonType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarRightButtonTapLoadScreenItemId:@], @navBarRightButtonTapLoadScreenItemId, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemRightButtonTapTransitionType:@], @navBarRightButtonTapTransitionType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemHideBottomTabBarWhenScreenLoads:@], @hideBottomTabBarWhenScreenLoads, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioFileName:@], @audioFileName, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioFileURL:@], @audioFileURL, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioStopsOnScreenExit:@0], @audioStopsOnScreenExit, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioNumberOfLoops:@0], @audioNumberOfLoops, nil]; //set the dictionary for the dynamic screen [theDynamicScreenObjectToLoad setJsonVars:dict]; //BT_viewControllerManager will launch the next screen [BT_viewControllerManager handleTapToLoadScreen:[self screenData]:thisMenuItem:theDynamicScreenObjectToLoad]; //clean up [theDynamicScreenObjectToLoad release]; theDynamicScreenObjectToLoad = nil; } ////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //parser delegate methods //did finish parsing -(void)didFinishParsing:(NSArray *)loadedRssItems{ [BT_debugger showIt:self:@didFinishParsing]; //rememeber the rssItems self.rssItems = loadedRssItems; //arrays for menu items self.menuItems = [[NSMutableArray alloc] init]; //Added Going-Viral self.filteredMenuItems = [[NSMutableArray alloc] init]; self.displayMenuItems = [[NSMutableArray alloc] init]; // //loop through the loaded rssItems and a menuItem for each... int i = 0; for(i = 0; i < [loadedRssItems count]; i++){ BT_rssItem *thisRssItem = [loadedRssItems objectAtIndex:i]; NSString* theTitle = [NSString stringWithFormat:@%@, thisRssItem.title]; NSString* theDescription = [NSString stringWithFormat:@%@, thisRssItem.description]; NSString* theIconURL = @; NSString *theIconName = @; if([thisRssItem.imageURL length] > 0){ theIconURL = [NSString stringWithFormat:@%@, thisRssItem.imageURL]; theIconName = [theIconURL lastPathComponent]; } //properties for the menu item NSString *menuItemId = [NSString stringWithFormat:@rss_%@_%d, [self.screenData itemId], i]; NSString *loadScreenWithItemId = menuItemId; NSString *transitionType = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemTransitionType:@]; NSString *rowAccessoryType = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAccessoryType:@]; NSString *soundEffectFileName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemSoundEffectFileName:@]; //create a dictionary for the BT_item - DO NOT CACHE WEB IMAGES NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: @0, @cacheWebImages, theTitle, @titleText, theDescription, @descriptionText, loadScreenWithItemId, @loadScreenWithItemId, theIconURL, @iconURL, theIconName, @iconName, transitionType, @transitionType, soundEffectFileName, @soundEffectFileName, rowAccessoryType, @rowAccessoryType, nil]; //create a menu item from the data BT_item *thisMenuItemData = [[BT_item alloc] init]; [thisMenuItemData setJsonVars:dict]; [thisMenuItemData setItemId:menuItemId]; [thisMenuItemData setItemType:@BT_menuItem]; [self.menuItems addObject:thisMenuItemData]; [thisMenuItemData release]; } [self performSelectorOnMainThread:@selector(layoutScreen) withObject:nil waitUntilDone:NO]; self.queue = nil; } //parse error -(void)parseErrorOccurred:(NSError *)error{ [BT_debugger showIt:self:[NSString stringWithFormat:@parseErrorOccurred: %@, [error localizedDescription]]]; } //allows us to check to see if we pulled-down to refresh -(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ [self checkIsLoading]; } -(void)checkIsLoading{ if(isLoading){ return; }else{ //how far down did we pull? double down = myTableView.contentOffset.y; if(down <= -65){ if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@1] length] > 3){ [self downloadData]; } } } } ////////////////////////////////////////////////////////////////////////////////////////////////// //downloader delegate methods -(void)downloadFileStarted:(NSString *)message{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloadFileStarted: %@, message]]; } -(void)downloadFileInProgress:(NSString *)message{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloadFileInProgress: %@, message]]; if(progressView != nil){ UILabel *tmpLabel = (UILabel *)[progressView.subviews objectAtIndex:2]; [tmpLabel setText:message]; } } -(void)downloadFileCompleted:(NSString *)message{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloadFileCompleted: %@, message]]; [self hideProgress]; //if message contains error, look for previously cached data... if([message rangeOfString:@ERROR options:NSCaseInsensitiveSearch].location != NSNotFound){ [BT_debugger showIt:self:[NSString stringWithFormat:@download error: There was a problem downloading data from the internet.%@, message]]; //NSLog(@Message: %@, message); //show alert [self showAlert:nil:NSLocalizedString(@downloadError, @There was a problem downloading some data. Check your internet connection then try again.):0]; //show local data if it exists if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ //use stale data if we have it NSString *staleData = [BT_fileManager readTextFileFromCacheWithEncoding:self.saveAsFileName:-1]; [BT_debugger showIt:self:[NSString stringWithFormat:@building screen from stale configuration data saved at: @, [self saveAsFileName]]]; [self parseScreenData:staleData]; }else{ //no local data? [BT_debugger showIt:self:[NSString stringWithFormat:@There is no local data availalbe for this screen?%@, @]]; } }else{ //parse previously saved data if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ [BT_debugger showIt:self:[NSString stringWithFormat:@parsing downloaded screen data.%@, @]]; NSString *downloadedData = [BT_fileManager readTextFileFromCacheWithEncoding:[self saveAsFileName]:-1]; [self parseScreenData:downloadedData]; }else{ [BT_debugger showIt:self:[NSString stringWithFormat:@Error caching downloaded file: %@, [self saveAsFileName]]]; //show alert [self showAlert:nil:NSLocalizedString(@appDownloadError, @There was a problem saving some data downloaded from the internet.):0]; } } } //Added Going-Viral ////////////////////////////////////////////// //search text delegate methods.. //begin edit - (void)textFieldDidBeginEditing:(UITextField *)textField{ //NSLog(@textFieldDidBeginEditing); } //end edit -(void)textFieldDidEndEditing:(UITextField *)textField{ //NSLog(@textFieldDidEndEditing); //remember the searched value [BT_strings setPrefString:@currentSearchValue:[searchBox text]]; } //should begin editing -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ //NSLog(@textFieldShouldBeginEditing); //deselect previously selected row NSIndexPath* selection = [myTableView indexPathForSelectedRow]; if(selection){ [myTableView deselectRowAtIndexPath:selection animated:NO]; } return YES; } //should end editing -(BOOL)textFieldShouldEndEditing:(UITextField *)textField{ //NSLog(@textFieldShouldEndEditing); return YES; } //return tapped -(BOOL)textFieldShouldReturn:(UITextField *)textField{ //NSLog(@textFieldShouldReturn); [self.searchBox resignFirstResponder]; return TRUE; } //should clear -(BOOL)textFieldShouldClear:(UITextField *)textField{ //NSLog(@textFieldShouldClear); //forward event to textFieldDidChange [self textFieldDidChange:NULL]; return YES; } //text field changed -(void)textFieldDidChange:(id)sender{ //NSLog(@textFieldDidChange); //remove filtered items [filteredMenuItems removeAllObjects]; //remember the searched value for next time (in case we leave the screen and come back) [BT_strings setPrefString:@currentSearchValue:[searchBox text]]; //search on every character... if([searchBox.text length] > 0){ //loop through items in menu data... for(int i = 0; i < [self.menuItems count]; i++){ BT_item *thisItem = [self.menuItems objectAtIndex:i]; NSRange r = [[thisItem.jsonVars objectForKey:@titleText] rangeOfString:searchBox.text options:NSCaseInsensitiveSearch]; if(r.location != NSNotFound){ if(r.location == 0){ [self.filteredMenuItems addObject:thisItem]; } } } } //show the filtered list if searching... if([searchBox.text length] > 0){ displayMenuItems = self.filteredMenuItems; }else{ displayMenuItems = self.menuItems; } //reload [myTableView reloadData]; } //dealloc -(void)dealloc{ [screenData release]; screenData = nil; [progressView release]; progressView = nil; [menuItems release]; menuItems = nil; [rssItems release]; rssItems = nil; [myTableView release]; myTableView = nil; [headerImageView release]; headerImageView = nil; [saveAsFileName release]; saveAsFileName = nil; [downloader release]; downloader = nil; [xmlItemTagName release]; xmlItemTagName = nil; [xmlItemTitleName release]; xmlItemTitleName = nil; [xmlItemDescriptionName release]; xmlItemDescriptionName = nil; [xmlItemLinkName release]; xmlItemLinkName = nil; [xmlItemImageName release]; xmlItemImageName = nil; [xmlAppendValueToLinkURL release]; xmlAppendValueToLinkURL = nil; [super dealloc]; } @end
 
David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
like
07/15/11 06:46 PM (14 years ago)
Myterious. You could try declaring (some call this describing, or interfacing) the Text Field Methods you have in the .m file. You do this in the .h file. There should be a few methods already described in the .h file. This sometimes helps the compiler understand that you've added method to the .m file. Confusing for sure but worth a shot. If the RSS class is not implementing the UITextFieldDelgate protocol (it is) then the methods should fire when you interact with the search box. I'm thinking this will cure the Symantec issue and we'll see what other issues exist after that.
 
Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
like
07/16/11 12:18 PM (14 years ago)
Will have another look, I'm new to Objective-C, not programming, but this language is something else. Just hoping I get a space on a course for Objective-C and Cocoa soon :-)
 
Going-Viral
Apple Fan
Profile
Posts: 120
Reg: Jun 13, 2011
Doncaster
1,200
like
07/17/11 05:09 AM (14 years ago)
Ok, I got rid of the wood for the tree scenario, took a step back and start again. This time I have got all elements added yet this time with no errors. The app loads, doesn't crash, displays the search bar and allows me to type into the search bar without the appDelegate function kicking in. I'm guessing now, that the reason the search functionality isn't working is that the search box isn't binding to the RSS feed. Could you please nudge me in the right direction? Please see my code below: // BT_screen_rssReader.h: #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import BT_viewController.h #import BT_item.h #import BT_header_image_view.h #import BT_rssParser.h #import BT_downloader.h @interface BT_screen_rssReader : BT_viewController <UITableViewDelegate, BT_downloadFileDelegate, BT_rssParserDelegate, UITableViewDataSource, UITextFieldDelegate, UIScrollViewDelegate>{ NSMutableArray *menuItems; //Added Going_Viral NSMutableArray *filteredMenuItems; NSMutableArray *displayMenuItems; // NSArray *rssItems; UITableView *myTableView; BT_header_image_view *headerImageView; BT_downloader *downloader; NSString *saveAsFileName; BOOL isLoading; NSOperationQueue *queue; int didInit; //Added Going-Viral UITextField *searchBox; NSTimer *searchTimer; BOOL isSearching; element names for parser */ NSString *xmlItemTagName; NSString *xmlItemTitleName; NSString *xmlItemDescriptionName; NSString *xmlItemLinkName; NSString *xmlItemImageName; NSString *xmlAppendValueToLinkURL; } @property (nonatomic, retain) NSMutableArray *menuItems; //Added Going-Viral @property (nonatomic, retain) NSMutableArray *filteredMenuItems; @property (nonatomic, retain) NSMutableArray *displayMenuItems; // @property (nonatomic, retain) NSArray *rssItems; @property (nonatomic, retain) UITableView *myTableView; @property (nonatomic, retain) BT_header_image_view *headerImageView; @property (nonatomic, retain) NSString *saveAsFileName; @property (nonatomic, retain) BT_downloader *downloader; @property (nonatomic) BOOL isLoading; @property (nonatomic) int didInit; //Added Going-Viral @property (nonatomic, retain) UITextField *searchBox; @property (nonatomic, retain) NSTimer *searchTimer; @property (nonatomic) BOOL isSearching; // @property (nonatomic, retain) NSOperationQueue *queue; @property (nonatomic, retain) NSString *xmlItemTagName; @property (nonatomic, retain) NSString *xmlItemTitleName; @property (nonatomic, retain) NSString *xmlItemDescriptionName; @property (nonatomic, retain) NSString *xmlItemLinkName; @property (nonatomic, retain) NSString *xmlItemImageName; @property (nonatomic, retain) NSString *xmlAppendValueToLinkURL; -(void)headerImageTap; -(void)loadData; -(void)downloadData; -(void)layoutScreen; -(void)parseScreenData:(NSString *)theData; -(void)checkIsLoading; //Added Going-Viral -(void)textFieldDidChange:(id)sender; // @end // End of BT_screen_rssReader.h // BT_screen_rssReader.m: #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #import <CFNetwork/CFNetwork.h> #import JSON.h #import *****_appDelegate.h #import BT_fileManager.h #import BT_color.h #import BT_strings.h #import BT_viewUtilities.h #import BT_downloader.h #import BT_item.h #import BT_debugger.h #import BT_viewControllerManager.h #import BT_cell_menuList.h #import BT_header_image_view.h #import BT_rssParser.h #import BT_rssItem.h #import BT_screen_rssReader.h @implementation BT_screen_rssReader @synthesize menuItems, rssItems, myTableView, didInit; @synthesize saveAsFileName, downloader, isLoading, headerImageView, queue; //Added Going-Viral @synthesize filteredMenuItems, displayMenuItems, searchBox, searchTimer, isSearching; // @synthesize xmlItemTagName, xmlItemTitleName, xmlItemDescriptionName, xmlItemLinkName, xmlItemImageName; @synthesize xmlAppendValueToLinkURL; //viewDidLoad -(void)viewDidLoad{ [BT_debugger showIt:self:@viewDidLoad]; [super viewDidLoad]; //init screen properties [self setDidInit:0]; //flag not loading [self setIsLoading:FALSE]; //appDelegate *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; //////////////////////////////////////////////////////////////////////////////////////// //build the table that holds the menu items. self.myTableView = [BT_viewUtilities getTableViewForScreen:[self screenData]]; self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.myTableView setDataSource:self]; [self.myTableView setDelegate:self]; //prevent scrolling? if([[BT_strings getStyleValueForScreen:self.screenData:@preventAllScrolling:@] isEqualToString:@1]){ [self.myTableView setScrollEnabled:FALSE]; } [self.view addSubview:myTableView]; //fill the element names for parser object self.xmlItemTagName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemTagName:@item]; self.xmlItemTitleName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemTitleName:@title]; self.xmlItemDescriptionName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemDescriptionName:@description]; self.xmlItemLinkName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemLinkName:@link]; self.xmlItemImageName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlItemImageName:@image]; self.xmlAppendValueToLinkURL = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@xmlAppendValueToLinkURL:@]; //////////////////////////////////////////////////////////////////////////////////////// //if we have a headerImageName, create a BT_image_header_view with this screens data // this is added before the table so the table is on top of it. BOOL addHeaderImage = FALSE; NSString *headerImageName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageNameSmallDevice:@]; NSString *headerImageURL = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageURLSmallDevice:@]; if([appDelegate.rootApp.rootDevice isIPad]){ //use large device header image headerImageName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageNameLargeDevice:@]; headerImageURL = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageURLLargeDevice:@]; } if([headerImageName length] > 3 || [headerImageURL length] > 3){ addHeaderImage = TRUE; } if(addHeaderImage){ //create an image view from the screen data..It will size itself. headerImageView = [[BT_header_image_view alloc] initWithScreenData:self.screenData]; headerImageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; //does header image scroll with the table? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@headerImageScrollWithList:@1] isEqualToString:@0]){ //add as sub-view [self.view addSubview:headerImageView]; }else{ //add as table view header [self.myTableView setTableHeaderView:headerImageView]; } [headerImageView release]; } //end if using header image //create adView? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@includeAds:@0] isEqualToString:@1]){ [self createAdBannerView]; } } //Commented Out Going-Viral //shows nav bar -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [BT_debugger showIt:self:@viewWillAppear]; //flag this as the current screen *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.rootApp.currentScreenData = self.screenData; //setup navigation bar and background [BT_viewUtilities configureBackgroundAndNavBar:self:[self screenData]]; //if we have not yet inited data.. if(self.didInit == 0){ [self performSelector:(@selector(loadData)) withObject:nil afterDelay:0.1]; [self setDidInit:1]; } //show adView? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@includeAds:@0] isEqualToString:@1]){ [self showHideAdView]; } } */ // //Added Going-Viral //view will appear -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [BT_debugger showIt:self:@viewWillAppear]; //flag this as the current screen *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.rootApp.currentScreenData = self.screenData; //setup navigation bar and background [BT_viewUtilities configureBackgroundAndNavBar:self:[self screenData]]; //custom view for title so we can insert a search bar UIView *titleView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 235, 40)] autorelease]; [titleView setTag:88]; titleView.backgroundColor = [UIColor clearColor]; //left view for search box UIImageView *searchImgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@search.png]] autorelease]; //search hint... NSString *searchHint = NSLocalizedString(@search, search...); if(![[BT_strings getStyleValueForScreen:self.screenData:@searchHint:@] isEqualToString:@]){ searchHint = [BT_strings getStyleValueForScreen:self.screenData:@searchHint:@]; } //if we already searched reset the search hint (happens when coming back to this screen) NSString *searchText = @; if([[BT_strings getPrefString:@currentSearchValue] length] > 0){ searchText = [BT_strings getPrefString:@currentSearchValue]; } //searchBar in title view searchBox = [[[UITextField alloc] initWithFrame:CGRectMake(0, 5, 210, 30)] autorelease]; searchBox.clearButtonMode = UITextFieldViewModeAlways; searchBox.tag = 199; searchBox.text = searchText; searchBox.placeholder = searchHint; searchBox.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; searchBox.textAlignment = UITextAlignmentLeft; searchBox.textColor = [UIColor blackColor]; searchBox.font = [UIFont systemFontOfSize:14]; searchBox.keyboardType = UIKeyboardTypeDefault; searchBox.borderStyle = UITextBorderStyleRoundedRect; searchBox.autocorrectionType = UITextAutocorrectionTypeNo; searchBox.autocapitalizationType = UITextAutocapitalizationTypeNone; searchBox.keyboardAppearance = UIKeyboardAppearanceAlert; searchBox.leftViewMode = UITextFieldViewModeAlways; searchBox.returnKeyType = UIReturnKeyDone; searchBox.leftView = searchImgView; searchBox.delegate = self; [searchBox addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; [titleView addSubview:searchBox]; self.navigationItem.titleView = titleView; //if we have not yet inited data.. if(self.didInit == 0){ [self performSelector:(@selector(loadData)) withObject:nil afterDelay:0.1]; } //show adView? if([[BT_strings getJsonPropertyValue:self.screenData.jsonVars:@includeAds:@0] isEqualToString:@1]){ [self showHideAdView]; } } // //header image tapped -(void)headerImageTap{ [BT_debugger showIt:self:@headerImageTap]; //appDelegate *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; //get possible itemId of the screen to load NSString *loadScreenItemId = [BT_strings getJsonPropertyValue:screenData.jsonVars:@headerImageTapLoadScreenItemId:@]; //get possible nickname of the screen to load NSString *loadScreenNickname = [BT_strings getJsonPropertyValue:screenData.jsonVars:@headerImageTapLoadScreenNickname:@]; //bail if load screen = none if([loadScreenItemId isEqualToString:@none]){ return; } //check for loadScreenWithItemId THEN loadScreenWithNickname THEN loadScreenObject BT_item *screenObjectToLoad = nil; if([loadScreenItemId length] > 1){ screenObjectToLoad = [appDelegate.rootApp getScreenDataByItemId:loadScreenItemId]; }else{ if([loadScreenNickname length] > 1){ screenObjectToLoad = [appDelegate.rootApp getScreenDataByNickname:loadScreenNickname]; }else{ if([screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject]){ screenObjectToLoad = [[BT_item alloc] init]; [screenObjectToLoad setItemId:[[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject] objectForKey:@itemId]]; [screenObjectToLoad setItemNickname:[[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject] objectForKey:@itemNickname]]; [screenObjectToLoad setItemType:[[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject] objectForKey:@itemType]]; [screenObjectToLoad setJsonVars:[screenData.jsonVars objectForKey:@headerImageTapLoadScreenObject]]; } } } //load next screen if it's not nil if(screenObjectToLoad != nil){ //build a temp menu-item to pass to screen load method. We need this because the transition type is in the menu-item BT_item *tmpMenuItem = [[BT_item alloc] init]; //build an NSDictionary of values for the jsonVars property NSDictionary *tmpDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @unused, @itemId, [self.screenData.jsonVars objectForKey:@headerImageTapLoadScreenTransitionType], @transitionType, nil]; [tmpMenuItem setJsonVars:tmpDictionary]; [tmpMenuItem setItemId:@0]; //load the next screen [BT_viewControllerManager handleTapToLoadScreen:[self screenData]:tmpMenuItem:screenObjectToLoad]; [tmpMenuItem release]; [screenObjectToLoad release]; }else{ //show message [BT_debugger showIt:self:[NSString stringWithFormat:@%@,NSLocalizedString(@menuTapError,@The application doesn't know how to handle this action?)]]; } } //load data -(void)loadData{ [BT_debugger showIt:self:@loadData]; //show progress [self showProgress]; //prevent interaction during operation [myTableView setScrollEnabled:FALSE]; [myTableView setAllowsSelection:FALSE]; Screen Data scenarios -------------------------------- a) No dataURL is provided in the screen data - use the info configured in the screen data b) A dataURL is provided and cacheWebData is 0. download button data everytime, do not cache c) A dataURL is provided and cacheWebData is 1. download button data, cache for offline use */ self.saveAsFileName = [NSString stringWithFormat:@screenData_%@.xml, [screenData itemId]]; //flag in progress self.isLoading = TRUE; //we must have a dataURL if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@] length] > 3){ //look for previously used version... if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ [BT_debugger showIt:self:@using cached version of screen data]; NSString *staleData = [BT_fileManager readTextFileFromCacheWithEncoding:self.saveAsFileName:-1]; [self parseScreenData:staleData]; }else{ [self downloadData]; } } } //download data -(void)downloadData{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloading screen data from: %@, [self saveAsFileName]]]; //flag this as the current screen *****_appDelegate *appDelegate = (*****_appDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.rootApp.currentScreenData = self.screenData; //show progress [self showProgress]; //prevent interaction during operation [myTableView setScrollEnabled:FALSE]; [myTableView setAllowsSelection:FALSE]; NSString *tmpURL = @; if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@] length] > 3){ //merge url variables tmpURL = [BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@]; tmpURL = [tmpURL stringByReplacingOccurrencesOfString:@[screenId] withString:[self.screenData itemId]]; ///merge possible variables in URL NSString *useURL = [BT_strings mergeBTVariablesInString:tmpURL]; NSString *escapedUrl = [useURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //fire downloader to fetch and results downloader = [[BT_downloader alloc] init]; [downloader setSaveAsFileName:[self saveAsFileName]]; [downloader setSaveAsFileType:@text]; [downloader setUrlString:escapedUrl]; [downloader setDelegate:self]; [downloader downloadFile]; } } //parse screen data -(void)parseScreenData:(NSString *)theData{ [BT_debugger showIt:self:@parseScreenData]; //prevent interaction during operation [myTableView setScrollEnabled:FALSE]; [myTableView setAllowsSelection:FALSE]; //the screen data is an XML string... fire the xml parser in the background... //it will tell us it's complete. //convert NSString to NSData for parser. NSData *tmpData = [theData dataUsingEncoding:NSUTF8StringEncoding]; //create the queue to run our parse operation self.queue = [[NSOperationQueue alloc] init]; //pass the data to the parser.. BT_rssParser *parser = [[BT_rssParser alloc] initWithData:tmpData delegate:self]; [parser setXmlItemTagName:self.xmlItemTagName]; [parser setXmlItemTitleName:self.xmlItemTitleName]; [parser setXmlItemDescriptionName:self.xmlItemDescriptionName]; [parser setXmlItemLinkName:self.xmlItemLinkName]; [parser setXmlItemImageName:self.xmlItemImageName]; [parser setXmlAppendValueToLinkURL:self.xmlAppendValueToLinkURL]; //tell parser what elements to look for... [parser setItemsToParse]; //start the parse operation. didFinishParsing is sent an array by the parser when done [queue addOperation:parser]; [parser release]; } //build screen -(void)layoutScreen{ [BT_debugger showIt:self:@layoutScreen]; //reload table [self.myTableView reloadData]; //hideProgress [self hideProgress]; //enable interaction again (unless owner turned it off) if([[BT_strings getStyleValueForScreen:self.screenData:@preventAllScrolling:@] isEqualToString:@1]){ [self.myTableView setScrollEnabled:FALSE]; }else{ [myTableView setScrollEnabled:TRUE]; } [myTableView setAllowsSelection:TRUE]; //flag done loading self.isLoading = FALSE; } ////////////////////////////////////////////////////////////// //UITableView delegate methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } // number of rows - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.menuItems count]; } //table view cells - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @Cell; BT_cell_menuList *cell = (BT_cell_menuList *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { //init our custom cell cell = [[[BT_cell_menuList alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } //this menu item BT_item *thisMenuItemData = [self.menuItems objectAtIndex:indexPath.row]; [cell setTheMenuItemData:thisMenuItemData]; [cell setTheParentMenuScreenData:[self screenData]]; [cell configureCell]; //custom background view. Must be done here so we can retain the round corners if this is a round table //this method refers to this screen's listRowBackgroundColor and it's position in the tap. Top and //bottom rows may need to be rounded if this is screen uses listStyle:round [cell setBackgroundView:[BT_viewUtilities getCellBackgroundForListRow:[self screenData]:indexPath:[self.menuItems count]]]; //return return cell; } //on row select - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [BT_debugger showIt:self:@didSelectRowAtIndexPath]; //get the rss BT_rssItem *theRssItem = [self.rssItems objectAtIndex:indexPath.row]; //pass this menu item to the tapForMenuItem method BT_item *thisMenuItem = [self.menuItems objectAtIndex:indexPath.row]; //build a BT_screen_webView to load. Give it an itemId that matches the menuItems //loadScreenWithItemId value so we BT_viewControllManager can find it. NSString *theDynamicScreenItemId = [thisMenuItem itemId]; BT_item *theDynamicScreenObjectToLoad = [[BT_item alloc] init]; [theDynamicScreenObjectToLoad setItemId:theDynamicScreenItemId]; [theDynamicScreenObjectToLoad setItemType:@BT_screen_webView]; //dictionary for menu row tapped NSDictionary *menuDict = [NSDictionary dictionaryWithObjectsAndKeys: theDynamicScreenItemId, @itemId, @BT_menuItem, @itemType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemRowTapTransitionType:@], @transitionType, nil]; [thisMenuItem setJsonVars:menuDict]; //create a dictionary for the dynamic screen. NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: theDynamicScreenItemId, @itemId, @BT_screen_webView, @itemType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@navBarTitleText:@], @navBarTitleText, theRssItem.linkURL, @dataURL, //these are the optional properties the BT_screen_webView will look for [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarBackgroundColor:@], @navBarBackgroundColor, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarStyle:@], @navBarStyle, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemToolBarStyle:@], @toolBarStyle, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemBackButtonText:@], @navBarBackButtonText, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemBackgroundColor:@], @backgroundColor, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemShowBrowserBarBack:@0], @showBrowserBarBack, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemShowBrowserRefresh:@0], @showBrowserBarRefresh, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemShowBrowserBarLaunchInNativeApp:@0], @showBrowserBarLaunchInNativeApp, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarRightButtonType:@], @navBarRightButtonType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemNavBarRightButtonTapLoadScreenItemId:@], @navBarRightButtonTapLoadScreenItemId, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemRightButtonTapTransitionType:@], @navBarRightButtonTapTransitionType, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemHideBottomTabBarWhenScreenLoads:@], @hideBottomTabBarWhenScreenLoads, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioFileName:@], @audioFileName, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioFileURL:@], @audioFileURL, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioStopsOnScreenExit:@0], @audioStopsOnScreenExit, [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAudioNumberOfLoops:@0], @audioNumberOfLoops, nil]; //set the dictionary for the dynamic screen [theDynamicScreenObjectToLoad setJsonVars:dict]; //BT_viewControllerManager will launch the next screen [BT_viewControllerManager handleTapToLoadScreen:[self screenData]:thisMenuItem:theDynamicScreenObjectToLoad]; //clean up [theDynamicScreenObjectToLoad release]; theDynamicScreenObjectToLoad = nil; } ////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //parser delegate methods //did finish parsing -(void)didFinishParsing:(NSArray *)loadedRssItems{ [BT_debugger showIt:self:@didFinishParsing]; //rememeber the rssItems self.rssItems = loadedRssItems; //arrays for menu items self.menuItems = [[NSMutableArray alloc] init]; //loop through the loaded rssItems and a menuItem for each... int i = 0; for(i = 0; i < [loadedRssItems count]; i++){ BT_rssItem *thisRssItem = [loadedRssItems objectAtIndex:i]; NSString* theTitle = [NSString stringWithFormat:@%@, thisRssItem.title]; NSString* theDescription = [NSString stringWithFormat:@%@, thisRssItem.description]; NSString* theIconURL = @; NSString *theIconName = @; if([thisRssItem.imageURL length] > 0){ theIconURL = [NSString stringWithFormat:@%@, thisRssItem.imageURL]; theIconName = [theIconURL lastPathComponent]; } //properties for the menu item NSString *menuItemId = [NSString stringWithFormat:@rss_%@_%d, [self.screenData itemId], i]; NSString *loadScreenWithItemId = menuItemId; NSString *transitionType = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemTransitionType:@]; NSString *rowAccessoryType = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemAccessoryType:@]; NSString *soundEffectFileName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@rssItemSoundEffectFileName:@]; //create a dictionary for the BT_item - DO NOT CACHE WEB IMAGES NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: @0, @cacheWebImages, theTitle, @titleText, theDescription, @descriptionText, loadScreenWithItemId, @loadScreenWithItemId, theIconURL, @iconURL, theIconName, @iconName, transitionType, @transitionType, soundEffectFileName, @soundEffectFileName, rowAccessoryType, @rowAccessoryType, nil]; //create a menu item from the data BT_item *thisMenuItemData = [[BT_item alloc] init]; [thisMenuItemData setJsonVars:dict]; [thisMenuItemData setItemId:menuItemId]; [thisMenuItemData setItemType:@BT_menuItem]; [self.menuItems addObject:thisMenuItemData]; [thisMenuItemData release]; } [self performSelectorOnMainThread:@selector(layoutScreen) withObject:nil waitUntilDone:NO]; self.queue = nil; } //parse error -(void)parseErrorOccurred:(NSError *)error{ [BT_debugger showIt:self:[NSString stringWithFormat:@parseErrorOccurred: %@, [error localizedDescription]]]; } //allows us to check to see if we pulled-down to refresh -(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ [self checkIsLoading]; } -(void)checkIsLoading{ if(isLoading){ return; }else{ //how far down did we pull? double down = myTableView.contentOffset.y; if(down <= -65){ if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@dataURL:@1] length] > 3){ [self downloadData]; } } } } ////////////////////////////////////////////////////////////////////////////////////////////////// //downloader delegate methods -(void)downloadFileStarted:(NSString *)message{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloadFileStarted: %@, message]]; } -(void)downloadFileInProgress:(NSString *)message{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloadFileInProgress: %@, message]]; if(progressView != nil){ UILabel *tmpLabel = (UILabel *)[progressView.subviews objectAtIndex:2]; [tmpLabel setText:message]; } } -(void)downloadFileCompleted:(NSString *)message{ [BT_debugger showIt:self:[NSString stringWithFormat:@downloadFileCompleted: %@, message]]; [self hideProgress]; //if message contains error, look for previously cached data... if([message rangeOfString:@ERROR options:NSCaseInsensitiveSearch].location != NSNotFound){ [BT_debugger showIt:self:[NSString stringWithFormat:@download error: There was a problem downloading data from the internet.%@, message]]; //NSLog(@Message: %@, message); //show alert [self showAlert:nil:NSLocalizedString(@downloadError, @There was a problem downloading some data. Check your internet connection then try again.):0]; //show local data if it exists if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ //use stale data if we have it NSString *staleData = [BT_fileManager readTextFileFromCacheWithEncoding:self.saveAsFileName:-1]; [BT_debugger showIt:self:[NSString stringWithFormat:@building screen from stale configuration data saved at: @, [self saveAsFileName]]]; [self parseScreenData:staleData]; }else{ //no local data? [BT_debugger showIt:self:[NSString stringWithFormat:@There is no local data availalbe for this screen?%@, @]]; } }else{ //parse previously saved data if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ [BT_debugger showIt:self:[NSString stringWithFormat:@parsing downloaded screen data.%@, @]]; NSString *downloadedData = [BT_fileManager readTextFileFromCacheWithEncoding:[self saveAsFileName]:-1]; [self parseScreenData:downloadedData]; }else{ [BT_debugger showIt:self:[NSString stringWithFormat:@Error caching downloaded file: %@, [self saveAsFileName]]]; //show alert [self showAlert:nil:NSLocalizedString(@appDownloadError, @There was a problem saving some data downloaded from the internet.):0]; } } } //Added Going-Viral ////////////////////////////////////////////// //search text delegate methods.. //begin edit - (void)textFieldDidBeginEditing:(UITextField *)textField{ //NSLog(@textFieldDidBeginEditing); } //end edit -(void)textFieldDidEndEditing:(UITextField *)textField{ //NSLog(@textFieldDidEndEditing); //remember the searched value [BT_strings setPrefString:@currentSearchValue:[searchBox text]]; } //should begin editing -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ //NSLog(@textFieldShouldBeginEditing); //deselect previously selected row NSIndexPath* selection = [myTableView indexPathForSelectedRow]; if(selection){ [myTableView deselectRowAtIndexPath:selection animated:NO]; } return YES; } //should end editing -(BOOL)textFieldShouldEndEditing:(UITextField *)textField{ //NSLog(@textFieldShouldEndEditing); return YES; } //return tapped -(BOOL)textFieldShouldReturn:(UITextField *)textField{ //NSLog(@textFieldShouldReturn); [self.searchBox resignFirstResponder]; return TRUE; } //should clear -(BOOL)textFieldShouldClear:(UITextField *)textField{ //NSLog(@textFieldShouldClear); //forward event to textFieldDidChange [self textFieldDidChange:NULL]; return YES; } //text field changed -(void)textFieldDidChange:(id)sender{ //NSLog(@textFieldDidChange); //remove filtered items [filteredMenuItems removeAllObjects]; //remember the searched value for next time (in case we leave the screen and come back) [BT_strings setPrefString:@currentSearchValue:[searchBox text]]; //search on every character... if([searchBox.text length] > 0){ //loop through items in menu data... for(int i = 0; i < [self.menuItems count]; i++){ BT_item *thisItem = [self.menuItems objectAtIndex:i]; NSRange r = [[thisItem.jsonVars objectForKey:@titleText] rangeOfString:searchBox.text options:NSCaseInsensitiveSearch]; if(r.location != NSNotFound){ if(r.location == 0){ [self.filteredMenuItems addObject:thisItem]; } } } } //show the filtered list if searching... if([searchBox.text length] > 0){ displayMenuItems = self.filteredMenuItems; }else{ displayMenuItems = self.menuItems; } //reload [myTableView reloadData]; } // //dealloc -(void)dealloc{ [screenData release]; screenData = nil; [progressView release]; progressView = nil; [menuItems release]; menuItems = nil; [rssItems release]; rssItems = nil; [myTableView release]; myTableView = nil; [headerImageView release]; headerImageView = nil; //Added Going_viral [filteredMenuItems release]; filteredMenuItems = nil; [displayMenuItems release]; displayMenuItems = nil; // [saveAsFileName release]; saveAsFileName = nil; [downloader release]; downloader = nil; //Added Going_viral [searchBox release]; searchBox = nil; [searchTimer release]; searchTimer = nil; // [xmlItemTagName release]; xmlItemTagName = nil; [xmlItemTitleName release]; xmlItemTitleName = nil; [xmlItemDescriptionName release]; xmlItemDescriptionName = nil; [xmlItemLinkName release]; xmlItemLinkName = nil; [xmlItemImageName release]; xmlItemImageName = nil; [xmlAppendValueToLinkURL release]; xmlAppendValueToLinkURL = nil; [super dealloc]; } @end // End of BT_screen_rssReader.m
 
David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
like
07/18/11 02:08 AM (14 years ago)
Sure. Email me the file you've created (forum is horibble for code!) and I'll fixer-up and get it back to you. info 'at' buzztouch.com - be sure to attach the class files (.h, .m for your rss screen) and include the name of the app as it appears in your control panel.
 

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.