Skip to content
This repository has been archived by the owner. It is now read-only.
Browse files

We’ve updated Cannonball from using Fabric to Firebase.

	This commit shows the transition to using Firebase Crashlytics, Google Analytics for Firebase, and Firebase Authentication. Poems are now stored using Firebase Realtime Database.
  • Loading branch information
kmcnellis committed May 23, 2018
1 parent 7fb5e75 commit e948fbbf3389971f4b7e9747de8908489013cf61
@@ -10,19 +10,19 @@ status: PUBLISHED
# statusNote:

# See http://go/sample-categories
technologies: [Android, AppEngine, Google+]
categories: [Getting Started, UI]
languages: [Java, Python]
technologies: [Firebase, Fabric, Crashlytics]
categories: [Getting Started]
languages: [Swift]
solutions: [Mobile]

# May be omitted if unpublished
github: google/actionbar-basics
github: firebase/cannonball-ios


# Dimensions: 512x512, PNG fomrat
icon: screenshots/icon.png
icon: cannonball-ios/Cannonball/Images.xcassets/AppIcon.appiconset/Icon@3x.png

# List of APIs that this sample should be listed under. Use authoritive,
# names that are unique for the product in question. Examples:
@@ -32,9 +32,6 @@ icon: screenshots/icon.png
# gae-python:<package>
# Web Services - ws:<name of API from Cloud Console>
- ws:drive.files
- ws:urlshortener.url

# Default: apache2. May be omitted for most samples.
# Alternatives: apache2-android (for AOSP)
@@ -143,8 +143,7 @@ We'd love for you to contribute to our source code and to make Cannonball even b
git push origin --delete my-fix-branch

* Check out the master branch:

* Check out the master branch
git checkout master -f
@@ -178,11 +177,6 @@ You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it

## License

By contributing your code, You agree to license your contribution under the terms of the Apache Public License 2.0


Large diffs are not rendered by default.

@@ -16,8 +16,7 @@
import UIKit
import Crashlytics
import TwitterKit
import DigitsKit
import Firebase

