Wednesday, November 18, 2015

Catalog App Tutorial: Part 3

Hey again everyone! We finished part 2 in this series last night and I'm back to continue part 3. I'm sorry about how many parts this tutorial is being split into, but its kind of a large project that needs some time to develop. Anyway, we're going to make this UITableView begin to work tonight. First, we're going to start off with Parse.

Open up your web browser and head over to www.parse.com. Open up the project we created a couple of days ago and select the core button. This is where we will create our clothing objects. To the left there is going to be a little pane. In this pane, click on the "Add Class" button. Keep the selector on "Custom" and name the class Clothing. Now a whole new table will appear. Click on the "+ Col" button to create a new column. Make the column a string object and name it "name". Then create five more string objects and name them "price", "link", "type", "description", and "featured". Now create another column, but this time make the object type "PFFile". Name this object "pic1". Do this two more times and name the other objects "pic2" and "pic3". Now that we created all of the pieces of the object, we are going to create our first object. Press the "+ Row" button to add a new row to the table. Find a piece of clothing from the web that you like and put in the corresponding information. Make sure the link is valid. Also, to add an image, double click the area under the PFFile title that says "undefined". This will allow you to add an image from your computer. Once your done creating your object, open up your Xcode project.
Now, add the following import to your customCellFile.h and tableViewController.h files:

 #import <Parse/Parse.h>

This allows us to use the Parse SDK in the project. Now add the following property under the @interface section in tableViewController.m:

@property NSMutableArray *arrayOfClothes;

This creates an editable array that we will put all of our clothing objects into. Now add the following method somewhere the "viewDidLoad:" method.

-(NSMutableArray *)loadClothing
{
    
    NSMutableArray *clothesArray = [[NSMutableArray alloc]init];
    
    PFQuery *query = [PFQuery queryWithClassName:@"Clothing"];
    
    [query orderByDescending:@"createdAt"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        //3
        if (!error) {
            

            clothesArray = [NSMutableArray arrayWithArray: objects];
            [self.tableView reloadData];
            
            
        } else {
            
            //4
            NSString *errorString = [[error userInfo] objectForKey:@"error"];
            UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [errorAlertView show];
        }
    }];

    
    return clothesArray;
}

This method is what retrieves our "Clothing" class we just created and return all of the objects within that class. In order to make this method useful, we'll have to call it in "viewDidLoad:". Add the following line of code in the "viewDidLoad:" method.

self.arrayOfClothes = [self loadClothing];

This method makes "arrayOfClothes" hold what is returned by the method. This allows "arrayOfClothes" to hold all of the objects from Parse. Now that we actually have an array with items in it, find the method that is called "numberOfRowsInSection". After the part that says return, type out the code [self.arrayOfClothes count]. This line allows the table view to know how many rows to display on the table. Now we need to make the table view cell actually display some information. Find the method that is called "cellForRowAtIndexPath. Add the following code after the line that creates a new custom cell.

PFObject *clothing = [self.searchArray objectAtIndex:indexPath.row];
        NSString *name = [clothing objectForKey:@"name"];
        NSString *description = [clothing objectForKey:@"description"];
        NSString *price = [clothing objectForKey:@"price"];
        NSString *url = [clothing objectForKey:@"link"];
        PFFile *clothingFile = [clothing objectForKey:@"pic1"];
        PFFile *clothingFile2 = [clothing objectForKey:@"pic2"];
        PFFile *clothingFile3 = [clothing objectForKey:@"pic3"];
        NSString *clothingPicUrl = clothingFile.url;
        NSString *clothingPicUrl2 = clothingFile2.url;
        NSString *clothingPicUrl3 = clothingFile3.url;
        
        cell.imageArray = [NSArray arrayWithObjects:clothingPicUrl,clothingPicUrl2,clothingPicUrl3, nil];
        cell.clothingUrl = url;
        cell.currentObject = clothing;
        
        cell.nameLabel.text = name;
        cell.descriptionLabel.text = description;
        cell.priceLabel.text = price;

        [cell awakeFromNib];

This code sets all of the different labels we have equal to the info of our object in the database. It also creates an array of the three images we have for each object. This code will be used to display multiple images in the cell later. The part that says [cell awakeFromNib] is calling the method that loads up the cell in order to display an array of images within the cell. This call is normally not needed for simpler table view projects, however, this project make the table view cell handle a little more code. Now open up customTableViewCell.h.

Under the @interface section of the file, add the following properties.

@property PFObject *currentObject;
@property NSInteger currentIndex;
@property NSArray *imageArray;
@property NSString *clothingUrl;

The PFObject allows the cell to know what object we are looking at in the array, currentIndex is for displaying multiple images in one imageView, imageArray is the array that contains all of the images in the Parse database, clothingUrl holds the url for the object. Now open up the customTableViewCell.m file.

In the "viewDidLoad" method add the following code.

    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeImage:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.clothingImage addGestureRecognizer:swipeLeft];
    
    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeImage:)];
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [self.clothingImage addGestureRecognizer:swipeRight];
    
    self.currentIndex = 0;
    [self showImageAtIndex:self.currentIndex];
    self.control.numberOfPages = self.imageArray.count;

This code allows our UIImage on the cell to recognize swipe gestures that will change the pictures within the UIImageView. It sets the number of pages to be displayed from the number of objects in our array from Parse. It also sets the first index to 0 so we start at the first picture. Now we will add some more methods to help the swiping gestures work. At this time we will need to link another library to our project. This library is called SDWebImage. This lets us load images from the internet easily without taking too much data. It uses a process called "lazy loading" which sets an image that we already have on our device to the table view cell image while we're loading the real image from the internet. It also makes all of the image loading occur on a background thread. For now, search "SDWebImage iOS" in google and follow the installation instructions on their GitHub site.

Now that SDWebImage is hooked up, we can continue. Add the following methods under the "viewDidLoad" method.

-(void)showImageAtIndex:(NSInteger)index
{
    
    [self.clothingImage setImageWithURL:[NSURL URLWithString:[self.imageArray objectAtIndex:index]] placeholderImage:[UIImage imageNamed:@"Place Holder.jpg"]];
}

//method to detect swipes on mainImage
-(void)swipeImage:(UISwipeGestureRecognizer*)recognizer
{
    NSInteger index = self.currentIndex;
    
    if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft)
    {
        index++;
    }
    else if (recognizer.direction == UISwipeGestureRecognizerDirectionRight)
    {
        index--;
    }
    
    if (index >= 0 && index < ([self.imageArray count]))
    {
        self.currentIndex = index;
        [self showImageAtIndex:self.currentIndex];
        [self.control setCurrentPage:self.currentIndex];
    }
    else
    {
        NSLog(@"Reached the end, swipe in opposite direction");
    }
    
}

The "showImageAtIndex" method uses an SDWebImage method to set the correct image to the cell. The image file called "Place Holder.jpg" can be any image that you put into your project. Make sure the name matches exactly. The "swipeImage" method detects if the swipe is to the left or to the right and changes the index accordingly. It then displays the image at the corresponding index in the array. Now, if you run the application you should be able to see a table view with your object from Parse in it! Congratulations on displaying your first database item! Currently, the buy button, wish list button, and share button will not work, but we will hook those up within the next couple of tutorials. Take a break from coding and enjoy the progress you've made. We've gone through a lot of different topics in this one short section. I hope you enjoyed part 3 of this catalog app tutorial series! Remember to contact me if you have any questions and most importantly have a great night!

No comments:

Post a Comment