Using Parse.com to load UIWebView from UITableView Cell Selection - ios

I have created an "events table", which features the event name, the date and location. Upon clicking each event cell, I am trying to load a specific event URL into a web view. Completely lost.
I have integrated a "prepareForSegue" in the ViewController.m, and have successfully loaded a single url into each table cell that is defined within the code, but I cannot seem to load a string of URLs from Parse.com. The rest of the event table data is loaded fine from Parse.. i'm just struggling with the URL.
Can anybody help?
This is what I have for the individual url load:
-(void)loadRequestFromString:(NSString*)urlString
{
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[self.eventWebView loadRequest:urlRequest];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = event.name;
[self loadRequestFromString:#"http://www.airleague.co.uk"];
}
- (void)viewDidUnload
{
[self setEventWebView:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
My segue is:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showEventDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
EventDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Event *event = [[Event alloc] init];
event.name = [object objectForKey:#"name"];
event.eventURL = [object objectForKey:#"eventURL"];
destViewController.event = event;
}
}
#end

for:
[self loadRequestFromString:NSString];
to work, the url should have #"http://" (or any protocol) in the url.
For example it must be "http://google.com" and NOT "google.com"
Does you urls in Parse.com have the protocol in the string?

First you have to retrieve your objects, which are stored as a string:
So in your viewDidLoad you perform the following query like this:
PFQuery *urlQuery = [PFQuery queryWithClassName:#"WebViewURLs"];
urlQuery.cachedPolicy = whateverPolicyYouWant;
[urlQuery selectKeys:#[#"NameOfURLColumn"]];
[urlQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.urlArray = objects;
NSLog(#"%#", self.urlArray);
//you'll notice the NSLog logs all attributes to that array, so if you want to narrow it down to a specific column you can do something like this:
self.urlArray = [objects valueForKey:#"NameOfColumn"];
}
}];
So now you have the objects in an array and you can act accordingly. Your going to have to be more specific with your set up if you want a more specific answer. I'm just guessing at this point since i'm not a mind reader...yet :)
EDIT after taking a gander from the project you sent to me via email...
A quick synopsis for other users looking for an answer similar:
Ensure your IBOutlet connections are singular and attached to their respective owners.
Additionally the OP wasn't segueing properly, they were allocating a new subclass every time the cell was selected, but wasn't passing any information to the webView View Controller.
It's also worth to point out the OP had subclassed the tableView to Parses PFQueryTableViewController
Make sure you properly call your destination view controller and pass information to a properly set property in the Detail VCs header :
if ([segue.identifier isEqualToString:#"showDetailVC"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
destViewController.eventURL = [object objectForKey:#"ingredients"];
destViewController.eventName = [object objectForKey:#"name"];
}
Detail VC Header
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#property (nonatomic, strong) NSString *eventURL;
#property (nonatomic, strong) NSString *eventName;
Detail VC implementation :
//Load the webView in viewDidLoad:
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.eventURL]]];

Related

cannot set a property

I am making a blog reader app. Everything works fine until I try to access the detailView from a cell. I receive this error,
[UINavigationController setPFeedURL:]: unrecognised selector sent to instance 0x7f96d5802800
below code is in the PRTableViewController.m
#import "PRTableViewController.h"
#import "PRFeedPost.h"
#import "PRDetailViewController.h"
This is where the code is where the crash happens
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showDetail"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PRFeedPost *feed_Post = [self.polisenFeed objectAtIndex:indexPath.row];
[segue.destinationViewController setPFeedURL:feed_Post.url];
}
}
This is to help you understand what I am trying to setPFeedURL to. Also in PRViewTableController.m
self.polisenFeed = [NSMutableArray array];
NSArray *polisenFeedArray = [dataDictionary objectForKey:#"posts"];
for (NSDictionary *postDictionary in polisenFeedArray) {
PRFeedPost *fp = [PRFeedPost feedWithTitle:[postDictionary objectForKey:#"title"]];
fp.author = [postDictionary objectForKey:#"author"];
fp.thumbnail = [postDictionary objectForKey:#"thumbnail"];
fp.date = [postDictionary objectForKey:#"date"];
fp.url = [NSURL URLWithString:[postDictionary objectForKey:#"url" ]];
[self.polisenFeed addObject:fp];
}
Now the PRDetailViewController.h,
This is where the property is I am trying to set is,
#property (strong, nonatomic) NSURL *pFeedURL;
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UIWebView *webView;
Here is the code in PRDetailViewController.m,
- (void)viewDidLoad {
[super viewDidLoad];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:self.pFeedURL];
[self.webView loadRequest:urlRequest];
I cannot seem to figure out why this is crashing. I know it has to do with this line ,
[segue.destinationViewController setPFeedURL:feed_Post.url];
(at leaset I think it is that line. I can't figure out why I cannot set it.
Thanks for your help guys!
Change This
PRDetailViewController *objPRDetailViewController = (PRDetailViewController *)[segue.destinationViewController topViewController];
objPRDetailViewController.pFeedURL=feed_Post.url;
And Also put bellow code in viewDidAppear
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:self.pFeedURL];
[self.webView loadRequest:urlRequest];
try this
[[((id)segue.destinationViewController) topViewController] setPFeedURL:feed_Post.url];
let me know if it works

Populating iOS table from Array

I have an array _locations which is populated from a server through a json query. I now want this array to populate a table that I have created, however it does not and it quits on [self.delegate itemsDownLoaded:_locations];.
If I look in the log I can see that _locations does get populated however, but it does not parse on that data.
Here is the full code for HomeModel2:
#import "HomeModel2.h"
#import "Location2.h"
#interface HomeModel2(){
NSMutableData *_downloadedData;
}
#end
#implementation HomeModel2
- (void) downLoadItems{
// Download the json file
NSURL *jsonFileUrl = [NSURL URLWithString:#"http://server.com/service_2.php"];
// Create the request
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
// Create the NSURLConnection
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
#pragma mark NSURLConnectionDataProtocol Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// Initialize the data object
_downloadedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the newly downloaded data
[_downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Create an array to store the locations
NSMutableArray *_locations = [[NSMutableArray alloc] init];
// Parse the JSON that came in
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_downloadedData options:NSJSONReadingAllowFragments error:&error];
// Loop through Json objects, create question objects and add them to our questions array
for (int i = 0; i < jsonArray.count; i++)
{
NSDictionary *jsonElement = jsonArray[i];
// Create a new location object and set its props to JsonElement properties
Location2 *newLocation = [[Location2 alloc] init];
newLocation.name = jsonElement[#"Name"];
newLocation.address = jsonElement[#"Address"];
newLocation.latitude = jsonElement[#"Latitude"];
newLocation.longitude = jsonElement[#"Longitude"];
// Add this question to the locations array
[_locations addObject:newLocation];
}
// Ready to notify delegate that data is ready and pass back items
if (self.delegate)
{
[self.delegate itemsDownLoaded:_locations];
}
}
#end
.. and this is the ViewController to publish the data:
#import "ViewController.h"
#import "Location2.h"
#interface ViewController (){
HomeModel2 *_homeModel;
NSArray *_feedItems;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Set this view controller object as the delegate and data source for the table view
self.listTableView.delegate = self;
self.listTableView.dataSource = self;
// Create array object and assign it to _feedItems variable
_feedItems = [[NSArray alloc] init];
// Create new HomeModel2 object and assign it to _homeModel variable
_homeModel = [[HomeModel2 alloc] init];
// Set this view controller object as the delegate for the home model object
_homeModel.delegate = self;
// Call the download items method of the home model object
[_homeModel downLoadItems];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)itemsDownLoaded:(NSArray *)items
{
// This delegate method will get called when the items are finished downloading
// Set the downloaded items to the array
_feedItems = items;
// Reload the table view
[self.listTableView reloadData];
}
#pragma mark Table View Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of feed items (initially 0)
return _feedItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Retrieve cell
NSString *cellIdentifier = #"BasicCell";
UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// Get the location to be shown
Location2 *item = _feedItems[indexPath.row];
// Get references to labels of cell
myCell.textLabel.text = item.address;
return myCell;
}
#end
Can you confirm that there is "location" objects after this piece of code:
// Set the downloaded items to the array
_feedItems = items;
or is the delegate method not even called?
i don't understand your wording...
I found the problem. I thick it all has to do with the delegate.self method. I read that using this in several places in your code is not the best thing and that the references easily can get messed up if you update and compile frequently. So i flushed all my old compiled data, and ran the app again from scratch and it worked!
I don't believe you ever define the delegate property, or a protocol for the delegate.
As such, you have no way of ensuring the view controller responds to the methods defined in the delegates protocol.
Can you see if the delegate method in the view controller ever gets called?
Instead of below code
if (self.delegate)
{
[self.delegate itemsDownLoaded:_locations];
}
Use
// Set the downloaded items to the array
_feedItems = [NSArray arrayWithArray:items];
// Reload the table view
[self.listTableView reloadData];
Or Change this line of code and check
Instead of
_feedItems = items;
Use
_feedItems = [NSArray arrayWithArray:items];
Hope it helps you...!

Why my custom protocol is not being call? Objective - C

I have 2 VC, one where the users write the data, with textfield or pickerview, and the main screen where i show the data on a tableview. The problem is that when i click on done button, it might call the delegate, but on the first vc, where is implemented, it doesnt receive any call. What should i do? I have been for 2 days trying to find the bug, and nothings happens. Thanks for any Help.
2VC.h
#protocol AddCountryDelegate <NSObject>
#required
-(void)didCreateCountry:(CountryClass*)country;
#end
#interface AddCountryViewController : UIViewController
#property (assign, nonatomic) id<AddCountryDelegate> customDelegate;
2VC.m
- (IBAction)actionDone:(id)sender {
NSString* itemName = self.itemNameTextField.text;
NSString* countryName = self.countryNameTextField.text;
NSDate *countryDate = [datePickerView date];
NSString *daysLeftString = [NSString stringWithFormat:#"%# days", self.daysLeftTextField.text];
NSInteger daysLeftInt = [daysLeftString integerValue];
NSNumber *daysLeft = [NSNumber numberWithInteger:daysLeftInt];
NSString *paymentMethod = self.paymentMethodTextField.text;
CountryClass* newCountryItem =
[[CountryClass alloc] initWithCountryName:countryName countryLogo:#"" itemName:itemName countryDate:countryDate daysLeft:daysLeft andPaymentMethod:paymentMethod];
[self.customDelegate didCreateCountry:newCountryItem];
[self dismissViewControllerAnimated:YES completion:nil];
}
And finally the implementation on the 1st VC:
-(void)didCreateCountry:(CountryClass *)country{
//Add new country-itemCountry - UPDATING OUR MODEL DATA
NSMutableArray *mutableCountries = [self.countries mutableCopy];
[mutableCountries addObject:country];
self.countries = [mutableCountries copy];
//UPDATING THE VIEW
[self.tableView reloadData];
NSLog(#"Created");
[self saveCountriesToDisc];
}
-(void)saveCountriesToDisc{
NSMutableArray* convertedCountries = [NSMutableArray array];
//Converting the model to dictionary
for(CountryClass *country in self.countries)
{
NSDictionary *convertedCountry = [shop countriesToDictionary];
[convertedCountries addObject:convertedCountry];
}
//NOW convertedShows CONTAINS ONLY STRINGS, NUMBERS,
//ARRAYS AND DICTIONARY
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = paths.firstObject;
NSString *destinationPath = [documentsDirectory stringByAppendingPathComponent:#"countriesListData.plist"];
//NOW TELL THE ARRAY TO SAVE
[convertedCountries writeToFile:destinationPath atomically:YES];
NSLog(#"Saved");
[self.tableView reloadData];
}
I initialize my delegate on the prepareforsegue
-(void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddSegue"]) {
AddCountryViewController* addCountryVC =
segue.destinationViewController;
addCountryVC.customDelegate = self;
}
where in VC1 did you set the customDelegate to self?
also you should set your delegate to weak not assign

Issue parsing JSON image url

I am trying to parse a JSON image url and display it in a view. I have no trouble getting the image url and converting it to UIImage. When the user selects a row in the tableview a new view is presented and displays the image from the url. The issue is that the image is different every time the view loads. I NSLog the url and it is the same every time I select the row. I can not see where I am going wrong here.
This is the view that gets the image url and converts it to an image:
// ViewController.m
#import "ViewController.h"
#import "DetailViewController.h"
#interface ViewController ()
#end
#implementation ViewController
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//imgURL = [imgURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *imageUrl = [NSURL URLWithString:[[_model.bars objectAtIndex:indexPath.row] objectForKey:#"image_url"]];
//NSLog(#"%#", imageUrl);
UIImage *barImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
NSLog(#"%#", imageUrl);
_model.barAddress = [NSString stringWithFormat: #"%# %# %#", [[_model.bars objectAtIndex:indexPath.row] objectForKey:#"address"],
[[_model.bars objectAtIndex:indexPath.row] objectForKey:#"state"],
[[_model.bars objectAtIndex:indexPath.row] objectForKey:#"zip"]];
_detailData.selectedBarName = [[_model.bars objectAtIndex:indexPath.row] objectForKey:#"name"];
_detailData.selectedBarAddress = _model.barAddress;
_detailData.selectedBarPhoneNumber = [[_model.bars objectAtIndex:indexPath.row] objectForKey:#"phone"];
_detailData.selectedBarImage = barImage;
NSLog(#"%#", _detailData.selectedBarImage);
if ([[segue identifier] isEqualToString:#"detailSeg"]) {
DetailViewController *controller = (DetailViewController *)segue.destinationViewController;
controller.barNameObject = _detailData.selectedBarName;
controller.barAddressObject = _detailData.selectedBarAddress;
controller.barPhoneNumberObject = _detailData.selectedBarPhoneNumber;
controller.barImageObject = _detailData.selectedBarImage;
NSLog(#"%#", controller.barImageObject);
}
}
#end
This is the view that displays the image.
// DetailViewController.m
#import "DetailViewController.h"
#import "DetailViewData.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
//_detailData = [[DetailViewData alloc] init];
_model = [[Model alloc] init];
// Do any additional setup after loading the view from its nib.
_barName.text = self.barNameObject;
_barAddress.text = self.barAddressObject;
_barPhone.text = self.barPhoneNumberObject;
_barPhoto.image = self.barImageObject;
}
Your code is absolutely correct.
So, I checked the web service response. If you check any of the image_URl
say http://lorempixel.com/900/500/sports/?v=-417059871 , it is loading different images all the time. I think the issue is not in your code but in the url, just paste it in your browser and refresh, each time it loads different images.
I wanted to add this as a comment but I don't have enough reputation as of now.

Passing a NSString to NSObject

I am having a hard time figuring out how to pass a NSString to a NSObject class.
I have a .h and .m file which is a NSObject and I need to pass a string from a UIViewController.
This is what I tried when pushing the view:
NSString *urlString = #"TextHere";
WXClient *svc = [[WXClient alloc]init];
svc.urlOne = urlString
And then, I am retrieving it this way:
#interface WXClient : NSObject {
NSString *urlOne;
}
#property (strong, nonatomic) NSString *urlOne;
and of course, then on the .m :
#synthesize urlOne;
Then to use the NSString:
NSString *urlString = [NSString stringWithFormat:urlOne];
NSURL *url = [NSURL URLWithString:urlString];
//blah blah blah blah... :D
}];
But for some reason it is returning null. I am able to use this method from viewController to viewController but to NSObject is not working :(
Any ideas?
Thanks!
Try this
WXClient *svc = [[WXClient alloc]init];
NSString *urlString = #"TextHere";
svc.urlOne = urlString;
Sorry didn't read question properly
If you are pushing/presenting view controller throug segue and you want to send some data to destination view contrller. Like you want to set some property, you need to implement this method. prepareForSegue:sender:.
In it you you can get destination viewController and set whatever property you want to.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"weatherWXID"]) {
WeatherViewController *vc = [segue destinationViewController];
NSString *urlString = #"TextHere";
WXClient *svc = [WXCLient new];
svc.urlOne = urlString
vc.wxclient = svc;
}
}

Resources