BRYXBanner is a great new library by Harlan Haskins for displaying "dropdown" notifications banners. It has a very straightforward API, while remaining extremely flexible. Let's take a look at some different ways to use it.
Momentarily show a banner. By default banners are dismissed on tap, swipe, or after the duration has elapsed.
letbanner=Banner(title:"New Mission Alert",subtitle:"New mission added to the schedule.",image:nil,backgroundColor:UIColor.lightGrayColor())banner.show(duration:3.0)
Without a duration, the show function caused the banner to be shown until the user taps it. Here we're passing in a closure that will be executed when the user taps the banner.
letbanner=Banner(title:"Life Form Detected",subtitle:"An unknown lifeform has been found.",image:UIImage(named:"alien"),backgroundColor:UIColor.redColor()){print("banner tapped!")}banner.hasShadows=falsebanner.show()
Disable image tinting to display all kinds of images.
banner.shouldTintImage=false
Use the provided .textColor property to change all the colors at once, or use the exposed title and detail labels to completely customize the look of each banner, including font face, size, color, etc.
More info about BRYXBanner can be found at git.io/banner
ResponseDetective is a new debugging library from Adrian Kashivskyy and the team at Netguru for "intercepting" HTTP activity and logging it. You can configure different sets of Interceptor classes, depending on what kinds of data you'd like to see. Let's set it up:
The first thing we'll need to do is register some request and response Interceptors. ResponseDetective comes with quite a few Interceptors out of the box, and you can of course create your own. Here we'll log all the headers of all requests and responses, as well as the content of any JSON requests.
We start with the default session config, and insert the InterceptingProtocol at the front of it's protocol classes.
Finally, we create a session with our config and kick off a new task to an example API endpoint.
It makes it easy to add drawing and text overlay capabilities to your app. Today we're going to use it to build a view controller that will allow our users to sign their name on the screen using their finger. Let's get started.
We start with the "Single View" template and import jot.
We instantiate a new JotViewController, and add it as a child view controller of our SignatureViewController. We'll do this inside viewDidLoad:
R.swift is a tool by Mathijs Kadijk that takes the resources in your app (images, segues, storyboards, nibs, etc.), examines them and generates a file in the root of your project called R.generated.swift containing a simple struct that maps your resources' actual names to Swift properties. R.swift updates the file each time you build, so you can focus on using your resources instead of managing them.
Why do this? For starters, it gives us Xcode native autocompleteion of resources names (finally). We're also saved from hardcoding strings throughout our app, or needing to go update a set of constants somewhere everytime we add a resource.
Let's look at some examples of where R.swift comes in handy. First up, images:
R.swift also makes it easy to work with our cell reuse identifiers. It even includes extensions for UITableView and UICollectionView that save you from casting your cell's type:
PINRemoteImage is a new and promising solution for asynchronously downloading images. It was created by the team at Pinterest and has been battle tested in their extremely popular iOS app. Let's import PINRemoteImage, take a look at how to use it, and see what it can do:
Images are downloaded and decoded off the main thread. They're then cached using a fast, non-deadlocking parallel object cache. (Courtesy of another Pinterest library, PINCache). Upon subsequent requests the in-memory, then disk caches will be checked before re-downloading.
Processing
You can process the image before caching occurs. Here we'll use Toucan (covered in Bite #40) to convert the image into a circular avatar.
Optionally, you can enable a mode supporting progressive JPEG images. They're treated with a nice blur effect, so they look great even at low resolutions.
imageView.updateWithProgress=true
Animated GIF Support
PINRemoteImage also comes with built-in support for Flipboard's blazing fast animated GIF library, FLAnimatedImage. All you have to do to use it is create an FLAnimatedImageView instead of a UIImageView:
Realm is a database made specifically for running on mobile devices. It works on Mac and iOS devices. (It even supports Android!) It's a great alternative to Core Data or even raw SQLite.
There's plenty to love about Realm, but the best part is it's ultra-simple API:
Define an Object
importRealmSwiftclassSpaceship:Object{dynamicvarname=""dynamicvartopSpeed=0// in km}
varship=Spaceship()ship.name="Outrider"ship.topSpeed=1150vardash=User()dash.firstName="Dash"dash.lastName="Rendar"ship.owner=dash// need one Realm per threadletrealm=Realm()realm.write{realm.add(ship)}
Find Objects
Queries in Realm couldn't be simpler. They are chainable. You can add as many calls to .filter as you'd like. You can sort results using the chainable sorted function.
Whether you're applying a circular crop to user avatars or just resizing a photo downloaded from a web service, processing images can be a bit of a chore. Toucan is a Swift image processing library from Gavin Bunney that makes working with images a breeze.
Let's import Toucan and take a look at what it can do:
Resize Images
// userAvatar is a UIImage downloaded from the networkletresizedAvatar=Toucan.Resize.resizeImage(myImage,size:CGSize(width:100,height:100))
Toucan provides another syntax for chaining different processing steps together. Just call .image at the end to get a final processed UIImage. Here we can also see how to apply a 1 point wide border to the final image.
Grand Central Dispatch is a wonderful way to write asynchronous code in your app. It's actual API however, can sometimes be a bit, well, let's call it "dry". Async is a Swift library by Tobias Due Munk that adds some much-welcomed syntactic sugar to Grand Central Dispatch. Async's core API is simple enough to be understood in a single line of code, so let's look at some other fun things it can do:
Chain Blocks
Async.background{// Runs on the background queue}.main{// Runs on the main queue, but only after// the previous block returns}
Delayed Execution
Async.main(after:0.5){// executed on the main queue after 500 ms}.background(after:0.4){// executed on the background queue// 400 ms after the first block completes}
Cancel Blocks
letcomputeThings=Async.background{computeSomethingBig()}letcomputerOtherThings=computeThings.background{// this sucker is about to get cancelled}Async.main{computeThings.cancel()// this won't do anything// you can only cancel blocks that haven't yet started executing!computerOtherThings.cancel()// this second block *would* in fact get cancelled,// since it hasn't started executing yet}
More info about Async can be found at git.io/async
FontBlaster is probably one of the simplest things we'll cover in these bites.
Don't be fooled though, it is one of the most useful little utilities and has quickly made its way into my "standard set" of third-party I use in all my new projects.
Adding a custom font to an iOS app is normally just a little cumbersome:
😁 First drag the font file(s) into Xcode
😐 Open up your Info.plist
😒 Add a new key for "Fonts provided by application"
😲 Find the exact names of each font that iOS’s font system wants to hear, adding items in the .plist for each
😭 Watch as loading them all slows down your app’s initial launch
With FontBlaster, all you have to do is make sure your custom font files are added to your app's main bundle then call this method anywhere in your app:
Hey everyone, first off the response to little bites has been absolutely incredible. I'd like to thank every single one of you for reading, responding, retweeting, requesting, etc. as I get things off the ground here.
Second, I'd like to let everyone know that there will be no bites published next week as I'll be busy attending Apple's Worldwide Developer Conference learning what is sure to be tons of exciting new things that I’ll get to cover here in the coming months.
If you're going to be at the conference as well, reach out on Twitter, I'd love to meet and talk to as many of you all as I can! 👍
Bites will resume their regular schedule starting Monday June, 15th.
DZNEmptyDataSet is a library that makes it extremely easy to add custom "empty" data sets, for when a screen in your app either currently has no data, or the user hasn’t created any data yet.
You can configure it by implementing a bunch of different optional methods in the DZNEmptyDataSet protocol. A pretty simple setup is shown here, but the there are lots of more advanced options including custom views and even easily adding a button below the text.
extensionPhotosViewController:DZNEmptyDataSetSource{functitleForEmptyDataSet(scrollView:UIScrollView!)->NSAttributedString!{returnNSAttributedString(string:"No Photos")}funcdescriptionForEmptyDataSet(scrollView:UIScrollView!)->NSAttributedString!{lettext="Photos you take will appear here"returnNSAttributedString(string:text,attributes:[NSForegroundColorAttributeName:UIColor.grayColor()])}funcimageForEmptyDataSet(scrollView:UIScrollView!)->UIImage!{returnUIImage(named:"cracked-egg")}}
Detect interaction by implementing one of the methods in the DZNEmptyDataSetDelegate protocol.
extensionPhotosViewController:DZNEmptyDataSetDelegate{funcemptyDataSetDidTapButton(scrollView:UIScrollView!){println("tapped button on the empty view!")}}
Here's some example empty screens DZNEmptyDataSet can help you create: