Core Data and HackerRank

Hello there! Welcome to another blog post of Kevin’s Journey to become a great iOS developer! In the past two days I have been learning more about Core Data and how it is implemented in the most basic form.

A lecture with 73 slides has taught me that Core Data is an object-oriented database, meaning everything is an object with properties and relationships to other objects. It is backed by SQL and sometimes in XML. Some key concepts are:

  • NSManagedObjectContext – the hub around which all Core Data activity turns
  • UIManagedDocument – provides mechanism for management of storage
  • NSFileManager – used to read and write at a specific url path
  • NSNotification – watching a document’s managedObjectContext

Once an NSManagedObjectContext is all set up, the following line is used to insert new objects:

[NSEntityDescription insertNewObjectForEntityForName: inManagedObjectContext:]

Entities’ attributes can be accessed using dot notation, even for relationships! For example, I have a photo and a photographer, I can simply write photo.whoTook.name to get the photographer’s name even I’m working with an instance of Photo.

To delete an object, simply:

[aDocument.managedObjectContext deleteObject: photo]

And everything will be saved once saveContext() is called.

Querying

To query from Core Data: here is some sample code, assuming you have an entity saved as “Photo”:


NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];

request.fetchBatchSize = 20;

request.fetchLimit = 100;

request.sortDescriptors = @[sortDescriptor];

request.predicate...;

FetchRequests can also be sorted before presenting them to the user. This is where the NSSortDescriptor comes in:


NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"title" ascending: YES selector: @selector(localizedStandardCompare:)];

The predicate “NSPredicate” is where the advanced querying comes in, something like SQL, but like another language. Here is an example:


NSString *serverName = @"flickr-5";

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"thumbnailURL contains %@", serverName];

You can also use NSCompoundPredicate to do some really advanced querying.

Finally, I have been doing some HackerRank challenges! Here is my GitHub project written in Swift: HackerRank

Multithreading with Spinning Wheel

Past week has been lots of meet ups, badminton sessions and interviews.

This demo  “Imaginarium” is an app I wrote to learn about multithreading and downloading resources from the internet. The photos in the video are fetched live from Apple’s website. Aside: these photos are actually taken by the iPhone 5 camera and was shown off at the Apple 2012 September Event. The photos look pixelated because of the compression that was done to make an animated GIF. The original photos are here, here, and here.

Here is the demo:

 

 

June26-Imaginarium

I remember I wanted an iPhone 5 so bad because it was so thin and light, running the then-latest iOS 6. Now every device has a 64-bit processor and iOS 11 is unlikely to even support iPhone 5. Time flies by really fast!

Trouble with Core Data

Have been playing with an “To Do” app to learn more about Core Data while traveling back to Toronto. Simple enough, UITableViewController takes care of all the cells for you based on IndexPath. But if you want to have custom TableViewCells, it wouldn’t take either IndexPath or NSIndexPath. Frustrated!

TestFlight Ready!

TestFlight and external testing is officially figured out by Monorail Apps! Now if you want to be an external tester, please let me know in the comment section and I’ll send you an invite to test my app on your device!

Animation in Application

So long story short, my friends and I have decided to make an app to decide where to go for lunch, so here is about 10 hours or so worth of learning and coding. Far from complete: To do: implement way to clear balls, get balls unstuck from the walls by having zigzag walls. Also to react to the bins which the balls fall in and notify user the decision. LOTS of credits to BC on deciding the color of the posts – purple.

 

Animation!

It has been a while focusing on the basics of Objective-C and iOS programming. Today I finally ran into animation! The infrastructure behind animation is Core Animation, which first appeared during WWDC in 2006 and it was supported by the first iPhone that was released in 2007. Apple later released SpriteKit that came along with iOS 7. SpriteKit supports physical properties, gravity, collisions and other animation settings right inside Interface Builder. But I like to know a little bit of more code in exchange for more control in the application.

For 90% of the time, animation is done on UIView’s. The main method to animate views is animateWithDuration:animations:completion:. It can have many other arguments such as delay and options.


+ (void)animateWithDuration: // how long the animation is
                    options: // how the animation should behave, such as  transitions
                  animation: // a block that describes the animation in detail
                 completion: // a block that executes if the animation is complete

Moving on to Dynamic Animation. This is the kind of animation that allows interaction between objects, such as collision, gravity, bouncing and other cool stuff.

