Info

Programmer by day, artist by night

Posts tagged programming

Developing iOS11 Apps with Swfit - Lecture 1 Summary

What’s New

After completing the 1st lecture, here is what I found new from the previous courses I took a few years ago.

  • Uses Swift 4, Xcode 9
  • Rename (refactor) with cmd + click on variable name
  • Fuzzy match on intellisense (was available form Xcode 8)
  • Back to developing card game  (the previous few years focused on developing calculator)
  • Outlet collections

The following video shows the state of the app Concentration after completing lecture 1.

 

The course Developing iOS 11 Apps with Swift by Stanford (cs193p) is available for free from https://itunes.apple.com/us/course/developing-ios-11-apps-with-swift/id1309275316

While the “escape” key has been the usual norm to exit “insert mode” into “visual mode”, the original vi editor encouraged and heavily used the “ctrl+[” keybinding to exit visual mode. Why should we care? Because “ctrl+[” is a lot closer to the fingers and more ergonomic, while hitting the “escape” key moves the left hand out of the home row position. Of course we assume that you remapped your Caps key to ctrl also 🙂

Here is the entry for the Sublime Text keymap file to bind “ctrl+[” to “escape” into visual mode:

{ "keys": ["ctrl+["], "command": "exit_insert_mode" }

On a sidenote: I cannot think of anyone would need to use the Caps key on a computer keyboard. Context is everything, the Caps key was important in the typewriter days because how else can text be made bold or italic. Capitalizing text was often the norm and it did’t indicate shouting as it does now.

The original vi manual, rather the paper “An Introduction to Display Editing with Vi” by Bill Joy has a very useful and quality tutorial that I have not seen matched even by commercial modern Vim/Vi books. You can get the PDF from the freebsd.org vi docs section here.

I have compiled the following resources based on my own experience and what I believe would be an effective learning path for beginners to get up to speed on iOS development.

1. Udacity

Start with the free iOS courses available at Udacity. They are not only fun and engaging but at the end will help you build 4 resume-worthy demos that you can showcase.

Additionally the following iOS specific free courses from Udacity are also recommended:

Time commitment: X months depending on your commitment

2. Ray Wenderlich

While taking the Udacity course, visit Ray Wenderlich http://www.raywenderlich.com/tutorials from time to time. Pick a topic or article that interests you and go through it.

The idea is, instead of going through everything available from A-Z, you pick something of interest and thoroughly explore it. Each article is on a particular topic and the time-investment is at most a few hours (in contrast to going through an entire book or course).

Time commitment: X hours depending on your commitment

The problem that I have experienced in learning any new technology is information retention. I found the above 2 techniques work well for me because:

  1. One path explores the area comprehensively with loads of relevant industry-specific projects, materials, demos, practice, quizzes, etc.
  2. Another path runs in parallel, diving deep into topics of personal interest for short sprints.

3. Stanford U.

Update, Jun 6, 2016: The latest course from Stanford U. “Developing iOS 9 Apps with Swift” can be found here: https://itunes.apple.com/us/course/developing-ios-9-apps-swift/id1104579961

Once the Udacity courses are done, take the Stanford U. course CS193P available for free on iTunes (https://itunes.apple.com/us/course/developing-ios-8-apps-swift/id961180099) for upping your game-level on iOS development. Some special highlights of the CS193P course that I found interesting were:

Using enums, structures, protocols, property observers, optional chaining, GCD, code re-use, OO design, MVC, autolayouts, iPhone/iPad compatibility, avoiding memory cycles, animations, internationalization, programming insights, well-designed assignments and much more. Using these in practice and specially in correct form as expected from a Stanford U. course, will definitely make you a better developer.

4. Additional Resources

Then further sharpen your axe, polish your skills and stay up-to-date with:

5. Algorithms

Useful for practicing algorithms in Swift for coding-tests/interviews. The sites below allow you to type the code solutions in Swift and run them online for evaluation.

6. Even More Resources

And here are even more resources added on request by the owners of the respective sites.
Enjoy 🙂

CalculatorBrainThis project CalculatorBrain is a continuation of the previous project Calculator: Assignment 1, Stanford University Winter 2015 (iOS)

Source code available at Github

The ViewController code is now more lean and better organized since all calculation related logic has been moved to the model.

The project covers all the required tasks and most extra credit tasks.

In addition to the features listed in the previous project Calculator, this assignment provides:

  • A separate model for all calculations
  • Additional scientific functions
  • Memory functions
  • An Undo button (which previously functioned as the Backspace button)
  • Replaces the previous History function with a better implementation
  • Provides error messages

Two items were not implemented as described in the Extra Credit Hints section in the project specifications document:

  • The error messages come from the model with full error text instead of error codes for the ViewController to translate
  • Error handling is not implemented by associating any value (a function) with UnaryOperations and BinaryOperations

Video Demo:

The problem: From page 37, Exercise 4, Chapter 2, Programming Erlang by Joe Armstrong

Run the file client and server code. Add a command called put_file. What messages do you need to add? Find out how to consult manual pages. Consult the manual pages for the file module.

Additional Specifications

  • We should be able to run “erl” from a directory of our choice other than where the .erl source files are located
  • We should be able to specify a directory of our choice in afile_server:start Dir argument
  • We should be able to put a file from a directory other than the current directory to the directory specified in Dir argument above

Solution

{Client, {put_file, File}} ->
  Source = filename:absname(File),
  Destination = filename:join(Dir, filename:basename(File)),
  Client ! {self(), file:copy(Source, Destination)}</pre>
  • We will use the file:copy function. copy/2 has a source and a destination
  • source = the absolute filename
  • destination = dir name + base filename

Testing the solution

1> c("../erlang/afile_server").
{ok,afile_server}
2> c("../erlang/afile_client").
{ok,afile_client}
3> FS = afile_server:start("../erlang").
<0.46.0>
4> afile_client:ls(FS).
{ok,[".idea","afile_client.beam","afile_client.erl",
     "afile_server.beam","afile_server.erl","erlang.iml","foo",
     "geometry.beam","geometry.erl","hello.beam","hello.erl",
     "shop.beam","shop.erl","shop1.beam","shop1.erl"]}
5> afile_client:put_file(FS, "../foo").
{ok,5}
6> afile_client:put_file(FS, "Test.java").
{ok,382}
7> afile_client:ls(FS).
{ok,[".idea","afile_client.beam","afile_client.erl",
     "afile_server.beam","afile_server.erl","erlang.iml","foo",
     "geometry.beam","geometry.erl","hello.beam","hello.erl",
     "shop.beam","shop.erl","shop1.beam","shop1.erl",
     "Test.java"]}

The files foo and Test.java are now showing up in the response from aflile_client:ls(FS) in line 7 above.

Full source code

afile_server.erl

-module(afile_server).
-export([start/1, loop/1]).

start(Dir) -> spawn(afile_server, loop, [Dir]).

loop(Dir) ->
  receive
    {Client, list_dir} ->
      Client ! {self(), file:list_dir(Dir)};
    {Client, {get_file, File}} ->
      Full = filename:join(Dir, File),
      Client ! {self(), file:read_file(Full)};
    {Client, {put_file, File}} ->
      Source = filename:absname(File),
      Destination = filename:join(Dir, filename:basename(File)),
      Client ! {self(), file:copy(Source, Destination)}
  end,
  loop(Dir).

afile_client.erl

-module(afile_client).
-export([ls/1, get_file/2, put_file/2]).

ls(Server) ->
  Server ! {self(), list_dir},
  receive
    {Server, FileList} ->
      FileList
  end.

get_file(Server, File) ->
  Server ! {self(), {get_file, File}},
  receive
    {Server, Content} ->
      Content
  end.

put_file(Server, File) ->
  Server ! {self(), {put_file, File}},
  receive
    {Server, Status} ->
      Status
  end.

stanford-university-itunes-course-developing-ios-8-apps-with-swift
Stanford University has released a new course on iTunes a few days ago on developing iOS 8 apps with the Swift language:

https://itunes.apple.com/us/course/developing-ios-8-apps-swift/id961180099

So far lectures 1 to 5 has been released:

  1. Logistics, iOS 8 Overview
  2. More Xcode and Swift, MVC
  3. Applying MVC
  4. More Swift and Foundation Frameworks
  5. Objective-C Compatibility, Property List, Views

The high quality of the instructional material in this course follows in line with the previous iOS courses as taught by Paul Hegarty. Having followed the last iOS 7 course, suffice to say that these lectures provided by Stanford University for free are better than many paid online courses on iOS.

Paul Hegarty, who currently teaches at Stanford University used to work at NeXT Computers. Here’s a video of him talking about Steve Jobs.

Though erlang-solutions.com provides pre-built binaries for Mac OS X (among other OS), an alternate and easy way to install Erlang on Mac OS X is via brew. Simply type:

brew install erlang

Once installed, you can test it by typing “erl” in the Terminal to fire up the Erlang interactive shell:

Now that you have Erlang installed, what next? Highly recommend Joe Armstrong’s Programming Erlang (2nd Edition). It’s always nice to read programming books authored by language creator themselves. Joe Armstrong’s Github page also has some goodies related to the book and other information.

joe-armstrong-programming-erlang-2nd-edition-book-cover

For a little inspiration, here’s “Erlang the Movie”:

Attached is the solution to the Assignment 2: Matchismo 2 (3-Card Matching Game) from the course “Developing iOS7 Apps for iPhone and iPad (Fall 2013)” by Stanford University (available in iTunes). The attached solution is not limited to a 2-card or 3-card matching game. The same method can be used for n-cards.

The solution addresses all the required tasks in the Assignment. The scoring mechanism implemented is a very simplified approach based on what was already shown in the lectures. While the iOS related tasks were easy to implement, the 3-card matching logic took some thought. There are obviously many approaches to matching a 3-card game. The solution attached is based on the CardMatchingGame model.

The model already stores the chosen and matched states of each card. While it may be tempting to create separate procedures to loop through the number of cards being played and matched, this is not required as the model already holds that information. All we need to do is simply to ask it.

The implementation also adds 2 features not required in the assignment. It presents the user with an alert (UIAlertView) when re-dealing the cards. This was easy to implement via UIAlertViewDelegate. A quick jump to the documentation shows how to do this. The other feature that was added was via the method – (void)shouldDisableGame. This disables the last remaining cards from being clicked if they cannot be matched.

A quick video demonstrating the solution in action.

Please download the attachment for full details – it contains the Xcode 5 project for Matchismo. Just unzip the file matchismo.zip and open Matchismo.xcodeproj

Download Solution to Assignment 2: Matchismo 2 (3-Card Matching Game)

The core matching logic is pasted below with inline code comments:

- (void)chooseCardAtIndex:(NSUInteger)index
{
    Card *card = [self cardAtIndex:index];
    
    if (!card.isMatched) {
        if (card.isChosen) {
            card.chosen = NO;
            self.status = @"";
        } else {
            // match against other cards
            
            // First we store the cards that are chosen and not matched in currentChosenCards
            NSMutableArray *currentChosenCards = [[NSMutableArray alloc] init];
            NSMutableString *statusCurrentChosenCards = [[NSMutableString alloc] init];
            for (Card *otherCard in self.cards) {
                if (otherCard.isChosen && !otherCard.isMatched) {
                    [currentChosenCards addObject:otherCard];
                    [statusCurrentChosenCards appendFormat:@"%@ ", otherCard.contents];
                }
            }
            if ([currentChosenCards count]) {
                self.status = [[NSString stringWithFormat:@"Chose %@ to match with: ", card.contents] stringByAppendingString:statusCurrentChosenCards];
            } else {
                self.status = [NSString stringWithFormat:@"Chose %@", card.contents];
            }

            
            // The model is already tracking how many cards are currently chosen and not matched
            // So all we need to do is match that count with the number of cards we are playing with
            // We do a -1 because currentChosenCards doesn't include the card that was just clicked
            if ([currentChosenCards count] == self.numberOfCardsToPlayWith-1) {
                int matchScore = [card match:currentChosenCards];
                if (matchScore) {
                    self.score += matchScore * MATCH_BONUS;
                    for (Card *otherCard in currentChosenCards) {
                        otherCard.matched = YES;
                    }
                    card.matched = YES;
                    self.status = [[NSString stringWithFormat:@"Scored: %d. Match found for: %@ ", matchScore * MATCH_BONUS, card.contents] stringByAppendingString:statusCurrentChosenCards];
                } else {
                    self.score -= MISMATCH_PENALTY;
                    for (Card *otherCard in currentChosenCards) {
                        otherCard.chosen = NO;
                    }
                    self.status = [[NSString stringWithFormat:@"Penalty: %d. No match found for: %@ ", MISMATCH_PENALTY, card.contents] stringByAppendingString:statusCurrentChosenCards];
                }
            }
        
            self.score -= COST_TO_CHOOSE;
            card.chosen = YES;
        }
    }
    
    // This is not part of the assignment. It's just a nice way to end the game.
    // If the last remaning cards do not match, the game should freeze those cards
    // from being clicked and end the game.
    [self shouldDisableGame];
}

If you completed Lecture 2 of the “Developing iOS7 Apps for iPhone and iPad (Fall 2013) by Stanford University” you will see that in total 4 model classes were created:

  • Card
  • PlayingCard
  • Deck
  • PlayingCardDeck

If you are new object oriented programming it might be a little difficult to wrap your head around all the classes and how they relate to each other, what methods they inherit, override, etc. So here is a class diagram overview that shows the 4 classes and their relations. I have mentioned all the public and private properties and methods.

All the models created in Lecture 2 of Developing iOS7 Apps for iPhone and iPad (Fall 2013) by Stanford University

All the models created in Lecture 2 of Developing iOS7 Apps for iPhone and iPad (Fall 2013) by Stanford University

You might find this diagram handy for referencing back and forth as you continue developing the Matchismo game in the forthcoming lectures.

Remember, PlayingCard is just a subclass of Card. Deck is a collection of Cards. PlayingCardDeck is a collection of PlayingCards 🙂

One should rewrite code for improved performance, structure and design. But how many times? In the beginning my thought was to possibly rewrite code twice. Later I found rewriting my own code three or four times made it better. This lead to very stable code and useful particularly as a library, API or framework. Now my belief is that to properly understand a problem and to produce really great code, it needs to be written half a dozen times to a dozen times!

I am sure a lot of people are laughing at the claim above, I assure you that I am not code challenged. Here’s what Charles H. Moore (Chuck Moore), inventor of the Forth Language has to say about rewrites:

Before you can write your own subroutine, you have to know how. This means, to be practical, that you have written it before; which makes it difficult to get started. But give it a try. After writing the same subroutine a dozen times on as many computers and languages, you’ll be pretty good at it. If you don’t plan to be programming that long, you won’t be interested in this book.

For more information please see: Programming a Problem-Oriented-Language by Charles H. Moore (http://www.colorforth.com/POL.htm)

The more one writes the same code again and again, a few amazing things happen. The code structure gets better. Refactoring improves. Code quality goes up. And most importantly a pattern emerges leading to improved and solid design. The code becomes extremely elegant and beautiful. Highly satisfying to use.

For most commercial projects, rewriting so many times if at all, is course not financially possible. Too many times software gets written, becomes a success, but no one dare rewrite it because of the resource implication to undertake such a task. But if one was to write code for personal projects then nothing is more satisfying than to improve one’s work. It is important not to be afraid to begin from scratch.

Hope this theory does not lead to code obsession. A proof that code rewrite is important and necessary can be proven if you ask yourself a few questions, ask yourself:

  • Am I better programmer today than yesterday?
  • Could my code today be better than what I wrote before?

When I reflect back the answers are always true. So the code that I can write today will always be better. Hence the call for a rewrite!