• What I Learned In My First Year Of iOS Consulting

    Wow, I can’t believe it has already been a full year since I struck it out on my own.  Last year, I published a post after my first month on doing contract iOS development.  Needless to say, I have grown and learned quite a bit over the past year and I wanted to share some of those experiences.

    Income

    While I won’t share exact numbers, I left my 6 figure/year job to pursue the indie/consulting life.  During the course of the year, I was able to amass 40% more income in 2013 than I had at my previous position.

    In addition to that, I had the time to launch a couple iOS applications and thus upping my Apple income by about 20% this year.

    Network Network Network

    I would say spending time networking and meeting people is just as important as being able to write code if you want to be successful on your own.  Through out the year, I dedicated at least five to ten hours a week just meeting with people, talking on the phone, and making new connections.

    Often times, I would get contract opportunities that I knew for sure that I wasn’t going to take; either because I didn’t love the project, or (more often than not) because I didn’t have the bandwidth to take them on.  However, rather than just writing the client back “I don’t have time“, I would take the call (or meeting in town), make the connection, and even listen to details about the contract.

    My wife would tell me to stop wasting my time and that those hours would be better spent on project work that actually made money.  However, these contacts are arguably more valuable than the hours “lost”.  In many situations, I have reached out to those potential clients weeks or months later once I hired a new developer and was then able signed a contract.  If I had declined the meeting to begin with, they probably wouldn’t have been as inclined to work with me so readily.

    Subcontractors

    Subcontracting has been a mixed bag for me.  It seems to be the only (safe-ish) way to expand your business as a consultant, other than hiring full time developers.  So, if you want to be able to work less yourself (which is almost never the case) or increase your companies revenue, you need to hire out.  

    Once I found the right people, subcontracting was a dream.  I was able to reach more clients, still deliver the same value in the work, and achieve the client’s goals, all while expanding my business.

    The main challenge I have had is deciding whether to hire subcontractors from here in the states or “offshore”.  They both have their benefits and complications. Here are some I have found:

    Benefits of hiring in the states:

    • Communication – Most of the time their timezones are close enough that one of you is not inconvenienced to communicate in real time.
    • Trust From Clients – Some clients still have some issues with “offshore”, especially because many of them have tried their hand at the ODesk lottery and have lost.  So, saying you have US based team members sometimes makes them more comfortable. It’s unfortunate, but I have seen it to be true in some cases.
    • Colleagues – Often times you already know or have worked with these guys since starting with acquaintances/friends is a good place to look for developers.

    Complications hiring in the states

    • Cost – US devs are expensive.  Most of the time they have full time jobs and want to do consulting on the side.  So it is important that they get paid more to do contract work than their day job pays.
    • Colleagues – This is on the negative list as well because hiring people you know can get weird if things go awry.

    **Benefit of Offshore developers **

    • Cost – I put this here, however that doesn’t mean I hire “cheap” developers.  Honestly, if you are not paying a contractor well, you are either under paying him and should give him a raise OR he shouldn’t be working for you as he’s probably too junior.
    • Perspective – I have some incredible developers in other countries that have taught me quite a bit whether it’s about development, process, culture, or even my own code.  It’s a great opportunity to learn.

    **Problems with Offshore developers **

    • Location – Timezone issues can be a problem if you let them.  For example, I have a developer who lives in a completely different timezone than my own.  However, he does a fantastic job of being available when he is needed.  I have had other instances where it was very challenging to reach my developer in an event where I needed information on short notice.
    • Vetting Process – Finding developers is a little more tricky.  With devs in the states, you can just head to a local meet up or conference, but finding GOOD “offshore” devs is a little trickier.  I have lucked out a few times, but for the most part it’s a bit more work.  I would suggest spending a little of your own money to adequately search and vet each candidate.
    • Language – While doing iOS development, you may need your client and your developer to communicate with one another.  That being said, it’s vital to find a developer who you can understand and who can understand you in order to make communication possible.

    Hiring An Assistant

    Taking a page from Tim Ferris’ 4 Hour Work Week, I decided to hire an assistant.  Ferris suggests “virtual”, however, I have hired one locally (she’ll be proofreading this post 😉 ).  I think it’s one of the best decisions I have made as a business owner.  Here is just a short list of things she handles for me:

    • Contracts
    • Invoicing
    • Payments of contractors
    • Research
    • Phone calls
    • Personal issues (like returns, purchasing equipment, etc.)

    Even if she saves me two hours per week, she has paid for herself, and believe me, she saves me much more than that.

    Never Decline A Contract

    I mentioned this earlier in the post, but I want to reiterate it here.  I seldom tell clients “no” and I really feel that it has worked out to my benefit.  At the very least, I hear them out and add them as a contact to keep in mind for the future.

    What I generally do when I can’t take on a client is I will give them an estimate of when myself or a member of my team will be available.  That way, if they are okay with the timeline, I can keep the pipeline open.  If not, there is no harm done.  Also, if I hire another developer before the time I said I was available, sometimes the client will still have the need and I am able to fill it.

    If I absolutely don’t have time or don’t want a particular contract, I will refer the client out to other dev shops.  I don’t look at this as competition, but rather opportunity as I would hope they would do the same for me one day.  As an added bonus, some of them have a referral fee so you can at least profit from pairing the client up.

    Taxes

    I have found out that taxes are less fun when you are self-employed than when you are employed by a business.  Luckily my wife is MUCH better at money management than I am, so she set up a separate tax account where roughly 40% of our income would go.

    One of the other good decisions I made besides hiring an assistant was hiring a CPA.  She has saved me countless hours and fees and is worth her weight in gold.

    Hire a CPA from day one; you will never regret it.

    Family

    I know this is a “business” related post, but I have to mention this.  Having a wife and kids, I am very much a family man.  Working for myself has been such a blessing since I have been able to spend considerably more time with my family than when I was employed by someone else.

    For example, if it’s a nice summer day and the family decides to head to the zoo, I can just go without asking a boss for time off or taking PTO.  I simply work in the evening or more hours the next day to recoup the time.  Personal time management is key to be able to have this kind of freedom.

    Summary

    Overall, 2013 was an incredible year.  While I did make mistakes (a ton), I gained so much knowledge and had a blast doing so.  Going solo isn’t for everyone (some days I wonder why everyone** isn’t** doing it, and others I wonder why I am), but it’s been one of the most exciting experiences of my life.

    I look forward to what 2014 brings and seeing how I can continue to grow my consultancy.

    Happy New Year and Happy Hacking!

    Tweet

  • iPhone Programming Tutorial: Creating An Image Gallery Like Over – Part 2

    Screen Shot 2013-08-09 at 8.36.42 PM

     

    Welcome to the second part of my tutorial series “Creating An Image Gallery Like Over”.  In this part of the tutorial, you will learn how to actually display the photos in the UICollectionView as well as give the user the ability to take photos with their camera.

    If you haven’t already done so, please go back and complete part 1.

    1. Custom UICollectionViewCell

    Start by creating a new subclass of UICollectionViewCell and naming it **PhotoCell.  **Now, open up PhotoCell.h and add the following code:

    #import <AssetsLibrary/AssetsLibrary.h>
     
    @interface PhotoCell : UICollectionViewCell
    @property(nonatomic, strong) ALAsset \*asset;
    @end
    

    |

    Now, open PhotoCell.m and add the following code:

    #import "PhotoCell.h"
     
    @interface PhotoCell ()
    // 1
    @property(nonatomic, weak) IBOutlet UIImageView \*photoImageView;
    @end
     
    @implementation PhotoCell
    - (void) setAsset:(ALAsset \*)asset
    {
        // 2
        _asset = asset;
        self.photoImageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
    }
    @end
    

    |

    1. This is an **IBOutlet **to a UIImageView that we will create inside of the Storyboard
    2. We overwrite the setter method for the asset in order to convert the asset’s thumbnail into a UIImage and set it to the contents of the UIImageView

    Now that we have the custom cell created, we need to hook it up and create the UIImageView inside of Storyboard.  Open **MainStoryboard.storyboard **and click on the default UICollectionViewCell inside of your UICollectionView.

    It might be tricky to see the cell as it has a white background and blends in, but it’s there.

    Screen Shot 2013-07-24 at 6.43.38 PM

    Now, click on the Identity Inspector from the right side bar and change the class to PhotoCell.  This will inform interface builder that this object is of the type PhotoCell and let us hook up the photoImageView outlet.

    Screen Shot 2013-07-24 at 6.46.35 PM

    Next, open the size inspector, change the size to **Custom, **the width to **104 **and the height to 104.  This will give us nice sized images, with a good amount of padding between them.

    Screen Shot 2013-07-24 at 6.49.51 PM

    The UICollectionView will overwrite these sizes, so we need to change it in one other location.  To ensure that the cells stay the correct size, click on the Collection View in left side bar and open it’s Size Inspector.  Then set the Cell Size width and height to 104.

    Screen Shot 2013-07-24 at 7.07.14 PM

    The final step here is to drag a UIImageView on to your cell (scaling it to fit the entire cell size), and hook up the IBOutlet to the photoImageView. Do this by control-click and dragging from Photo Cell to the ImageView and selecting photoImageView.

    Screen Shot 2013-07-24 at 6.52.32 PM

    If you build and run at this stage, nothing will be different.  That’s because we still need to tell the ViewController class about our new PhotoCell.  Open **ViewController.m **and import PhotoCell.h.

    #import "PhotoCell.h"
    

    |

    Now, head down to the collectionView:cellForItemAtIndexPath method and replace the contents of it with the following code:

    - (UICollectionViewCell \*) collectionView:(UICollectionView \*)collectionView cellForItemAtIndexPath:(NSIndexPath \*)indexPath
    {
        PhotoCell \*cell = (PhotoCell \*)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
     
        ALAsset \*asset = self.assets[indexPath.row];
        cell.asset = asset;
        cell.backgroundColor = [UIColor redColor];
     
        return cell;
    }
    

    |

    What’s changed here is, we are now telling the UICollectionView that the cell it’s returning is of the type PhotoCell. Also, we are fetching the ALAsset out of our array at each index and sending it to the cell so that it can display it’s thumbnail.

    Build And Run!

    Screen Shot 2013-07-24 at 7.10.39 PM

    Whoohoo**! **You should now see your photos populating the **UICollectionView. Congratulations! 

    While, this is definitely cool, you might now be wondering “how do I select a photo?”.  Great question, and here is the solution.

    2. Selecting Photos

    Now that you have all of the groundwork in place, selecting photos from the collection could not be easier.  Open up ViewController.m and replace the **collectionView:didSelectItemAtIndexPath **method with the following code:

    - (void) collectionView:(UICollectionView \*)collectionView didSelectItemAtIndexPath:(NSIndexPath \*)indexPath
    {
        ALAsset \*asset = self.assets[indexPath.row];
        ALAssetRepresentation \*defaultRep = [asset defaultRepresentation];
        UIImage \*image = [UIImage imageWithCGImage:[defaultRep fullScreenImage] scale:[defaultRep scale] orientation:];
        // Do something with the image
    }
    

    |

    This will get the selected asset and convert it to a UIImage. You are now free to use the UIImage how you want. Perhaps you create a protocol for this class and make a callback to a delegate OR maybe you add this to a UINavigationController stack and push a new view controller on to the stack containing this image. The sky is the limit!

    If you look at the Over app and back to your image gallery that you just created, you will notice something is still missing.  What if the user wants to take a photo or access other albums?  This is where Over adds a bar across the top of the interface with 2 buttons that fall back to the “default” style of fetching images if the user wants to take a photo or access a different photo album.  Let’s build this out now.

    3. Building The Interface To Take Photos And Access Albums

    Start by setting up the IBActions for theses buttons.  Open ViewController.m and add the following empty methods:

    #pragma mark - Actions
     
    - (IBAction)takePhotoButtonTapped:(id)sender
    {
     
    }
     
    - (IBAction)albumsButtonTapped:(id)sender
    {
     
    }
    

    |

    We don’t need to add the code yet since we still need to build the UI and hook up the IBOutlets. Now open **MainStoryboard.storyboard **and drag a **UIView **right on top of your UIView.

    One issue you might run in to here is the view will want to become a subview of the collection view.  To combat this, drag the view outside of the collection view inside the left bar so the hierarchy will look like this:

    Screen Shot 2013-07-25 at 12.35.06 PM

     

    One other “gotcha” is, you must ensure that the view is positioned below the collection view in this list, otherwise it won’t show above it on screen.

    Now, let’s manually size and position the view as Interface Building will make things hard on us if we want to position it over our collection view.

    Select the view and open the Size Inspector. Set the values as follows:

    Screen Shot 2013-07-25 at 12.44.23 PM

     

    Again, remember this positioning is optimized for the iPhone 5. So make sure you are testing with that simulator or you won’t see this bar.

    After this, the bar still won’t be visible inside of Interface Builder.  We need to set the background color to black with some transparency.  Open the Attributes Inspector and click on the background color.  Then set the color to black with 80% opacity:

    Screen Shot 2013-07-25 at 12.40.13 PM

     

    You should now see the bar positioned on the screen like this:

    Screen Shot 2013-07-25 at 12.41.54 PM

     

    Now drag a **UIButton **on to the view you just created. There are a few things that must be done to style the button:

    1. Position it at 0,0
    2. Set the width to 160px and the height to 70x
    3. Change the type to custom
    4. Change the text to “Take Photo”
    5. Change the font to “Helvetica Neue Condensed Black” size 20
    6. Set the text color to white

    When you have completed these steps, the button should look like this:

    Screen Shot 2013-07-25 at 12.47.26 PM

     

    Now, hook up the IBAction by opening the Connections Inspector and dragging from Touch Up Inside to the View Controller object and selecting takePhotoButtonTapped:

    Finally, duplicate this button (copy and paste), rename the title to “Albums”, move it next to the “Take Photo” button and hook its Touch Up Inside to albumsButtonTapped:

    The final Interface should look like this:

    Screen Shot 2013-07-25 at 12.51.25 PM

     

    Go ahead and do a Build and Run and this stage and marvel at your interface development prowess!

    4. Actually Taking Photos And Accessing Albums

    The final step for this tutorial is to implement the code to bring up the camera as well as bring up the photo albums.  Let’s start with the camera.  Open ViewController.m and add the following code to the takePhotosButtonTapped: method:

    - (IBAction)takePhotoButtonTapped:(id)sender
    {
        if (([UIImagePickerController isSourceTypeAvailable:
              UIImagePickerControllerSourceTypeCamera] == NO))
            return; // 1
     
        // 2
        UIImagePickerController \*mediaUI = [[UIImagePickerController alloc] init];
        mediaUI.sourceType = UIImagePickerControllerSourceTypeCamera;
        mediaUI.allowsEditing = NO;
        mediaUI.delegate = self;
        // 3
        [self presentViewController:mediaUI animated:YES completion:nil];
    }
    

    |

    1. Makes sure that the photo library is available.  If the user declines photo access, this will be the case.
    2. Create the UIImagePickerController and set its source type to UIImagePickerControllerSourceTypeCamera.  This lets the media picker know to use the camera and not the image library.
    3. Finally, present the view controller modally

    The method to bring up the photo albums is almost identical to the method above.  Add the following code to the albumsButtonTapped: method.

    - (IBAction)albumsButtonTapped:(id)sender
    {
        if (([UIImagePickerController isSourceTypeAvailable:
              UIImagePickerControllerSourceTypePhotoLibrary] == NO))
            return;
     
        UIImagePickerController \*mediaUI = [[UIImagePickerController alloc] init];
        mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;    
        mediaUI.allowsEditing = NO;
        mediaUI.delegate = self;
        [self presentViewController:mediaUI animated:YES completion:nil];
    }
    

    |

    As I said before, this method is almost identical with the only difference being, we are using **UIImagePickerControllerSourceTypePhotoLibrary **to open up the photo albums.

    Build and Run and tap the “Take Photo” button. Make sure you are testing on the device at this stage or nothing will happen since the simulator doesn’t have a camera.  You can however test the “Albums” button assuming you have some photos in your photo library.

    Now that you are able to pick a photo, you need to be able to access the photo that was selected or taken.  To do this implement the following delegate method for UIImagePickerController.

    #pragma mark - image picker delegate
     
    - (void) imagePickerController:(UIImagePickerController \*)picker didFinishPickingMediaWithInfo:(NSDictionary \*)info
    {
        UIImage \*image = (UIImage \*) [info objectForKey:
                                              UIImagePickerControllerOriginalImage];    
        [self dismissViewControllerAnimated:YES completion:^{
            // Do something with the image
        }];
    }
    

    |

    This method fetches the selected (or taken) image and stores. It then dismisses the camera or photo albums allowing you to do whatever is needed with the image.

    5. Next Steps

    By now, you should have learned how to use the **ALAssets **library to interact with a user’s photos and use them to build a custom interface. You also learned how to use a UICollectionView to display a grid of photos.

    With this knowledge in hand, you should now be able to make much more interesting photo selection interfaces than the default one Apple has to offer.  Other apps like Google+ and Instagram both have very slick photo pickers and I hope this tutorial has your gears going thinking about other interesting photo selection interfaces.

    You can download the source from this tutorial on GitHub

    Feel free to leave a comment if you have any questions. Happy Hacking!

     

    Tweet

  • iPhone Programming Tutorial: Creating An Image Gallery Like Over &#8211; Part 1

    Screen Shot 2013-08-09 at 8.36.42 PM

     

    Recently, I have had to build an app (download link) that required the user to choose a photo from their photo library.  Rather than just throwing up a UIImagePickerController like many apps, I decided to add a little bit of style.  Being inspired by Over’s ultra simplistic (and beautiful) photo selection interface, I decided to fancy things up a bit.

    For this tutorial, I will start with a Fresh iOS6 View-Based application that uses Storyboards and ARC. Also note that I will be optimizing for the iPhone 5 resolution.  You are free to make the tweaks necessary to deploy on the iPhone 4 and 4S.

     

    Here is a breakdown of what we will cover in this part:

    1. Creating a UICollectionViewinside of Storyboard
    2. Using the ALAssetsLibrary to fetch photos from the user’s Camera Roll
    3. Displaying the ALAssets inside of the UICollectionView

    1. Preparing The IBOutlets

    Start by opening up **ViewController.m **and replacing the @interface declaration at the top with the following code:

    @interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
    @property(nonatomic, weak) IBOutlet UICollectionView \*collectionView;
    @end
    

    |

    This will declare the **IBOutlet **needed to hook up the main UICollectionView that we will be using to display the user’s photos.  I have also set up our class to be a UICollectionViewDataSource, UICollectionViewDelegate, and UICollectionViewDelegateFlowLayout. This is necessary when interfacing with the UICollectionView.

    2. Setting Up The UICollectionView In Storyboard

    Open up **MainStoryboard.storyboard **and drag a UICollectionView on to your view ensuring that it stretches the entire screen.

    Screen Shot 2013-07-21 at 8.44.02 PM

    Then, Control-Click and drag from the **UICollectionView **to your **ViewController **Object and set it as the **delegate **and datasource.

    Screen Shot 2013-07-21 at 8.41.29 PM

    Finally, **Control-Click **and drag from **View Controller **to Collection View and selected **collectionView **to make the **IBOutlet **connection.

    Screen Shot 2013-07-21 at 8.45.05 PM

    Now, we need to give a Cell Identifier to the UICollectionViewCell so that we can reference it in code.  Click on the default cell inside of the UICollectionView and open the **Attributes Inspector. **For the Identifier type in PhotoCell. The cell might be a little tricky to see as its background color is clear, but it’s there. Simply click in the top left corner of the UICollectionView.

    Screen Shot 2013-07-21 at 9.13.08 PM

    Now that the UICollectionView has been set up, it’s time to fetch the photos from the user’s photo library.

    If you are using the simulator, make sure to populate the Photo Gallery with images from the web. Simply open up a browser, do a Google Image Search, and click and hold on various images. You should have an option from the menu that pops up to save the images to your camera roll.
    Finally, open up the **Photos** app on the simulator to initialize the Assets Library.
    

    3. Fetching ALAssets (user photos) From The ALAssets Library

    In order to interface with the user’s photo library, we must first import the **AssetsLibrary.framework **framework.  To do this, click on your project in the sidebar, select the Target, then click **Build Phases, **expand the Link Binary With Libraries section and click the **+ **button.  Do a search for **Assset **and then double click on AssetsLibrary.framework.

    Screen Shot 2013-07-21 at 8.57.37 PM

    It should now be added to your project and ready to use.  Now that it has been linked, we must import it into the **ViewController.m **file.  Open up **ViewController.m **and add the following import to the top of the file:

    #import <AssetsLibrary/AssetsLibrary.h>
    

    |

    Before we can fetch the user’s photos, we need to set up an NSArray to put them in.  Add the following line within the **@interface **declaration at the top.

    @property(nonatomic, strong) NSArray \*assets;
    

    |

    Now, add the following method to your class:

    + (ALAssetsLibrary \*)defaultAssetsLibrary
    {
        static dispatch_once_t pred = ;
        static ALAssetsLibrary \*library = nil;
        dispatch_once(&pred, ^{
            library = [[ALAssetsLibrary alloc] init];
        });
        return library;
    }
    

    |

    This is a static method that creates a static instance to the ALAssetsLibrary.  The reason this is needed is, when we enumerate the ALAssets in the next method, it seems that the assets get released immediately and otherwise wouldn’t be able to be used in the rest of the application. I will explain this a little more in a moment.

    Head over to viewDidLoad and add the following code:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
     
        _assets = [@[] mutableCopy];
        __block NSMutableArray \*tmpAssets = [@[] mutableCopy];
        // 1
        ALAssetsLibrary \*assetsLibrary = [ViewController defaultAssetsLibrary];
        // 2
        [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup \*group, BOOL \*stop) {
            [group enumerateAssetsUsingBlock:^(ALAsset \*result, NSUInteger index, BOOL \*stop) {
                if(result)
                {
                    // 3
                    [tmpAssets addObject:result];
                }
            }];
     
            // 4
            //NSSortDescriptor \*sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
            //self.assets = [tmpAssets sortedArrayUsingDescriptors:@[sort]];
            self.assets = tmpAssets;
     
            // 5
            [self.collectionView reloadData];
        } failureBlock:^(NSError \*error) {
            NSLog(@"Error loading images %@", error);
        }];
    }
    

    |

    1. Grab our static instance of the ALAssetsLibrary
    2. Enumerate through all of the **ALAssets **(photos) in the user’s Asset Groups (Folders)
    3. Enumerate each folder and add it’s **ALAssets **to the temporary array
    4. Sort the assets list by date (this won’t work yet, but I will show you how to fix later). For now this code is commented out and the Assets will be sorted however they come out.
    5. Reload the UICollectionView (this won’t work yet as we haven’t set up the delegate methods)

    Now that we have an NSArray populated with ALAssets, let’s set up the **delegate **methods for the UICollectionView in order to populate it with data.

    4. Populating the UICollectionView With Data

    UICollectionView functions much like a **UITableView **having delegate and datasource methods.  Add the following methods to your ViewController class to populate the view.

    #pragma mark - collection view data source
     
    - (NSInteger) collectionView:(UICollectionView \*)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return self.assets.count;
    }
     
    - (UICollectionViewCell \*) collectionView:(UICollectionView \*)collectionView cellForItemAtIndexPath:(NSIndexPath \*)indexPath
    {
        UICollectionViewCell \*cell = (UICollectionViewCell \*)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
     
        ALAsset \*asset = self.assets[indexPath.row];
        //cell.asset = asset;
        cell.backgroundColor = [UIColor redColor];
     
        return cell;
    }
     
    - (CGFloat) collectionView:(UICollectionView \*)collectionView layout:(UICollectionViewLayout \*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
    {
        return 4;
    }
     
    - (CGFloat) collectionView:(UICollectionView \*)collectionView layout:(UICollectionViewLayout \*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
    {
        return 1;
    }
    

    |

    This code should be fairly straight forward if you have ever worked with a UITableView.  The only lines to note are where ‘cell.asset = asset’ is commented out and we set the cell’s background color to red.  We will uncomment that line when we create a custom cell to display the image (for now it won’t).  I have also set the background color to red so that you can see that the number of cells is actually corresponding to the number of photos in the camera roll.

    Build and Run!

    Let’s take a break to do a build and run to see what happens.  If you have hooked everything up correctly, you should see a black screen with red squares on it with a count equalling the number of photos in the user’s library.

    Screen Shot 2013-07-21 at 9.26.07 PM

    Not too exciting, however it shows that we are displaying a number of cells corresponding to the number of photos in the user’s asset library.  At least it’s showing that you have done something.  The next step is to create a custom UICollectionViewCell that actually displays the photos, which we will do next time.

    5. Next Time

    That’s all for today.  In a ploy to get you to come back to my site (and subscribe to my RSS feed), I have chosen to break this post up into two parts.

    Luckily for you, I wrote the above message a while ago. Click the link below to go to part 2!

    iPhone Programming Tutorial: Creating An Image Gallery Like Over – Part 2

    Stay tuned!

    Tweet

subscribe via RSS