• Digitally Downloaded Games

    With the release of the new generation of game consoles I adopted a new policy to only digitally download games instead of buying physical discs. I’ve never been a fan of physical media and hated having to go to a store and purchase game. Video Games are the most painful to buy in store because every GameStop I went to had two things in common. First are little kids whining to their parents to buy them a $60 game and the constant harassing to pre-order a game or buy some add-on for something I don’t care about. To not deal with this I have only purchased games for my Xbox One digitally. At first it was great and made me more willing to buy games since I didn’t need to go to a store and deal with the in-store environment. This allowed me to essential hide my Xbox from my TV area since I don’t have to put discs in when I want to play a game, which is a small and lazy thing but something I like.

    This all changed with the release of Destiny. I played Destiny during the beta period and loved it, so when the game was released early last week I purchased the game and season pass for $98. It was great because the game pre-downloaded to my Xbox and was ready to play right away. After playing for a couple of hours I quickly changed my mind about Destiny and found the game very repetitive and lacking of a good storyline.

    The issue is that I can’t return the game or trade the game in to help recoup the initial cost. And I fully understood this going into only buying digital downloads, but there should be some kind of system to help reduce the price of digital downloads. The best solution right now seems to be what EA is trying out with a subscription based service for games, similar to Netflix with their streaming service. I think going forward digital streaming services for games will become much more requested and used since it is a good balance of digital games and the ability to reduce the price of video games. To make this work though the game publishers will probably have to take a pricing hit since most new games are around $60 and the subscription service will have to be below that for there to be any hope of success in these new subscription services.

  • Swift-2 Months Later

    The first language I had ever written any code in was Objective-C. I taught myself everything about Objective-C that I could find in online tutorials, books, and Apple documentation. Being my first language, I thought Objective-C was the best language and nothing would come close to it. Even after I expanded out and taught myself PHP, Ruby, and JavaScript I always thought Objective-C was the most well rounded and complete language. I was also writing Objective-C when there was no such thing as ARC and you had to manually manage your memory. Even with its shortcomings, I loved Objective-C and everything you could do with it and how easy it was for me to pick up.

    When Swift was announced in June at WWDC I was not as excited as others were about a new programming language. Throughout my four years of Objective-C development I had never come across anything that I would have blamed Objective-C for, most of my blame went to the Cocoa/Cocoa Touch APIs. While I had little excitement for Swift, I did download the The Swift Programming Language iBook and started to play around with Swift in Xcode Playgrounds. And while there were plenty of shortcuts to make things “easier” to write, nothing stood out to the point where I wanted to drop everything and start writing Swift only. I also wasn’t getting excited since Apple said they would be changing the syntax based on developer feedback, which was great for the language and really helped it grow in the past two months. The last thing that held me back was I wanted to write an App that used some of the new Extension functionality of iOS 8 and Yosemite, but every time a issue/bug came up it was difficult to figure out if it was a Swift language issue, beta OS limitation, or me writing buggy code. After a few weeks I decided to put Swift aside and continue to write Objective-C code.

    It wasn’t until a week ago that I had some free time and re-downloaded the The Swift Programming Language and Using Swift with Cocoa and Objective-C iBook along with the latest Xcode. This time when I used Swift I quickly found myself loving the shortcuts and the various improvements it has over Objective-C and found myself wanting to convert some of my projects over to Swift. I’ve even had issues going back to Objective-C for work projects since I would try to write Swift code and it would cause errors, mainly me not adding a semicolon. Over the past two months Swift has matured and I can’t wait to see how it grows over its life.

  • Pinball Map

    3 Months, 197 commits, 13061 additions and 17107 deletions. These are the pull request statistics for Pinball Map, an app I have been working on for the past 3 months with two other developers.

    This app represented a lot of firsts for me as a developer. My first time working with other developers/designers, who were great during the entire development process, that I did not know from my current job. First time contributing to a Rails app to help build the public Pinball Map API that powers the app. First time I had a formal set of testers and proper beta releases, actually 6 beta releases to be exact. Overall it was a great experience and can’t wait to ship the next version.

    The app is available in the App Store and a gallery of screenshots are below.

  • Auto Layout Animation

    When switching from springs and struts to Auto Layout in a recent project I found that my animations would occasionally break. For the longest time I always used animateWithDuration:animations: to alter the frame of a view. However, when you want to animate a view controlled by Auto Layout the process is a little different and requires some setup first.

    Example

    Below is the type of animation we are trying to accomplish.

    Springs & Struts

    To accomplish this animation simply wrap the frame code inside of an animateWithDuration:animations: block.

    [UIView animateWithDuration:0.5 animations:^{
    	_sideView.frame = CGRectMake(-320, 0, 320, 480);
    }];

    Auto Layout

    The first step to animating in Auto Layout is to ensure that your view is properly setup with all necessary constraints. Once that is setup you will need to create a reference to the constraint that you will want to animate. In this example you will need to create a reference to the constraint that controls the space between the left side of a view and it’s superview. If you are using Interface Builder to setup your constraints, simply make an IBOutlet to the constraint in your View Controller.

    @property (nonatomic) IBOutlet NSLayoutConstraint *leftSide;

    After making the connection you are now ready to animate the view. You will first set the new constant for the constraint, then in your animateWithDuration:animations: block you will call its superviews layoutIfNeeded. It is important to call the proper view that is controlling the layout of the animated view. In this example we would call it on self.view since it is controlling the layout of the constraint.

    _leftSide.constant = -320;
    
    [UIView animateWithDuration:0.5 animations:^{
    	[self.view layoutIfNeeded];
    }];

    While animating Auto Layout does require more setup, the code is a little more straight forward and cleaner than Springs & Struts code.

  • Auto Layout In Code

    Recently I had to learn how to setup Auto Layout constraints within code. The usual method of setting up Auto Layout is through a storyboard with Interface Builder. Apple has documentation on how to write constraints in code, but I thought they fell short on providing real world examples. I still highly recommend reading the documentation since it does describe what the syntax is for writing these constraints in more detail than this post will.

    Setup

    There are two very important steps to do before writing constraints.

    • Set “translatesAutoresizingMaskIntoConstraints” to false on the view you plan on applying constraints to. If you do not set this property on the view, nothing will work properly due to conflicting constraints.
    • Add the view to your superview before applying the constraints.

    Stretch to fill screen

    The first example is applying constraints to a table view. When you turn your device, and you support landscape orientation, the expected behavior is for the table view to expand and fill the entire screen. To do this within code, setup two constraints on the superview for the horizontal and vertical alignment. First the horizontal code:

    NSArray *horizontalTable = [NSLayoutConstraint 
    	constraintsWithVisualFormat:@"H:|-(0)-[table]-(0)-|" 
    	options:NSLayoutFormatAlignmentMask 
    	metrics:nil 
    	views:@{@"table": self.tableView}];
    	

    The VisualFormat parameter is what defines the rule. The basic format for a constraint is “Orientation:Secondary View-(Constant)-[Primary View]-(Constant)-Secondary View”.

    • Orientation: Either “H” or “V” for horizontal and vertical.
    • Secondary View: The view to the left and right for horizontal constraints, or directly above and below for vertical constraints.
    • Constant: The actual value for the constraint to follow.
    • Primary View: The view we want the constraint to apply to.

    This format string is essentially saying to keep 0 pixels between the table and the superview on the left and right side.

    With the hard part over, there are just a few more parameters.

    • The options parameter should be set to “NSLayoutFormatAlignmentMask”, since we are defining both left and right constraints.
    • For this example, metrics does not need to be set.
    • The last important part of the constraint is the “views” dictionary. This is where you link your format string to actual views. In the format string we declared “table” as a view, so we need to link that to an actual view in our view hierarchy. To create this link we pass a dictionary with a key “table” then pass our actual table as its value.

    Once you have setup the horizontal constraint, the vertical constraint is very similar. The main difference is the use of “V” instead of “H”.

    NSArray *verticalTable = [NSLayoutConstraint 
    	constraintsWithVisualFormat:@"V:|-(0)-[table]-(0)-|" 	options:NSLayoutFormatAlignmentMask 
    	metrics:nil 
    	views:@{@"table": self.tableView}];

    To apply these constraints we add them to the superview since it is taking care of the layout in this example.

    [self.view addConstraints:horizontalTable];
    [self.view addConstraints:verticalTable];

    If you run your project and rotate your device, you will see that the table will stretch to fill the screen as expected.

    Bottom Toolbar

    When you have a toolbar within a view it usually belongs fixed to the bottom of the view.

    The first constraint will be for the horizontal alignment, which will look similar to the table view horizontal constraint.

    NSArray *horizontalToolbar = [NSLayoutConstraint 
    	constraintsWithVisualFormat:@"H:|-(0)-[toolbar]-(0)-|" 
    	options:NSLayoutFormatAlignmentMask 
    	metrics:nil 
    	views:@{@"toolbar": actionsBar}];

    The vertical alignment is a little bit different since we want the view to be pinned to the bottom of the view.

    NSArray *verticalToolbar = [NSLayoutConstraint 
    	constraintsWithVisualFormat:@"V:[toolbar]-(0)-|" 
    	options:NSLayoutFormatAlignAllBottom 
    	metrics:nil 
    	views:@{@"toolbar": actionsBar}];

    The difference here is that we only have the superview pipe character as the last item. This is because we want the view pinned to the bottom of its superview.

    Now add the constraints to the superview and run the app. You should have a toolbar that is pinned to the bottom of the view.

    Conclusion

    While working with Auto Layout in code is not as easy compared to creating them in Interface Builder, it is still very useful to know in case you ever want to create a view in code rather than in a storyboard or nib.

  • BorderButton CocoaPod

    This week I released a new CocoaPod called BorderButton for iOS. When iOS 7 launched and I was updating apps, I found that the new iOS 7 style button was the worst change in iOS 7. The new default button of iOS 7 did not have a border, which caused confusion to some users since they did not know where to tap and thought the button was text. BorderButton solves this issue by taking the text color attribute of the button and creating a border around the button with the same color. What is nice about this subclass is that all you have to do is change the class name in Interface Builder and BorderButton takes care of everything for you. For instance, the class will automatically draw a circular border around a button if the width and height are the same.

    You can install BorderButton by adding it to your Podfile ‘pod BorderButton’ or by going to GitHub. Hopefully you find it as useful as I do.

  • Core Data

    I have almost completely moved from a SQLite/FMDB setup to Core Data in my iOS apps. The main reason for this switch was due to how easy it is for me to get Core Data setup and have a nice object backed database. If you have read anything about Core Data in the past, great post by Brent Simmons talking about when he tried Core Data, you will know that depending on what app you are building Core Data can either be a godsend or a massive pain. For the types of apps I write Core Data works perfectly, and I still leave open the possibility to change from Core Data to SQLite/FMDB at any point if I find the switch worthwhile.

    With that being said there are a few things that I miss a lot from the SQLite/FMDB setup and really wish Apple would fix. The biggest issue surfaces when you try to bulk update/delete records from the database. When you want to delete all records from a table with FMDB the code looks similar to this.

    if ([appDatabase open]){
        [appDatabase executeUpdate:@"DELETE FROM Checkins WHERE 1"];
        [appDatabase executeUpdate:@"DELETE FROM Events WHERE 1"];
    }

    On Core Data though you first must load all the instances of the object in the database then iterate over each and delete them.

    NSFetchRequest *eventFetch = [NSFetchRequest fetchRequestWithEntityName:@"Event"];
    NSFetchRequest *checkinsFetch = [NSFetchRequest fetchRequestWithEntityName:@"Checkin"];
    NSArray *events = [[[CoreDataManager sharedInstance] managedObjectContext] executeFetchRequest:eventFetch error:nil];
    NSArray *checkins = [[[CoreDataManager sharedInstance] managedObjectContext] executeFetchRequest:checkinsFetch error:nil];
    [events enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    	[[[CoreDataManager sharedInstance] managedObjectContext] deleteObject:obj];
    }];
    [checkins enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    	[[[CoreDataManager sharedInstance] managedObjectContext] deleteObject:obj];
    }];
    [[CoreDataManager sharedInstance] saveContext];

    Core Data should have some kind of method that allows for the ability to remove or update all objects based on a NSPredicate, or something new, without the need to iterate over each item. I would even be fine with the ability to call deleteObjects: and pass in an array of objects over what you currently have to do. With WWDC 2014 coming up hopefully we will see some improvements to Core Data.

    Side Note: You should really read Brent’s posts about his work with setting up sync for Vesper, it is one of the best developer diaries on the web.

  • Weekend Project

    I had some free time this past weekend, so I thought I would create a little unofficial demo app for the Achievement Hunter website. I’ve been working on getting all the achievements in my 360 games and wanted an easy way to track the achievements without opening up the Xbox guide or having a laptop next to me.

    The app lists all the recent game guides from Achievement Hunter and allows you to easily search to find a game. In the game profile you see the main image, title, achievements, and associated Achievement Hunter videos. You can easily scroll through all the achievements to see their image, title, and description. When an achievement has been completed its cell is turned green. When you tap an achievement its profile gives the full description, if it is single or multiplayer, difficulty, and a link to any video guides for the achievement. Once you have completed an achievement you just swipe the cell to mark it as completed. Along with the achievement list, the profile shows any Achievement Hunter videos that are associated with the game and allows you to easily watch them from within the app.

  • comiXology In-App Purchase

    On Saturday comiXology, the large comic reading/purchasing mobile app, removed the option to buy comics through In-App purchasing. Customers will now have to go to comiXology’s website to purchase comics, then be redirected back to the app to read it.

    I have used comiXology in the past and loved it, mainly for its ability to purchase comics from the app with my Apple ID. I would imagine that many people liked the convenience of not having to give out their credit card information and create a comiXology account to buy comics.

    ComiXology is adding another step to their customers checkout process, something that should never be done. In-App purchasing allowed customers to easily buy a comic, since they did not have to complete a traditional checkout process. New customers, who just got their iPad for instance, will have to leave the app, go to comiXology’s website, select a comic, create an account, and enter in their payment information. The process before this change required the customer to open the app, select a comic, and enter their Apple ID password. It didn’t require them to have their payment information on hand, or create a new account with comiXology.

    In the long term they have removed Apple and Google from taking their cuts for In-App purchasing, but complicated the buying experience for their customers. It should be noted that comiXology was purchased by Amazon last month.

  • Helpful Development Links

    I thought this week I would collect a list of the most useful resources I have used to learn iOS development. These range from the basics of development, to very advanced Objective-C ideas and techniques. This list also includes developer blogs and podcasts that are entertaining and helpful.

    Tutorials

    • Stanford: Developing iOS Apps for iPhone and iPad
      • The best way to start learning iOS development. Even the information from past semesters are worth a look. Is a great first step for people wanting to learn iOS/Objective-C development.
    • Ray Wenderlich
      • Covers all topics relating to iOS development from basic Table View setup to OpenGL ES for game development.
    • Mobile Tuts
      • Collection of Mobile development tutorials covering a wide range of topics.

    Writing

    • NSHipster
      • Great writing covering all types of Objective-C and developer related topics. Usually focuses on moderate to advance topics.
    • objc.io

    Developer Blogs

    • Marco Arment-Creator of Tumblr, Instapaper, The Magazine, and Overcast. Also the host of Build and Analyze and the Accidental Tech Podcast.
    • Brent Simmons-Creator of NetNewswire, MarsEdit, and Vesper.
    • Brett Terpstra-To many projects to list, so just go to his site to see everything. Host of Systematic.
    • Andrew Pontious-Host of Edge Cases podcast.
    • Jonathan Rentzsch-Host of Edge Cases podcast.

    Podcasts

Archive

subscribe via RSS