class AboutViewController: UIViewController {

@@ -48,8 +47,9 @@ class AboutViewController: UIViewController {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()

// Log Answers Custom Event.
Answers.logCustomEvent(withName: "Viewed About", customAttributes: nil)
// Log Analytics custom event.
parameters: [AnalyticsParameterItemID: "about"])

// MARK: IBActions
@@ -59,28 +59,28 @@ class AboutViewController: UIViewController {

@IBAction func learnMore(_ sender: AnyObject) {
UIApplication.shared.openURL(URL(string: "")!)
UIApplication.shared.openURL(URL(string: "")!)

@IBAction func signOut(_ sender: AnyObject) {
// Remove any Twitter or Digits local sessions for this app.
let sessionStore = Twitter.sharedInstance().sessionStore
if let userId = sessionStore.session()?.userID {
// Remove any Firebase Phone Auth local sessions for this app.
if Auth.auth().currentUser != nil {
do {
try Auth.auth().signOut()
} catch let signOutError as NSError {
print ("Error signing out: %@", signOutError)

// Remove user information for any upcoming crashes in Crashlytics.

// Log Answers Custom Event.
Answers.logCustomEvent(withName: "Signed Out", customAttributes: nil)
// Log Analytics custom event.
Analytics.logEvent("logout", parameters: nil)

// Present the Sign In again.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signInViewController: UIViewController! = storyboard.instantiateViewController(withIdentifier: "SignInViewController")
present(signInViewController, animated: true, completion: nil)
navigationController!.popToRootViewController(animated: true)

@@ -17,30 +17,52 @@
import UIKit
import Fabric
import Crashlytics
import TwitterKit
import DigitsKit
import Firebase
import FirebaseUI

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Developers: Welcome! Get started with
let welcome = "Welcome to Cannonball! Please onboard with the Fabric Mac app. Check the instructions in the README file."
assert(Bundle.main.object(forInfoDictionaryKey: "Fabric") != nil, welcome)

// Register Crashlytics, Twitter, Digits and MoPub with Fabric.
Fabric.with([Crashlytics.self, Twitter.self, Digits.self])

// Check for an existing Twitter or Digits session before presenting the sign in screen.
if Twitter.sharedInstance().sessionStore.session() == nil && Digits.sharedInstance().session() == nil {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signInViewController: AnyObject! = storyboard.instantiateViewController(withIdentifier: "SignInViewController")
window?.rootViewController = signInViewController as? UIViewController
// Use Firebase library to configure APIs
Database.database().isPersistenceEnabled = true

Auth.auth().addStateDidChangeListener { (auth, user) in
if user == nil {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signInViewController: AnyObject! = storyboard.instantiateViewController(withIdentifier: "SignInViewController")
self.window?.rootViewController = signInViewController as? UIViewController
let myPoemsRef = Database.database().reference().child(user!.uid)
return true;

return true
@available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String?
return self.handleOpenUrl(url, sourceApplication: sourceApplication)

@available(iOS 8.0, *)
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return self.handleOpenUrl(url, sourceApplication: sourceApplication)

func handleOpenUrl(_ url: URL, sourceApplication: String?) -> Bool {
if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false {
return true
// other URL handling goes here.
return false


@@ -11,28 +11,6 @@
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<!--Popular Poems-->
<scene sceneID="xvW-ne-Fdi">
<tableViewController id="Vc8-Wc-foP" customClass="PoemTimelineViewController" customModule="Cannonball" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="100" sectionHeaderHeight="22" sectionFooterHeight="22" id="1qJ-gv-FWZ">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="0.90980392160000001" blue="0.79215686269999996" alpha="1" colorSpace="calibratedRGB"/>
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
<color key="sectionIndexBackgroundColor" red="0.99607843139999996" green="0.90980392160000001" blue="0.79215686269999996" alpha="1" colorSpace="calibratedRGB"/>
<outlet property="dataSource" destination="Vc8-Wc-foP" id="i8n-EU-aNW"/>
<outlet property="delegate" destination="Vc8-Wc-foP" id="mny-ZX-IZh"/>
<navigationItem key="navigationItem" title="Popular Poems" id="A4z-bM-j9w"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="HKI-d7-bOo" userLabel="First Responder" sceneMemberID="firstResponder"/>
<point key="canvasLocation" x="776" y="1303"/>
<!--Theme Chooser View Controller-->
<scene sceneID="pHw-4S-UaI">
@@ -88,15 +66,9 @@
<segue destination="wiA-rN-OmI" kind="push" id="PGs-2w-0OG"/>
<barButtonItem key="rightBarButtonItem" image="Popular" id="Brd-vp-Ykq">
<segue destination="Vc8-Wc-foP" kind="push" id="3W5-0s-bxT"/>
<outlet property="historyButton" destination="e6j-wo-e5J" id="kh7-iB-0s5"/>
<outlet property="tweetsButton" destination="Brd-vp-Ykq" id="NeO-0U-6c5"/>
<segue destination="oFl-4R-C3q" kind="modal" identifier="ShowAbout" id="rAS-nZ-AL1"/>
@@ -447,7 +419,8 @@
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<action selector="signInWithTwitter:" destination="LWk-Ji-zOn" eventType="touchUpInside" id="grY-Bw-c9e"/>
<action selector="skipSignIn:" destination="LWk-Ji-zOn" eventType="touchUpInside" id="vyA-9Z-oRn"/>
<segue destination="Lee-FR-LJd" kind="modal" identifier="ShowThemeChooser" id="ixt-1E-UyI"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Logo" translatesAutoresizingMaskIntoConstraints="NO" id="PFT-X7-KfD">
@@ -484,7 +457,6 @@
<outlet property="logoView" destination="PFT-X7-KfD" id="8nt-sK-TZy"/>
<outlet property="signInPhoneButton" destination="uyF-uy-Dc6" id="9w2-Vs-3BF"/>
<outlet property="signInTwitterButton" destination="7eD-LI-DDW" id="4iD-62-Uzn"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="PMd-PQ-HmI" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -20,6 +20,17 @@
@@ -29,6 +40,11 @@

0 comments on commit e948fbb

Please sign in to comment.
You can’t perform that action at this time.