Discussion Forums  >  Plugins, Customizing, Source Code

Replies: 5    Views: 99

Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
06/15/12 12:07 PM (13 years ago)

Tutorial (v1.5 iOS): Feeding a List Menu from a text file included in your build.

Building upon a concept that David and I brought to life last week, here is a tutorial on how to use a text file containing your JSON childitems inside your project build, and still control it from the online control panel. (Original post at my website, which includes links and possibly easier to read) http://idevdepot.com/?p=835 Reason: I wanted to be able to include a text file containing all the JSON childitems needed to feed a List Menu in my build. After completing the List Menu Tool, I decided it would be great if I could use the output file in my projects without having to either host the file on dropbox, or copy and paste the JSON manually into the BT_Config.txt. So after I looked at the LoadData method in the BT_screen_menulist.m file, I found where the modifications needed to be made, but couldn't quite figure out the exact syntax to do it. I emailed David @ buzztouch, and he was very quick to show me the correct syntax. He shared that in the forums here. While that method worked, it wasn't perfect for my application because when you make changes to your BT_config.txt manually (in xCode), you end up forcing yourself to "cut ties" with the online control panel. There's no way to make those changes in the control panel, you have to do them in xCode. So I decided to find a way to fix that problem. What I came up with was a modification to the loadData method that would look at the Screen Data URL (where you would normally point to a URL containing the file outputted from the List Menu Tool). And I changed the code so that when it reads the Screen Data URL, it decides if its really a URL, or if its a Filename. If it sees "http" as the first four characters of the Screen Data URL, it assumes it to be a true URL and downloads the config as normal. If it doesn't see "http" as the first four characters, it assumes it to be a Filename, and looks for it in the project files. To get this to work, you have two options. 1. Grab the CodeShare file from the Code Share Tool Library and simply use the Code Share Tool to convert it for your project, and replace your project's BT_screen_menulist.m file with the one you get from the Code Share Tool or 2. Manually make the changes in xCode: In your v1.5 iOS Buzztouch project: Find the BT_screen_menuList.m file in the BT_Screens group Around Line # 214, find the loadData block, which looks like this originally: //load data -(void)loadData{ [BT_debugger showIt:self:@"loadData"]; self.isLoading = TRUE; //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 app's configuration file b) A dataURL is provided, download now if we don't have a cache, else, download on refresh. */ self.saveAsFileName = [NSString stringWithFormat:@"screenData_%@.txt", [screenData itemId]]; //do we have a URL? BOOL haveURL = FALSE; if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@"dataURL":@""] length] > 10){ haveURL = TRUE; } //start by filling the list from the configuration file, use these if we can't get anything from a URL if([[self.screenData jsonVars] objectForKey:@"childItems"]){ //init the items array self.menuItems = [[NSMutableArray alloc] init]; NSArray *tmpMenuItems = [[self.screenData jsonVars] objectForKey:@"childItems"]; for(NSDictionary *tmpMenuItem in tmpMenuItems){ BT_item *thisMenuItem = [[BT_item alloc] init]; thisMenuItem.itemId = [tmpMenuItem objectForKey:@"itemId"]; thisMenuItem.itemType = [tmpMenuItem objectForKey:@"itemType"]; thisMenuItem.jsonVars = tmpMenuItem; [self.menuItems addObject:thisMenuItem]; [thisMenuItem release]; } } //if we have a URL, fetch.. if(haveURL){ //look for a previously cached version of this screens data... if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ [BT_debugger showIt:self:@"parsing cached version of screen data"]; NSString *staleData = [BT_fileManager readTextFileFromCacheWithEncoding:[self saveAsFileName]:-1]; [self parseScreenData:staleData]; }else{ [BT_debugger showIt:self:@"no cached version of this screens data available."]; [self downloadData]; } }else{ //show the child items in the config data [BT_debugger showIt:self:@"using menu items from the screens configuration data."]; [self layoutScreen]; } } and replace with this: //load data -(void)loadData{ [BT_debugger showIt:self:@"loadData"]; self.isLoading = TRUE; //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 app's configuration file b) A dataURL is provided, download now if we don't have a cache, else, download on refresh. c) No dataURL is provided, AND a file exists in the Xcode project containing the childItems array... */ self.saveAsFileName = [NSString stringWithFormat:@"screenData_%@.txt", [screenData itemId]]; //do we have a URL? BOOL haveURL = FALSE; if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@"dataURL":@""] length] > 10){ haveURL = TRUE; } //start by filling the list from the configuration file, use these if we can't get anything from a URL if([[self.screenData jsonVars] objectForKey:@"childItems"]){ //init the items array self.menuItems = [[NSMutableArray alloc] init]; NSArray *tmpMenuItems = [[self.screenData jsonVars] objectForKey:@"childItems"]; for(NSDictionary *tmpMenuItem in tmpMenuItems){ BT_item *thisMenuItem = [[BT_item alloc] init]; thisMenuItem.itemId = [tmpMenuItem objectForKey:@"itemId"]; thisMenuItem.itemType = [tmpMenuItem objectForKey:@"itemType"]; thisMenuItem.jsonVars = tmpMenuItem; [self.menuItems addObject:thisMenuItem]; [thisMenuItem release]; } } //if we have a URL, fetch.. if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@"dataURL":@""] hasPrefix:@"http"]){ //look for a previously cached version of this screens data... if([BT_fileManager doesLocalFileExist:[self saveAsFileName]]){ [BT_debugger showIt:self:@"parsing cached version of screen data"]; NSString *staleData = [BT_fileManager readTextFileFromCacheWithEncoding:[self saveAsFileName]:-1]; [self parseScreenData:staleData]; }else{ [BT_debugger showIt:self:@"no cached version of this screens data available."]; [self downloadData]; } }else{ //see if we have a file in the Xcode project names the same as the childItemsLocalFileName property in the JSON //that contains the childItems data... NSString *localFileName = [BT_strings getJsonPropertyValue:self.screenData.jsonVars:@"dataURL":@"unused.txt"]; if([BT_fileManager doesFileExistInBundle:localFileName]){ //read the contents of the file included in the Xcode project... [BT_debugger showIt:self:@"using menu items from a file included in the Xcode project."]; NSString *childItemsData = [BT_fileManager readTextFileFromBundleWithEncoding:localFileName:-1]; //pass this data to the parseScreenData method... [self parseScreenData:childItemsData]; }else{ //show the child items in the config data [BT_debugger showIt:self:@"using menu items from the screens configuration data."]; [self layoutScreen]; } } } Sorry for the poorly pasted code. (another reason to use the Code Share Tool) If you have any questions, let me know.
 
