I needed an app to look at live analytics of my website/app but did not find a good app on AppStore. Swiflytics
is super simple tiny app completely written in swift. Here is a video overview:
Get it on AppStore
Source code and build instructions are available at github.
Here is some of the code from app which I want to highlight :
- No more ugly
dispatch_async
snake case
onMainThread { completion(onlineUsers) }
- Some of the async code look totally elegant
fetchTotalOnlineUsers {
self.activeUsersLabel.text = $0
}
fetchData {
self.tableView.reloadData()
}
- guards for easy validation code!
@IBAction func saveButtonPressed(sender: AnyObject?) {
guard let cardName = self.cardNameField.text where cardName.characters.count > 0 else {
showAlertWithText("Enter name of the card", onViewController: self)
return
}
guard let metric = self.metric else {
showAlertWithText("Select a metric", onViewController: self)
return
}
guard let dimension = self.dimension else {
showAlertWithText("Select a dimension", onViewController: self)
return
}
let card = AnalyticsCard(cardName: cardName, dimension: dimension, metric: metric)
CardManager.sharedManager.addCard(card)
}
- This might be a bad thing to highlight but one line singletons :D
static let sharedManager = CardManager()
- Protocol Extensions!
protocol StoryboardInstantiable {
typealias ViewController
static var storyboardID: String { get }
static func instance(storyboard: UIStoryboard) -> ViewController?
}
extension StoryboardInstantiable {
static func instance(storyboard: UIStoryboard) -> ViewController? {
return storyboard.instantiateViewControllerWithIdentifier(Self.storyboardID) as? ViewController
}
}
- This lets us do things like: (no more global static constants for identifiers >_<)
LoginViewController.instance(storyboard)
- Powerful Enums: This is very handy while making network calls
enum AnalyticsDimension: String, EnumCollectable {
case PagePath = "rt:pagePath"
case PageTitle = "rt:pageTitle"
case ReferralPath = "rt:referralPath"
case Campaign = "rt:campaign"
case Source = "rt:source"
case Medium = "rt:medium"
case TrafficType = "rt:trafficType"
case Keyword = "rt:keyword"
case Browser = "rt:browser"
case BrowserVersion = "rt:browserVersion"
case OperatingSystem = "rt:operatingSystem"
case OperatingSystemVersion = "rt:operatingSystemVersion"
...
}
- Crazy if-case-let and for-case-let
if case let savedCardsArray as NSArray = savedCards {
for case let savedCard as NSDictionary in savedCardsArray {
guard let card = AnalyticsCard.from(savedCard) else { continue }
cards.append(card)
}
}
The only thing I really struggled was persistence and handling JSON responses due to swift’s strict type system (cake-walk in ObjC) though Mantle-like feature were possible via Lyft’s Mapper.