To start off, a UIDynamicAnimator is initiated with a view in which you want to animate, then various behaviors can be added to the animator. The animation is then evaluated at run time, forming a real-time 2D physical environment. The common behaviors such as gravity and collision actually exist as UIGravityBehavior and UICollisionBehavior, among others. Gravity can be set to any angle, and not just “down”, the positive y direction on a screen. The acceleration is also adjustable, the default is set to 1000 points/s². When animated, this acceleration will feel like the real 9.81m/s². The collision is actually easier to implement: simply set the property translatesReferenceBoundsIntoBoundary to “YES” and all of the view’s bounds are able to collide. Here is a demo:

June15-Dropit

(You can also play around this demo by cloning this repo. This is an earlier commit, later commits require Fingertips installed by cocoapod, you are also welcome to try it)

Views, Drawing and Gestures

Aside from dragging UIViews, – rectangular areas that allow you to put things in it – from the Interface Builder within Xcode, it is possible to create, change, and completely control a view with code. You’ll think it will look a lot like old school Java game programming – lots of pixel manipulation. Yes and no. It is more complicated in that, in UIView you don’t work with pixels, you work with “points” instead. This is to make sure that objects are rendered the same size on both retina and non-retina device screens. To take into account all the screen sizes and pixel densities, a “scale factor” constant is set within the view class, and this scale factor will be multiplied to the proportions of the view size at run time, which can be figured out by calling self.bounds.size.width or self.bounds.size.height. This “point” system works really well when it comes supporting fonts: CGPoint, the “point” object containing an x and y coordinate, can be directly used as font sizes in UIFont. This way it is easy to control the size of various objects in proportions to the size of the view in which they contain.

Geometry can also be drawn using paths. In UIKit, UIBezierPath is used to draw the path first, and various stroke and fill methods are applied after. But since one line of such “painting code” effects everything that was created within the view, so one must use CGContext to assign different “canvases” called “graphics state” for individual objects. Graphics states can be saved and restored within drawing subroutines:

//subroutine:
-(void)drawGreenCircle:(CGContextRef) ctxt {
    // get out of current Graphics State and
// start a new one
    CGContextSaveGState(ctxt);
    [[UIColor greenColor] setFill];
    // draw circle...
    // restore ctxt as the original Graphics State
    CGContextRestoreGState(ctxt);
}
//main drawing method:
-(void)drawRect:(CGRect)aRect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor redColor] setFill];
    // do some stuff here
// draw a green circle inside "context":
    [self drawGreenCircle: context];
    // do more stuff & expect fill color to be red
}

Lastly, I also learned about gestures. It is handled in UIKit by UIGestureRecognizer. Prior to this gesture recognizer, it was insanely difficult to know how the user is swiping the screen, due to the fact that lots of data is generated even for the simplest gestures. It is quite impressive what the Apple engineers did to make the touch experience so buttery smooth even for the very first iPhone back in 2007. The gesture recognizer supports pan, pinch, swipe, and tap, each has their own API. Pan and pinch are continuous gestures, they have different methods to detect when the touch began, have been, and ended, but all of the four gestures support a single “Recognized” state,  which can be used to trigger cool actions like flipping a card over. Below is a very very basic demo of what I learned today:

 

June14-SuperCard

Colors and Strokes

Today is about NSAttributedString, a special kind of string that can carry information such as color, stroke, font, etc. on top of just string themselves. An app called “Attributor” can be used to demonstrate this. Also performing transitions between screens – segues. A button whose action is connecting to another view controller, and the connection itself is a segue. It can have an identifier which can be referenced in code and pass on information between views. Super when the app has multiple views. Later, I learned about UINavigationController and UITabBarController with multiple MVCs working together. I feel that these material are really basic but also very useful.
For the Chinese Zodiac Sign app, I figured out how to convert Gregorian dates into not only Chinese calendar-based dates, but also to the zodiac sign of that specific day! Basically what I did was to have an instance of DateFormatter() and have its locale property set to Locale(identifier: "zh_CN"), and its calendar property set to Calendar.Identifier.chinese, this way the DateFormatter can display a string of Chinese characters for a Chinese-calendar date translated from any Gregorian date. One of the characters in the resulting string reveals about the zodiac sign.

Chinese Character Zodiac Sign
Rat
Ox
Tiger
Rabbit
Dragon
Snake
Horse
Ram
Monkey
Rooster
Dog
Pig/Boar

Simply enough, extracting that character from the string and have a switch case to translate it into English version of the zodiac sign. However, there are still lots to do about saving a person’s birthday and keeping it inside persistent storage. Will work on that in the next few days when I learn more about Core Data. Now here is a video showing the app “Attributor”:

 

Coffee and Coding

