Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Crystal Ball and Blog Reader in Swift

I decided to go through the Crystal Ball tutorial again, but this time, using Swift. It wasn't too hard to do and Swift makes certain things really easy (and less verbose).

I'm really starting to like this programming language.

Anyway, if anyone is interested in the source code, it's available here.

I really hope I'm not breaking any Treehouse rules by posting this on GitHub, if I am, please let me know, and I'll remove it promptly.

I was rushing this, so I can't guarantee I've implemented everything from the Crystal Ball tutorial, but most of it should be there.

Also, I've replaced the AudioToolbox framework with AVFoundation because I couldn't make AudioToolbox work. So, the sound effect uses the AVAudioPlayer class, and different methods.

Nice job! thanks for sharing this.

Brett Doffing
Brett Doffing
4,978 Points

Can't wait to start using Swift. I've started reading up on it, but don't have the time to make anything yet.

8 Answers

Hey Dino! Thanks for posting.

I am learning too so I figured I would try at least something with the code. Here is an one-liner for:

for num in 1...60 { 
    if num < 10 { 
        imagesArr.append(UIImage(named: "CB0000(num)")) } 
    else {
       imagesArr.append(UIImage(named: "CB000(num)")) 
    } 
}

//swifter! 
for num in 1...60 {
    imagesArr.append(UIImage(named: "CB000(Double(num)/10)".stringByReplacingOccurrencesOfString(".", withString: ""))) 
}

Writing a String extension would be a swifter option, maybe.

Hey Aaron! Well, I am not going to rewrite the code, ehem, but check this out from the official guide.

Both of these have been updated to reflect changes to Swift's array syntax introduced in Xcode 6 beta 3 (I had to move one character :) ).

Thomas Nilsen
Thomas Nilsen
14,957 Points

I'm reading the book published by apple on swift. About halfway done. Examples like this really helps. Good work! :)

And the Blog Reader in Swift, although with slightly more awkward code. I'll need to spend more time with the documentation to see if what I'm doing is actually the right way to do things.

Sweet I'll check it out.

I get a crash with the thumbnail line. I take out Swift blogPost.thumbnail = bpDictionary["thumbnail"] as String

and everything is fine, I leave it in and I get bad access

I've updated the code in the repository so it works with the latest Xcode release.

Looks like Swift will mean less code and less code is always better :) Thanks for these examples!

James Barnett
James Barnett
39,199 Points

> less code and less code is always better

Not really no, see code golf

Thomas Nilsen
Thomas Nilsen
14,957 Points

I was wondering about this:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return blogPosts.count
    }

The function returns an int, which is fine. It takes two parameters: a UITableView and a section. Why does it have 'numberOfRowsInSection' right before the section parameter?

numberOfRowsInSection is the external parameter name (which is more descriptive) and section is the local parameter name.

I guess the idea was to replicate the parameter passing when sending messages in Objective-C.

You can read about it here.

Any ideas on how to translate this into swift?

-(NSString *)generateSHA256:(NSString *)signature secretKey:(NSString *)secretKey{
    NSLog(@"[+] %@", NSStringFromSelector(_cmd));
    const char *cKey  = [secretKey cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [signature cStringUsingEncoding:NSASCIIStringEncoding];

    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
                                          length:sizeof(cHMAC)];

    NSString *hash = [HMAC base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    NSLog(@"hash==> %@", hash);
    return hash;
}

This isn't a straightforward re-write. The problematic part here is the CCHmac() function call. It's a C function, and Apple hasn't yet provided bindings for all of them. So, CommonCrypto/CommonHMAC is not available (at least I couldn't get it to run directly).

What you could theoretically do is create your own Objective-C class that exposes the parts of CommonHMAC that you need and then use that inside of Swift. So far, I've tried to avoid using bridging headers.

I was afraid that was the case. Thanks for the help. I think I'll wait for apple to update this before pushing this over to swift.

The comments section needs a delete post option.