MGoBlue
Apple Fan
Profile
Posts: 980
Reg: Jun 07, 2011
Gold River, CA
10,600
like
06/15/12 01:04 PM (13 years ago)
Great job. Thanks for sharing.
 
RonBo
buzztouch Evangelist
Profile
Posts: 167
Reg: Feb 26, 2012
Raleigh, NC
5,220
like
06/28/12 05:52 PM (13 years ago)
Stobe, so if I go the edit-route, where do I place the file output from your List Menu tool? "If it doesn't see "http" as the first four characters, it assumes it to be a Filename, and looks for it in the project files." thanks
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/28/12 06:50 PM (13 years ago)
I think you can drag it anywhere in your build in xcode. I always use the documents folder.
 
RonBo
buzztouch Evangelist
Profile
Posts: 167
Reg: Feb 26, 2012
Raleigh, NC
5,220
like
07/04/12 08:02 PM (13 years ago)
Thanks, that works perfectly
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
08/03/12 11:39 AM (13 years ago)
For anyone subscribed to this thread, I found one small glitch: If you use this method and "drag" down the list menu screen to refresh, you will get a download (check internet) error. To fix this: 1. Find the "checkIsLoading" function in the BT_menuList.m file (around line 662-ish) 2. Replace: if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@"dataURL":@"1"] length] > 3){ With: if([[BT_strings getJsonPropertyValue:screenData.jsonVars:@"dataURL":@"1"] hasPrefix:@"http"]){ That's it! It shouldn't mess anything else up, but if it does, I'm not responsible. :) -Stobe
 

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.