I probably spend as much time on the public transit as write code everyday, but downtown really has a lot of resources and meet up that can develop my coding skills. Today I went down again to meet with a “Coffee and Coding” club. Although most people there were more experienced with web development, I got to meet lots of people working on different projects using different tools that I haven’t even heard of. Just to name a few – Django, a Python-powered web dev framework, and Python’s micro-framework “Flask”. There is a framework called “Laravel” designed to work with PHP. The work they were able to do is also very diverse. PHP programmers using IDEs I also haven’t seen before, graphic designers with PhotoShop open, asking for people’s opinions, I even see someone using Jupyter Notebook, writing much more complicated code than what I wrote for my thesis. After getting introduced to the event organizer, on his laptop he was running an Operating System that looked nothing like anything I’ve seen before – split screen terminals with a thin status bar. I asked him what OS it was, and he said a word that started with “a”. Sadly I never were able to spell it (Probably Linux based, it supported vim). Maybe because I am not from a CS or ECE-based education, but once again, I felt that I belonged there; everyone was writing and talking about code, helping each other, not minding at all the hot day.

Aside from meeting other developers, I was working on the Matchismo app. It worked fine when it is designed to flip and match two cards, but after few hours of fiddling, trial and error, and with Ben’s help, I could not get it to work with flipping and matching three cards. If you are interested in this challenge before I figure it out, check it out here under this commit.

Meeting another Freelancer

Today I spent the afternoon with another iOS freelancer named Li. He has been developing iOS apps independently for almost two years, after obtaining a non-CS/ECE degree from Queen’s, very much like me. It turned out we have so much in common, even the fact that we both came to Canada in elementary school grade 5, from the same hometown!

We chatted about freelancing as well as iOS development independently in general. He suggests that some really good source of learning how to code is coding spaces such as Lighthouse Lab where lots of people with industrial experience are able to provide some insight in your code. Second, reverse engineering from other people’s GitHub projects, and hacking and breaking the code down to test what code does what, piece by piece. Thirdly, by focusing on a personal project where you know you are doing meaningful work, and by having the drive to push yourself and complete something that belongs to you – really enhances the learning experience. Lastly, by involving in boot camps like Lighthouse Lab, lots of the motivation come from the intense pressure of having to learn each day’s material to understand the next day’s material. In addition to the Stanford course, Li suggested me another book called “iOS Big Ranch Guide” by Christian Keur and Aaron Hillegass. I looked it up and it actually updates very frequently as Swift and iOS versions are updated. At this moment the book is already ordered!

In terms of freelancing, client relations is a crucial part in becoming successful. Sometimes the client is vague or simply does not know what he/she wants exactly. By suggesting and selling creative ideas, clients are more likely to accept them, especially if the idea is credited to the client somehow. Next, when showing off your portfolio, it is important to get good at the show and tell. It really reveals your competency as a developer. And of course, your own uniqueness.

Later in the day, Li showed me his app which I thought is incredibly cool. It is an ancient-China-themed hack and slash action game. What’s amazing is, one: it incorporates Force Touch as the attack strength on devices that support it; two: he hand-draws all the graphics for the game on a Bamboo tablet using PhotoShop; third; he composes all of the game’s music assets all by himself! I became fascinated by how talented he is as I listened (and watched) to his music playing inside Logic Pro X. His songs sound really good, to the point where I wouldn’t think it is made by a non-professional music producer. It is incredible that someone from the finance industry is able to code, draw, animate, compose and put all of these together to make something he’s enjoying so much doing. Li said although he’s been working on it for quite a while, the app is planning to be released in two months. I’m super excited to be one of his beta testers.

Li also has another personal app: a highly customizable speed-reading app that can display text one word at a time, with options to pause longer at commas and periods. The display speed is also variable, with options to accelerate, stop, and manually scroll up and down. When stopped, it has the option to look up a word in the dictionary, or even have the text-to-speech engine pronouncing it. Personally I have read lots about speed reading, and I know how helpful such an app can be.

After returning home, I went through lecture 3 of the CS193P course in iTunes U. It added more functions to Matchismo: 12 cards instead of 1; flipping a card now checks if they match, and if they do, the score will be shown on the bottom. The ugly “Flips” label has been replace with a slightly less ugly, centered “Score” label. Yes, I felt that centering it made it less ugly. I believe prettier UI will be implemented soon. The negative score is caused by the fact that there’s a cost of 1 point each time a card is flipped. And hey, let’s leave the time of the simulator in there too.

Simulator Screen Shot Jun 11, 2017, 2.56.36 AM

P.S. I am registered as a paid Apple Developer today. Hooray! Here I come, push notifications, more apps on the demo phone, Testflight, and beta software!