@ -1,12 +1,40 @@
// C o p y r i g h t © 2 0 1 5 A b h i s h e k B a n t h i a
import Cocoa
import Firebase
struct EmailSignupConstants {
static let CLEmailSignupEmailProperty = " email "
static let CLOperatingSystemVersion = " OS "
static let CLClockerVersion = " Clocker version "
static let CLAppFeedbackDateProperty = " date "
}
class FinalOnboardingViewController : NSViewController {
@IBOutlet var titleLabel : NSTextField !
@IBOutlet var subtitleLabel : NSTextField !
@IBOutlet var accesoryLabel : NSTextField !
@IBOutlet var accessoryImageView : NSImageView !
@IBOutlet var emailTextField : NSTextField !
@IBOutlet var emailExplanationLabel : NSTextField !
private let emailValidator = EmailTextFieldValidator ( )
private var serialNumber : String ? {
let platformExpert = IOServiceGetMatchingService ( kIOMasterPortDefault , IOServiceMatching ( " IOPlatformExpertDevice " ) )
guard platformExpert > 0 else {
return nil
}
guard let serialNumber = ( IORegistryEntryCreateCFProperty ( platformExpert , kIOPlatformSerialNumberKey as CFString , kCFAllocatorDefault , 0 ) . takeUnretainedValue ( ) as ? String ) else {
return nil
}
IOObjectRelease ( platformExpert )
return serialNumber
}
override func viewDidLoad ( ) {
super . viewDidLoad ( )
@ -14,5 +42,74 @@ class FinalOnboardingViewController: NSViewController {
subtitleLabel . stringValue = " Thank you for the details. "
accesoryLabel . stringValue = " You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences. "
accessoryImageView . image = Themer . shared ( ) . menubarOnboardingImage ( )
emailExplanationLabel . stringValue = " If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email! "
}
override func viewWillAppear ( ) {
super . viewWillAppear ( )
emailTextField . becomeFirstResponder ( )
}
private func todaysDate ( ) -> String {
let dateFormatter = DateFormatter ( )
dateFormatter . dateStyle = . medium
dateFormatter . timeStyle = . short
dateFormatter . timeZone = TimeZone ( identifier : AppFeedbackConstants . CLCaliforniaTimezoneIdentifier )
return dateFormatter . string ( from : Date ( ) )
}
private func extraData ( ) -> [ String : String ] {
guard let validEmail = emailValidator . validate ( field : emailTextField ) else {
print ( " Not sending up email because it was invalid " )
return [ : ]
}
guard let shortVersion = Bundle . main . object ( forInfoDictionaryKey : " CFBundleShortVersionString " ) as ? String ,
let appVersion = Bundle . main . object ( forInfoDictionaryKey : " CFBundleVersion " ) as ? String else {
return [ : ]
}
let operatingSystem = ProcessInfo . processInfo . operatingSystemVersion
let osVersion = " \( operatingSystem . majorVersion ) . \( operatingSystem . minorVersion ) . \( operatingSystem . patchVersion ) "
let versionInfo = " Clocker \( shortVersion ) ( \( appVersion ) ) "
return [
EmailSignupConstants . CLEmailSignupEmailProperty : validEmail ,
EmailSignupConstants . CLOperatingSystemVersion : osVersion ,
EmailSignupConstants . CLClockerVersion : versionInfo ,
EmailSignupConstants . CLAppFeedbackDateProperty : todaysDate ( ) ,
]
}
func sendUpEmailIfValid ( ) {
let annotations = extraData ( )
guard let identifier = serialNumber else {
assertionFailure ( " Serial Identifier was unexpectedly nil " )
return
}
let myRootReference = Firebase ( url : " https://fiery-heat-5237.firebaseio.com/EmailSignup " )
let feedbackReference = myRootReference ? . child ( byAppendingPath : identifier )
feedbackReference ? . setValue ( annotations )
}
}
class EmailTextFieldValidator {
func validate ( field : NSTextField ) -> String ? {
let trimmedText = field . stringValue . trimmingCharacters ( in : . whitespacesAndNewlines )
guard let dataDetector = try ? NSDataDetector ( types : NSTextCheckingResult . CheckingType . link . rawValue ) else {
return nil
}
let range = NSMakeRange ( 0 , NSString ( string : trimmedText ) . length )
let allMatches = dataDetector . matches ( in : trimmedText ,
options : [ ] ,
range : range )
if allMatches . count = = 1 ,
allMatches . first ? . url ? . absoluteString . contains ( " mailto: " ) = = true {
return trimmedText
}
return nil
}
}