iloveios
iloveios

Reputation: 37

Displaying an URL from a different view controller in a UIWebView

   RecipesTableViewController.m

    #import "RecipesTableViewController.h"
    #import "RecipeTableViewCell.h"
    #import "IngredientsViewController.h"
    #import "Recipe.h"
    #import "RecipeDetailViewController.h"

    @interface RecipesTableViewController () {

        NSMutableArray *recipesArray;

    }

    @end

    @implementation RecipesTableViewController

    - (void)viewDidLoad {
        [super viewDidLoad];

//api from recipepuppy 
        NSString *recipeUrlString = [NSString stringWithFormat:@"http://www.recipepuppy.com/api/?i=%@",self.searchRecipe];

//adding percentage on the textfield when the user is searching
        NSString *formattedString = [recipeUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

//download data 
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString: formattedString]];


//put data into a dictionary
        NSDictionary *recipeDictinary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

//then put the dictionary into an array
        recipesArray = [[NSMutableArray alloc]init];
        for (NSDictionary *recipeDict in [recipeDictinary objectForKey:@"results"]) {


            Recipe *recipe = [[Recipe alloc]initWithTitle:[recipeDict objectForKey:@"title"] andRecipeIngredients:[recipeDict objectForKey:@"ingredients"] andImageURL:[NSURL URLWithString:[recipeDict objectForKey:@"thumbnail"]] andRecipeWebUrl:[recipeDict objectForKey:@"href"]];


            [recipesArray addObject:recipe];
            NSLog(@"%@", recipeDict);
        }
    }



    #pragma mark - Table view data source

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        // Return the number of sections.
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        // Return the number of rows in the section.

        return [recipesArray count];
    }


    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        RecipeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"recipeCell" forIndexPath:indexPath];

        [cell drawTheCell:[recipesArray objectAtIndex:indexPath.row]]; 

        return cell;
    }
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        if([segue.identifier isEqualToString:@"recipeDetail"]) {
            //NSIndexPath *indexPath =[self.tableView indexPathForSelectedRow];

            RecipeDetailViewController *recipeDetail = segue.destinationViewController;

            recipeDetail.title = @"Recipe";


        }

      }

    @end

Short Story: I’m making a recipe by ingredient for my class. I have a UITableViewControllre parsing content from an api and and I have the objects of the api in an array. In that array I have “results” and in those results I have urls, title, ingredients, and image of recipe. I want to send the url to a WebView into another view controller but I just can’t. Whenever I select the recipe the app crashes to view the webview. I been stuck on this for threes days and I’m so frustrated and I know the problem is my linking to the webview because the array prints the url but is not displayed on the webview.

this is my table view controller where my api is and the prepare for segue to the view controller where the webview is at.

    RecipeTableViewCell.m

    #import <UIKit/UIKit.h>
    #import "Recipe.h"

    @interface RecipeTableViewCell : UITableViewCell
    @property (strong, nonatomic) IBOutlet UILabel *recipeUrl;
    @property (strong, nonatomic) IBOutlet UILabel *recipeTitle;
    @property (strong, nonatomic) IBOutlet UILabel *recipeIngredients;
    @property (strong, nonatomic) IBOutlet UIImageView *recipeImage;

    -(void)drawTheCell:(Recipe *)recipeObject;

    @end

    RecipeTableViewCell.m

    -(void)drawTheCell:(Recipe *)recipeObject {

        self.recipeTitle.text = recipeObject.title;

        self.recipeIngredients.text = recipeObject.ingredients;

        self.recipeUrl.text = recipeObject.recipeWebUrl; 

        NSData *imageData = [NSData dataWithContentsOfURL:recipeObject.imageURL];
        self.recipeImage.image = [UIImage imageWithData:imageData];

    #import "RecipeDetailViewController.h"
    #import "RecipeTableViewCell.h"



    @interface RecipeDetailViewController ()
    @property (strong, nonatomic) IBOutlet UIWebView *recipeWebView;

    @end

    RecipeDetailViewController.m

    @implementation RecipeDetailViewController

    - (void)viewDidLoad {
        [super viewDidLoad];

        Recipe *recipe = [[Recipe alloc] init];

        NSURL *url = [NSURL URLWithString: recipe.recipeWebUrl];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        [self.recipeWebView loadRequest:request];


    }

    RecipeDetailViewController.h

    #import <UIKit/UIKit.h>

    @interface RecipeDetailViewController : UIViewController
    @property (nonatomic, strong ) NSString *recipeWebUrlString;

this is my cell and in here the title, ingredients, and image is displayed and it works fine.

Upvotes: 1

Views: 740

Answers (2)

Skyler Lauren
Skyler Lauren

Reputation: 3812

There is a long winded answer here but I will try to keep it short and hopefully it makes sense.

First I don't see where you are calling performSegueWithIdentifier: which means you are likely doing a segue from clicking the cell directly to the next view via storyboard. This is great for a simple button press but not ideal for selecting a cell that you need to send information from. I would recommend calling the segue in didSelectRowAtIndexPath:. The segue on the storyboard should go directly from one view controller to another and not directly from a table cell. Don't forget to set the identifier again.

Something like this to call the segue in code.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"recipeDetail" sender:nil]; //you could also pass the cell with if you want
}

Second in your prepare for segue you are not setting the URL you want and just setting the title of the next view controller. Looks like you were close to what you wanted because I can see you were already looking at the index path but commented it out. You should grab the cell there and set the url to the recipeDetail. You could also pass the cell via sender.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{

    if([segue.identifier isEqualToString:@"recipeDetail"]) 
    {
        NSIndexPath *indexPath =[self.tableView indexPathForSelectedRow];
        RecipeTableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

        RecipeDetailViewController *recipeDetail = segue.destinationViewController;

        recipeDetail.title = @"Recipe";
        recipeDetail.recipeWebUrlString = cell. recipeUrl.text;


    }
}

Third thing if all else fails start putting NSLogs everywhere. You can log the URL in the view did load in the next view and see that it isn't getting set. The next thing you should have been looking at where you are setting it, which appears to be no where as far as I can see =)

Also with all of that being said I would not relay on the text on the cell but instead grab the recipe from your array and pass that in the segue.

I hope that helps or at least gets you pointed in the right direction.

Upvotes: 1

Lyndsey Scott
Lyndsey Scott

Reputation: 37290

Skyler's answer's heading in the right direction, but it's missing a few critical pieces...

Yes, you need to pass the web url string in prepareForSegue: like he's suggesting, i.e.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{
    if([segue.identifier isEqualToString:@"recipeDetail"]) 
    {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        RecipeTableViewCell *cell = (RecipeTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];

        RecipeDetailViewController *recipeDetail = segue.destinationViewController;

        recipeDetail.title = @"Recipe";
        recipeDetail.recipeWebUrlString = cell.recipeUrl.text;
    }
}

but the problem is that you're not using that recipeWebUrlString to perform your url request.

Instead, you're creating an empty Recipe object in your .m and thus using an empty url to perform the web request, i.e.

Recipe *recipe = [[Recipe alloc] init];
NSURL *url = [NSURL URLWithString: recipe.recipeWebUrl];

Instead replace those two lines (^) with the following:

NSURL *url = [NSURL URLWithString:self.recipeWebUrlString];

in order to use the url you just passed in from the RecipesTableViewController.

Upvotes: 1

Related Questions