I have an iPhone app that shows the user a UIWebView in the first view, what I am trying to do is allow the user to save what is essentially favorites to be saved and then displayed in a table view in the second view. To do this all i need is the page URL and also the Page Title to be saved to then populate the table view. Now here is the problem I am just starting to learn how to make iPhone apps and I have no clue what would be the best way to save it and how to get this information from the web view?
Implement the UIWebViewDelegate protocol. You can obtain the URL from the request object in the delegate method -webView:shouldStartLoadWithRequest:navigationType:
To extract the title from the HTML, run some Javascript on the content using – stringByEvaluatingJavaScriptFromString:. Make sure you do this after the content is fully loaded, i.e. in the delegate method - (void)webViewDidFinishLoad:(UIWebView *)webView
To populate and display in a TableView, you have to have some sort of a DataSource, preferably an NSArray, since you shall be appending or altering this array, use a NSMutableArray. Now to save two bits of information, the URL and the Title, have two arrays, one for Title and one for the URL. (Since the title can be customised).
In the TableView delegate, where you return the number of rows, return [URLArray count];
and in the function to populate the cell, set the Text to [titleArray objectAtIndex:[indexPath row]] and the SubTitle to [URLArray objectAtIndex:[indexPath row]];
Hope this resolves your question and is what you were looking for.
Related
I'm making a simple To-Do list app for the iPhone with a rails backend.
So far, I can pull all the tasks in a To-Do list from the web app, parse the JSON, and insert it into the UITableView.
The json response from rails:
[
{"id":1,"name":"Buy bread"},
{"id":8,"name":"Get gas"},
{"id":14,"name":"Call John"}
]
In the UITableView, a row for each task, the textLabel of the cell is the name of the task:
The problem I'm having now is how to associate the cell with the record id of the task.
Two tasks can have the same name, so I can't just get the id from the hash based only on the name.
I need the record id, so I can post back to the rails app, after the user edits the UItableView (deletes a task for example).
Is there a property I can set on the cell? I feel like I'm missing something obvious. This is my first iPhone app, so please be gentle, hehe.
How are you getting the JSON array to an Objective-C array for use in the table? You'll have to do that again for the ID of the task, and in your - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method use something like theID = [idArray objectAtIndex:indexPath.row];
The better solution would be to maintain a proper data model on the client. You could use the JSON as your model, but Core Data is a bit more robust. What you'd want is to have your controller associate what it knows about the view with what it knows about the model. For instance, if you use didSelectRowAtIndexPath: You'd want to use this index path to map to your model.
Your solution of setting a property on a cell which allows a client of your view to query your data model is in violation of the rules of the MVC paradigm. It couples your view to your model which isn't great.
I have a UITableView and you can add/delete cells if you like. There are 3 pages. The second page allows the user to add cells to the table view, which is on the third page. The first page is just a navigation page. If i add any number of cells to the table view, i can see them on the 3rd page fine! I can return to the second page, and then return back to the 3rd page. And the cells will still be there, but if i go to the 2nd page, then the 1st, and back to the table view, all the cells are gone!! How can i fix this? My Code for navigating through the pages is as follows:
-(IBAction)button1:(id)sender{
RootViewController * black = [[BlackFacePlateViewControlller alloc]init];
black.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:black animated:YES];
[black release];
}
and:
- (IBAction)back:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
Thanks in advance!
Kurt, you have to understand something about persistence on not just the iPhone, but any system. You most likely have an array that is loaded into the table, but when the controller class containing that array is dismissed (as you have it with [self dismissModalViewControllerAnimated:YES];), the chance is more likely than not that dealloc (or in the case of ARC, a mass release of your objects) will be called on that controller, and your array will be set to nil and reclaimed but the system. You need a storage mechanism, whether that's a plist, a specific file format, or XML, you need some means of retrieving the datasource array even after it's been destroyed.
I myself am now huge advocate of the plist route, as they're just so convenient and easy to use, and they can be edited with absolutely massive amounts of data with little side effects.
I am implementing the application which consumes webservice (first authentication and then calling different webservices with provided token as a header field in URL)
After the authentication phase, I am showing the Home page to the user.
On Home page i am showing UITableView (with 9 cells on it.)
If those were the buttons I would write separate 9 - "onButtonClick" functions to call 9 different webservices, accordingly.
What can be best implementation (or flow), for implementing this structure.
Let me know if you want more details.
Thank you.
You could keep the URLs for the services in an array attached to the table view's view controller (or delegate really) and then use the selected row as an index into the array and call the service.
No need to write nine methods separately
you can use the JASON COCO way as he said store the URL in an array.
when you will click on a particular row. you should pass that URL to Web services method
suppose you have
- (void)tableView:(UITableView *)tableView1 didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* urlString=[self.URLArray objectAtIndex:indexPath.row];
[self callWebSerciceWithUrl:urlString];
}
-(void)callWebSerciceWithUrl:(NSString* )Url{
//Use that URL String for calling web services...
//You Should write your Remaining web service Code here...
}
In my application i parsed some JSON RSS feed and stored the parsed data into a NSMutableArray.
here ,i want to display only 4 items in my tableview at a time . Below the tableview , there a UIButton 'more'. When the user clicks this button, i want to display another 4 like that ..... How to do that.
Can any one give me an idea or point me any simple example that i can refer . How can i do some pagination with the parsed data . Thanks in advance .......
http://www.iphonedevsdk.com/forum/iphone-sdk-development/6676-paging-tableview.html
As you already know there is a data source for a uiTableView. You can easily achieve this as your requirement needs a button press. Pagination without button press on scroll of the table view would be tricky.
You have to create a NSMutableArray as a data source. Everytime the more button is pressed add 4 items to the end of the NSMutableArray.
Using NSRange you can get the objects from the main array and add them 4 at a time to the data source. Once you add call [tableview reload];
Also you can create the data source again
NSArray *dataSource = [mainArray subarrayWithRange:NSMakeRange(0, PageNum*4)];
so I am trying to create an array of recently viewed pictures. Basically I have a TableViewController that pushes a picture view in a navigation controller, located in one tab and then am trying to have a navigation controller that records what pictures have been recently viewed, lists them in a TableViewController and then also pushes that to a new view displaying the picture. I have set up both navigation controllers within the tab bar controller programmatically. Pretty much everything is set up the way I want it but I am just not able to pass the recently viewed picture information to the table view controller that will display the list.
Here is how I am trying to pass the data when a user clicks on a particular table cell:
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
RecentsTableViewController *rtvc = [[RecentsTableViewController alloc] init];
[rtvc.recents addObject:[self dictionaryAtIndex:indexPath]];
[rtvc release];
}
recents is a mutable array that I created in the RecentsTableViewController. It is getting initialized ok, checked using NSLog, but every time a user clicks on the table cell in the other view controller, the dictionary is not being passed to the array. I also know the dictionary information is correct and set correct because it works passing on to the view that displays the image. I guess I am just confused because I can do it for a NavigationController, I am just struggling to find the answer in passing data in a TabBarController.
Sorry if this post may be long/confusing but I have really searched everywhere for an answer with no luck. I have heard about using the app delegate to store like a global variable but I am under the impression this is bad practice and I am trying to write my code correctly.
Here is the updated code for the dictionaryAtIndex method:
- (NSDictionary *)dictionaryAtIndex:(NSIndexPath *)indexPath {
NSArray *flickrPics = [FlickrFetcher photosAtPlace:self.placeID];
NSDictionary *returnedDictionary = [flickrPics objectAtIndex:indexPath.row];
return returnedDictionary;
}
indexPath is a struct which contains two properties, row and index, and cannot be used directly to access an object in an array. You probably want to do this instead:
[rtvc.recents updateRecents:[self dictionaryAtIndex:indexPath.row]];
You're creating a new RecentsTableViewController (it is not the same as the one in the tab bar), setting its "recent items", and then releasing it. Nothing else has a pointer to it, so nothing else will see its "recent" items.
There are at least three easy-ish ways to update the "recents" controller:
Access it directly from the tab bar controller (incredibly icky layering violation and breaks when you change the tab order or the navigation structure or...): [(RecentsTableViewController*)[self.tabBarController.viewControllers objectAtIndex:...]) updateRecentsWithDictionary:...]
Post a notification, which you listen for in RecentsTableViewController: [[NSNotificationCenter defaultCenter] postNotificationWithName:MyViewedPictureNotificationName object:nil userInfo:...]
Save it to NSUserDefaults. Load it from NSUserDefaults in -[RecentsTableViewController viewWillAppear:]. The advantage here is that it persists across app launches. (There is the implicit assumption that the defaults will not change while the "Recents" view is visible".)