Discussion Forums  >  Plugins, Customizing, Source Code

Replies: 13    Views: 434

David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
06/04/12 01:05 PM (13 years ago)

How to use a txt file in the Xcode project to provide menu items

Hi gang, I was working on a solution for @Stobe and it occurred to me that lots of folks may want to take advantage of this code. The idea is that when you're working with "childItems" that power a menu list, you have a few options. You can... a) Use a dataURL that points to a file that provides the childItems array for the menu items. b) Use a childItems[] array included in the JSON that describes the screen. @Stobe needed a third option and this post is about that option. c) Add a simple .txt file to the Xcode project that provided the childItems data. Here's how to do this: a) Create a .txt file that holds the childItems data and add it to the Xcode project. This data will look like: { "childItems":[ {"itemId":"001", "itemType":"BT_menuItem", "titleText":"Menu item 1"}, {"itemId":"002", "itemType":"BT_menuItem", "titleText":"Menu item 2"}, {"itemId":"003", "itemType":"BT_menuItem", "titleText":"Menu item 3"}, {"itemId":"004", "itemType":"BT_menuItem", "titleText":"Menu item 4"} ] } b) Modify the JSON data that describes the BT_screen_menu. Add a property to the JSON data that tells the app what file to use for the childItems. The JSON data for the menu screen will look like: {"itemNickname":"Home Menu", "itemId":"002", "itemType":"BT_screen_menuList", "childItemsLocalFileName":"menu-items.txt", "navBarTitleText":"Contact Us", "navBarBackgroundColor":"#000000"} Notice there is NO dataURL and NO childItems array in this JSON, only a file name that holds the childItems data. In this case, the file name is menu-items.txt and it's been added to the Xcode project. c) Overwrite the loadData() method in the BT_screen_menuList.m file (it starts on line 214) with this newly worked method: //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(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{ //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:@"childItemsLocalFileName":@"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]; } } } c) Compile. Run. Works great. There are several advantages to using this approach. @Stobe uses separate files to power different menus, quizzes and other screens. You could use the method in other files as needed, this example show how to use it for a must list. Happy app building.
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/04/12 02:25 PM (13 years ago)
Thanks a ton for that @David. For those of you who have my List Menu tool, I will be adding support for this in the next update. I'm going to try to automate it as much as possible, so it will be easy to implement.
 
Fred@mySkylla com
Android Fan
Profile
Posts: 5259
Reg: Oct 03, 2011
location unknow...
62,560
like
06/04/12 02:51 PM (13 years ago)
I guess the part I missed was modify the JSON data. I suppose that's done in the BT_Config.txt file. If you leave the app online would the first update be a problem ? Is it the same process for Android? Fred Edited.
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/04/12 03:27 PM (13 years ago)
No need to re-create the method files for each list. The lists are created by the BT_config.txt. Then you have to edit the JSON manually to add the text file parameter call. And as far as Android, the process would be the same, but obviously not the code. You'd have to come up with your own syntax for the java class.
 
Fred@mySkylla com
Android Fan
Profile
Posts: 5259
Reg: Oct 03, 2011
location unknow...
62,560
like
06/04/12 03:35 PM (13 years ago)
My edit crossed with the last post. Do the app need to be on offline app? Fred
 
ATRAIN53
Code is Art
Profile
Posts: 1755
Reg: Nov 17, 2011
Chicago
26,450
like
06/04/12 04:49 PM (13 years ago)
Wow. Thanks for sharing David. Just what I need more code to digest. Scary how much sense that post makes to me. Is this code that works on Self Hosted? and if it works in 1.5 Does this mean that childItems don't tally against the screen count limitations? This line of the code really piqued my interest... //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]; "Bundle" just means the main project? Do/can you reference other file types in xcode projects with this same code? Like plist and possibly the coveted XIB? I haven't worked with Chris list tool yet but keeping notes for future. Hopefully he'll heave it all automated by the time I use it. LOL. Love this childitem concept for menus. Seems like it might help organize the control panel with lots of screens. Thanks for the efforts guys!
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/04/12 05:05 PM (13 years ago)
@Fred: It certainly helps if its an offline app. If you're ok with having an online app, then it makes better sense to host the JSON.txt file as well (for full dynamic control). The main purpose I was working with David on this was because I wanted an offline solution to a source of JSON that was not created in the control panel. Its still possible to copy/paste it manually, but this makes it prettier. And helps a ton for revisioning.
 
Fred@mySkylla com
Android Fan
Profile
Posts: 5259
Reg: Oct 03, 2011
location unknow...
62,560
like
06/04/12 05:14 PM (13 years ago)
@Strobe, thanks for confirming my understanding & the explanation of the purpose of this technique. Did you try the http:/// method of accessing a file in the assets folder? I haven't tried it but think it'll work. Fred
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/04/12 05:19 PM (13 years ago)
I think that was in reference to android, correct? @stRobe has no time for multiple OS's
 
Fred@mySkylla com
Android Fan
Profile
Posts: 5259
Reg: Oct 03, 2011
location unknow...
62,560
like
06/04/12 05:23 PM (13 years ago)
Posted link to iOS also. Appeared to work with either. Fred
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/04/12 05:50 PM (13 years ago)
Ahh yes, I remember that now. The little bit I read involved adding some code to the project to find the file structure. I decided at that point it would be better to improve upon the code we already have here. Too many razors, not enough stray cats. (disclaimer: no stray cats were actually hurt during the creation of this post)
 
mrDavid
BTMods.com
Profile
Posts: 3936
Reg: May 21, 2011
San Diego, CA
51,910
like
06/04/12 08:00 PM (13 years ago)
Great stuff @david & @stobe. David buzztouchmods.com
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
06/04/12 11:31 PM (13 years ago)
Sweet, ty!
 
Stobe
buzztouch Evangelist
Profile
Posts: 1528
Reg: Mar 04, 2011
Fredericksburg,...
24,680
like
06/05/12 05:57 AM (13 years ago)
I have modified the above code to be much easier to implement in your project while still using buzztouch's control panel. I will be documenting it, and releasing it probably later today. -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.