diff --git a/StockWatchlist/Assets/.gitkeep b/StockWatchlist/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/StockWatchlist/Podfile b/StockWatchlist/Podfile new file mode 100644 index 0000000..0bf8bf6 --- /dev/null +++ b/StockWatchlist/Podfile @@ -0,0 +1,26 @@ +platform :ios, '9.0' + +target 'StockWatchlist' do + use_frameworks! + + pod 'Alamofire', '4.5.0' + pod 'AlamofireObjectMapper', '4.1.0' + pod 'Dollar', '6.2.0' + pod 'Material', '2.6.3' + pod 'PromiseKit', '4.2.2' + pod 'RealmSwift', '2.8.3' + pod 'Reveal-SDK', '8', :configurations => ['Debug'] + pod 'SnapKit', '3.2.0' + pod 'SwiftyTimer', '2.0.0' + pod 'SwiftyUserDefaults', '3.0.0' + pod 'ZAlertView', '0.3.4' + + target 'StockWatchlistTests' do + inherit! :search_paths + end + + target 'StockWatchlistUITests' do + inherit! :search_paths + end + +end diff --git a/StockWatchlist/Podfile.lock b/StockWatchlist/Podfile.lock new file mode 100644 index 0000000..59a09d1 --- /dev/null +++ b/StockWatchlist/Podfile.lock @@ -0,0 +1,63 @@ +PODS: + - Alamofire (4.5.0) + - AlamofireObjectMapper (4.1.0): + - Alamofire (~> 4.1) + - ObjectMapper (~> 2.0) + - Dollar (6.2.0) + - Material (2.6.3): + - Material/Core (= 2.6.3) + - Material/Core (2.6.3) + - ObjectMapper (2.2.5) + - PromiseKit (4.2.2): + - PromiseKit/Foundation (= 4.2.2) + - PromiseKit/QuartzCore (= 4.2.2) + - PromiseKit/UIKit (= 4.2.2) + - PromiseKit/CorePromise (4.2.2) + - PromiseKit/Foundation (4.2.2): + - PromiseKit/CorePromise + - PromiseKit/QuartzCore (4.2.2): + - PromiseKit/CorePromise + - PromiseKit/UIKit (4.2.2): + - PromiseKit/CorePromise + - Realm (2.8.3): + - Realm/Headers (= 2.8.3) + - Realm/Headers (2.8.3) + - RealmSwift (2.8.3): + - Realm (= 2.8.3) + - Reveal-SDK (8) + - SnapKit (3.2.0) + - SwiftyTimer (2.0.0) + - SwiftyUserDefaults (3.0.0) + - ZAlertView (0.3.4) + +DEPENDENCIES: + - Alamofire (= 4.5.0) + - AlamofireObjectMapper (= 4.1.0) + - Dollar (= 6.2.0) + - Material (= 2.6.3) + - PromiseKit (= 4.2.2) + - RealmSwift (= 2.8.3) + - Reveal-SDK (= 8) + - SnapKit (= 3.2.0) + - SwiftyTimer (= 2.0.0) + - SwiftyUserDefaults (= 3.0.0) + - ZAlertView (= 0.3.4) + +SPEC CHECKSUMS: + Alamofire: f28cdffd29de33a7bfa022cbd63ae95a27fae140 + AlamofireObjectMapper: 435adc82f5b367679bd9e71c4974a54efd0b2521 + Dollar: da81aacae30cf7dd059bfdfec709e97f2f0ae2f8 + Material: af607a7ec0e9978ef85cf189a3d8ceeeb650400f + ObjectMapper: fb30f71e08470d1e5a20b199fafe1246281db898 + PromiseKit: 00e8886881f151c7e573d06b437915b0bb2970ec + Realm: 3601ef091c8c499a31101d8563b991e75546cdce + RealmSwift: 8183818515471b01a99abdd2970f8e4fd52b6f4a + Reveal-SDK: 43be4e662864e937960d0d04d005135e29c4e53b + SnapKit: 1ca44df72cfa543218d177cb8aab029d10d86ea7 + SwiftyTimer: 2efd74b060d69ad4f1496baf5bbedbe132125fcf + SwiftyUserDefaults: 0f1d45fc3aafb9064dac661e367f8f83fe21a4b4 + ZAlertView: d0e399f75e65eb1272e69777dc4a584f7edd6ea7 + +PODFILE CHECKSUM: aa95cc9986713096e422d82045177a4aba2b2653 + +COCOAPODS: 1.3.0.beta.2 diff --git a/StockWatchlist/StockWatchlist.xcodeproj/project.pbxproj b/StockWatchlist/StockWatchlist.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d7fbbbc --- /dev/null +++ b/StockWatchlist/StockWatchlist.xcodeproj/project.pbxproj @@ -0,0 +1,831 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 00941F90BFB33EF3610A9AB4 /* Pods_StockWatchlistTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00E8FD7319472ABE1FA6104D /* Pods_StockWatchlistTests.framework */; }; + 36D60B361CB7A4AB78DC304C /* Pods_StockWatchlist.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 143D0E0CF4E9097472D3EEAF /* Pods_StockWatchlist.framework */; }; + 499D90D51F048CC000F15DB2 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 499D90D41F048CC000F15DB2 /* Utils.swift */; }; + 499D90D71F049EE000F15DB2 /* Dialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 499D90D61F049EE000F15DB2 /* Dialog.swift */; }; + 499D90D91F04A37100F15DB2 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 499D90D81F04A37100F15DB2 /* TableViewCell.swift */; }; + F07FFD088BE64130D0AC0D49 /* Pods_StockWatchlistUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1239CD5DB1F55E4E79E3E3AB /* Pods_StockWatchlistUITests.framework */; }; + F7E27CC71E972A8300DCF068 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CC61E972A8300DCF068 /* AppDelegate.swift */; }; + F7E27CCE1E972A8300DCF068 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7E27CCD1E972A8300DCF068 /* Assets.xcassets */; }; + F7E27CD11E972A8300DCF068 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7E27CCF1E972A8300DCF068 /* LaunchScreen.storyboard */; }; + F7E27CDC1E972A8400DCF068 /* StockWatchlistTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CDB1E972A8400DCF068 /* StockWatchlistTests.swift */; }; + F7E27CE71E972A8400DCF068 /* StockWatchlistUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CE61E972A8400DCF068 /* StockWatchlistUITests.swift */; }; + F7E27CF91E97306600DCF068 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CF81E97306600DCF068 /* ViewController.swift */; }; + F7E27CFB1E97306F00DCF068 /* launch.png in Resources */ = {isa = PBXBuildFile; fileRef = F7E27CFA1E97306F00DCF068 /* launch.png */; }; + F7E27D031E97381600DCF068 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CFC1E97381600DCF068 /* BaseViewController.swift */; }; + F7E27D051E97381600DCF068 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CFE1E97381600DCF068 /* Constants.swift */; }; + F7E27D061E97381600DCF068 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27CFF1E97381600DCF068 /* Extensions.swift */; }; + F7E27D081E97381600DCF068 /* RealmControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27D011E97381600DCF068 /* RealmControllers.swift */; }; + F7E27D091E97381600DCF068 /* RealmUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E27D021E97381600DCF068 /* RealmUtils.swift */; }; + F7EE2C401F01F69A00587BFD /* RealmModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7EE2C3F1F01F69A00587BFD /* RealmModels.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F7E27CD81E972A8400DCF068 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E27CBB1E972A8300DCF068 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F7E27CC21E972A8300DCF068; + remoteInfo = StockWatchlist; + }; + F7E27CE31E972A8400DCF068 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F7E27CBB1E972A8300DCF068 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F7E27CC21E972A8300DCF068; + remoteInfo = StockWatchlist; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 00E8FD7319472ABE1FA6104D /* Pods_StockWatchlistTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StockWatchlistTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1239CD5DB1F55E4E79E3E3AB /* Pods_StockWatchlistUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StockWatchlistUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 143D0E0CF4E9097472D3EEAF /* Pods_StockWatchlist.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StockWatchlist.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 199E7326BFC67AD91E902ED0 /* Pods-StockWatchlistTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StockWatchlistTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-StockWatchlistTests/Pods-StockWatchlistTests.release.xcconfig"; sourceTree = ""; }; + 1FE6CD27A2353DA97BDFD543 /* Pods-StockWatchlistUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StockWatchlistUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-StockWatchlistUITests/Pods-StockWatchlistUITests.release.xcconfig"; sourceTree = ""; }; + 499D90D41F048CC000F15DB2 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = Sources/Utils.swift; sourceTree = ""; }; + 499D90D61F049EE000F15DB2 /* Dialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Dialog.swift; path = Sources/Dialog.swift; sourceTree = ""; }; + 499D90D81F04A37100F15DB2 /* TableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TableViewCell.swift; path = Sources/TableViewCell.swift; sourceTree = ""; }; + 515E04A874A586C716ABD3A5 /* Pods-StockWatchlistTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StockWatchlistTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StockWatchlistTests/Pods-StockWatchlistTests.debug.xcconfig"; sourceTree = ""; }; + 900CA4BB3001BFB6AF40B87E /* Pods-StockWatchlistUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StockWatchlistUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StockWatchlistUITests/Pods-StockWatchlistUITests.debug.xcconfig"; sourceTree = ""; }; + 95A41A7B18CC644A48B3DFCD /* Pods-StockWatchlist.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StockWatchlist.release.xcconfig"; path = "Pods/Target Support Files/Pods-StockWatchlist/Pods-StockWatchlist.release.xcconfig"; sourceTree = ""; }; + B6180AB0AA77DC4B2BAEFA9C /* Pods-StockWatchlist.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StockWatchlist.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StockWatchlist/Pods-StockWatchlist.debug.xcconfig"; sourceTree = ""; }; + F7E27CC31E972A8300DCF068 /* StockWatchlist.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StockWatchlist.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F7E27CC61E972A8300DCF068 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + F7E27CCD1E972A8300DCF068 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F7E27CD01E972A8300DCF068 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + F7E27CD21E972A8300DCF068 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F7E27CD71E972A8400DCF068 /* StockWatchlistTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StockWatchlistTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F7E27CDB1E972A8400DCF068 /* StockWatchlistTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockWatchlistTests.swift; sourceTree = ""; }; + F7E27CDD1E972A8400DCF068 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F7E27CE21E972A8400DCF068 /* StockWatchlistUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StockWatchlistUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F7E27CE61E972A8400DCF068 /* StockWatchlistUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockWatchlistUITests.swift; sourceTree = ""; }; + F7E27CE81E972A8400DCF068 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F7E27CF81E97306600DCF068 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = Sources/ViewController.swift; sourceTree = ""; }; + F7E27CFA1E97306F00DCF068 /* launch.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = launch.png; path = Resources/Images/launch.png; sourceTree = ""; }; + F7E27CFC1E97381600DCF068 /* BaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BaseViewController.swift; path = Sources/BaseViewController.swift; sourceTree = ""; }; + F7E27CFE1E97381600DCF068 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = Sources/Constants.swift; sourceTree = ""; }; + F7E27CFF1E97381600DCF068 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = Sources/Extensions.swift; sourceTree = ""; }; + F7E27D011E97381600DCF068 /* RealmControllers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RealmControllers.swift; path = Sources/RealmControllers.swift; sourceTree = ""; }; + F7E27D021E97381600DCF068 /* RealmUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RealmUtils.swift; path = Sources/RealmUtils.swift; sourceTree = ""; }; + F7EE2C3F1F01F69A00587BFD /* RealmModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RealmModels.swift; path = Sources/RealmModels.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F7E27CC01E972A8300DCF068 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 36D60B361CB7A4AB78DC304C /* Pods_StockWatchlist.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E27CD41E972A8400DCF068 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 00941F90BFB33EF3610A9AB4 /* Pods_StockWatchlistTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E27CDF1E972A8400DCF068 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F07FFD088BE64130D0AC0D49 /* Pods_StockWatchlistUITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 58A514DB97EAE6BE33BD60B9 /* Pods */ = { + isa = PBXGroup; + children = ( + B6180AB0AA77DC4B2BAEFA9C /* Pods-StockWatchlist.debug.xcconfig */, + 95A41A7B18CC644A48B3DFCD /* Pods-StockWatchlist.release.xcconfig */, + 515E04A874A586C716ABD3A5 /* Pods-StockWatchlistTests.debug.xcconfig */, + 199E7326BFC67AD91E902ED0 /* Pods-StockWatchlistTests.release.xcconfig */, + 900CA4BB3001BFB6AF40B87E /* Pods-StockWatchlistUITests.debug.xcconfig */, + 1FE6CD27A2353DA97BDFD543 /* Pods-StockWatchlistUITests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + D3960E95356908532DAD8C2C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 143D0E0CF4E9097472D3EEAF /* Pods_StockWatchlist.framework */, + 00E8FD7319472ABE1FA6104D /* Pods_StockWatchlistTests.framework */, + 1239CD5DB1F55E4E79E3E3AB /* Pods_StockWatchlistUITests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + F7E27CBA1E972A8300DCF068 = { + isa = PBXGroup; + children = ( + D3960E95356908532DAD8C2C /* Frameworks */, + 58A514DB97EAE6BE33BD60B9 /* Pods */, + F7E27CC41E972A8300DCF068 /* Products */, + F7E27CC51E972A8300DCF068 /* StockWatchlist */, + F7E27CDA1E972A8400DCF068 /* StockWatchlistTests */, + F7E27CE51E972A8400DCF068 /* StockWatchlistUITests */, + ); + sourceTree = ""; + }; + F7E27CC41E972A8300DCF068 /* Products */ = { + isa = PBXGroup; + children = ( + F7E27CC31E972A8300DCF068 /* StockWatchlist.app */, + F7E27CD71E972A8400DCF068 /* StockWatchlistTests.xctest */, + F7E27CE21E972A8400DCF068 /* StockWatchlistUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + F7E27CC51E972A8300DCF068 /* StockWatchlist */ = { + isa = PBXGroup; + children = ( + F7E27CC61E972A8300DCF068 /* AppDelegate.swift */, + F7E27CCD1E972A8300DCF068 /* Assets.xcassets */, + F7E27CF61E972F8200DCF068 /* Base.lproj */, + F7E27CD21E972A8300DCF068 /* Info.plist */, + F7E27CF41E972F6F00DCF068 /* Resources */, + F7E27CF51E972F7700DCF068 /* Sources */, + ); + path = StockWatchlist; + sourceTree = ""; + }; + F7E27CDA1E972A8400DCF068 /* StockWatchlistTests */ = { + isa = PBXGroup; + children = ( + F7E27CDD1E972A8400DCF068 /* Info.plist */, + F7E27CDB1E972A8400DCF068 /* StockWatchlistTests.swift */, + ); + path = StockWatchlistTests; + sourceTree = ""; + }; + F7E27CE51E972A8400DCF068 /* StockWatchlistUITests */ = { + isa = PBXGroup; + children = ( + F7E27CE81E972A8400DCF068 /* Info.plist */, + F7E27CE61E972A8400DCF068 /* StockWatchlistUITests.swift */, + ); + path = StockWatchlistUITests; + sourceTree = ""; + }; + F7E27CF41E972F6F00DCF068 /* Resources */ = { + isa = PBXGroup; + children = ( + F7E27CF71E97300C00DCF068 /* Images */, + ); + name = Resources; + sourceTree = ""; + }; + F7E27CF51E972F7700DCF068 /* Sources */ = { + isa = PBXGroup; + children = ( + F7E27CFC1E97381600DCF068 /* BaseViewController.swift */, + F7E27CFE1E97381600DCF068 /* Constants.swift */, + 499D90D61F049EE000F15DB2 /* Dialog.swift */, + F7E27CFF1E97381600DCF068 /* Extensions.swift */, + F7E27D011E97381600DCF068 /* RealmControllers.swift */, + F7EE2C3F1F01F69A00587BFD /* RealmModels.swift */, + F7E27D021E97381600DCF068 /* RealmUtils.swift */, + 499D90D81F04A37100F15DB2 /* TableViewCell.swift */, + 499D90D41F048CC000F15DB2 /* Utils.swift */, + F7E27CF81E97306600DCF068 /* ViewController.swift */, + ); + name = Sources; + sourceTree = ""; + }; + F7E27CF61E972F8200DCF068 /* Base.lproj */ = { + isa = PBXGroup; + children = ( + F7E27CCF1E972A8300DCF068 /* LaunchScreen.storyboard */, + ); + name = Base.lproj; + sourceTree = ""; + }; + F7E27CF71E97300C00DCF068 /* Images */ = { + isa = PBXGroup; + children = ( + F7E27CFA1E97306F00DCF068 /* launch.png */, + ); + name = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F7E27CC21E972A8300DCF068 /* StockWatchlist */ = { + isa = PBXNativeTarget; + buildConfigurationList = F7E27CEB1E972A8400DCF068 /* Build configuration list for PBXNativeTarget "StockWatchlist" */; + buildPhases = ( + C9992E36329CCCF9C096A7A5 /* [CP] Check Pods Manifest.lock */, + F7E27CBF1E972A8300DCF068 /* Sources */, + F7E27CC01E972A8300DCF068 /* Frameworks */, + F7E27CC11E972A8300DCF068 /* Resources */, + B091E3E85383B6CBE3B64481 /* [CP] Embed Pods Frameworks */, + D346D14B5C4E5F4E373872A6 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StockWatchlist; + productName = StockWatchlist; + productReference = F7E27CC31E972A8300DCF068 /* StockWatchlist.app */; + productType = "com.apple.product-type.application"; + }; + F7E27CD61E972A8400DCF068 /* StockWatchlistTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F7E27CEE1E972A8400DCF068 /* Build configuration list for PBXNativeTarget "StockWatchlistTests" */; + buildPhases = ( + 0EBF862000F1DD4CB583703D /* [CP] Check Pods Manifest.lock */, + F7E27CD31E972A8400DCF068 /* Sources */, + F7E27CD41E972A8400DCF068 /* Frameworks */, + F7E27CD51E972A8400DCF068 /* Resources */, + D3813286387F70DAA3E477ED /* [CP] Embed Pods Frameworks */, + 12A215A2EC5BCABD1CAA01D8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + F7E27CD91E972A8400DCF068 /* PBXTargetDependency */, + ); + name = StockWatchlistTests; + productName = StockWatchlistTests; + productReference = F7E27CD71E972A8400DCF068 /* StockWatchlistTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + F7E27CE11E972A8400DCF068 /* StockWatchlistUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F7E27CF11E972A8400DCF068 /* Build configuration list for PBXNativeTarget "StockWatchlistUITests" */; + buildPhases = ( + 44CDE3C12C08F7D9B847B2F3 /* [CP] Check Pods Manifest.lock */, + F7E27CDE1E972A8400DCF068 /* Sources */, + F7E27CDF1E972A8400DCF068 /* Frameworks */, + F7E27CE01E972A8400DCF068 /* Resources */, + 27F4CF6C1A7D52AF38C657AD /* [CP] Embed Pods Frameworks */, + EC245955247F9CC4AD5A18D8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + F7E27CE41E972A8400DCF068 /* PBXTargetDependency */, + ); + name = StockWatchlistUITests; + productName = StockWatchlistUITests; + productReference = F7E27CE21E972A8400DCF068 /* StockWatchlistUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F7E27CBB1E972A8300DCF068 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Andrew Gerst"; + TargetAttributes = { + F7E27CC21E972A8300DCF068 = { + CreatedOnToolsVersion = 8.3; + DevelopmentTeam = VLF9HQZ98F; + ProvisioningStyle = Automatic; + }; + F7E27CD61E972A8400DCF068 = { + CreatedOnToolsVersion = 8.3; + DevelopmentTeam = VLF9HQZ98F; + ProvisioningStyle = Automatic; + TestTargetID = F7E27CC21E972A8300DCF068; + }; + F7E27CE11E972A8400DCF068 = { + CreatedOnToolsVersion = 8.3; + DevelopmentTeam = VLF9HQZ98F; + ProvisioningStyle = Automatic; + TestTargetID = F7E27CC21E972A8300DCF068; + }; + }; + }; + buildConfigurationList = F7E27CBE1E972A8300DCF068 /* Build configuration list for PBXProject "StockWatchlist" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = F7E27CBA1E972A8300DCF068; + productRefGroup = F7E27CC41E972A8300DCF068 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F7E27CC21E972A8300DCF068 /* StockWatchlist */, + F7E27CD61E972A8400DCF068 /* StockWatchlistTests */, + F7E27CE11E972A8400DCF068 /* StockWatchlistUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + F7E27CC11E972A8300DCF068 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E27CFB1E97306F00DCF068 /* launch.png in Resources */, + F7E27CD11E972A8300DCF068 /* LaunchScreen.storyboard in Resources */, + F7E27CCE1E972A8300DCF068 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E27CD51E972A8400DCF068 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E27CE01E972A8400DCF068 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0EBF862000F1DD4CB583703D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-StockWatchlistTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 12A215A2EC5BCABD1CAA01D8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlistTests/Pods-StockWatchlistTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 27F4CF6C1A7D52AF38C657AD /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlistUITests/Pods-StockWatchlistUITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 44CDE3C12C08F7D9B847B2F3 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-StockWatchlistUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + B091E3E85383B6CBE3B64481 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlist/Pods-StockWatchlist-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", + "${BUILT_PRODUCTS_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework", + "${BUILT_PRODUCTS_DIR}/Dollar/Dollar.framework", + "${BUILT_PRODUCTS_DIR}/Material/Material.framework", + "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework", + "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", + "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${PODS_ROOT}/Reveal-SDK/RevealServer-8/iOS/RevealServer.framework", + "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework", + "${BUILT_PRODUCTS_DIR}/SwiftyTimer/SwiftyTimer.framework", + "${BUILT_PRODUCTS_DIR}/SwiftyUserDefaults/SwiftyUserDefaults.framework", + "${BUILT_PRODUCTS_DIR}/ZAlertView/ZAlertView.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlamofireObjectMapper.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Dollar.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Material.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RevealServer.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyTimer.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyUserDefaults.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZAlertView.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlist/Pods-StockWatchlist-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + C9992E36329CCCF9C096A7A5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-StockWatchlist-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + D346D14B5C4E5F4E373872A6 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlist/Pods-StockWatchlist-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + D3813286387F70DAA3E477ED /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlistTests/Pods-StockWatchlistTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + EC245955247F9CC4AD5A18D8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StockWatchlistUITests/Pods-StockWatchlistUITests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + F7E27CBF1E972A8300DCF068 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E27D051E97381600DCF068 /* Constants.swift in Sources */, + 499D90D71F049EE000F15DB2 /* Dialog.swift in Sources */, + F7EE2C401F01F69A00587BFD /* RealmModels.swift in Sources */, + 499D90D51F048CC000F15DB2 /* Utils.swift in Sources */, + F7E27D081E97381600DCF068 /* RealmControllers.swift in Sources */, + F7E27D061E97381600DCF068 /* Extensions.swift in Sources */, + 499D90D91F04A37100F15DB2 /* TableViewCell.swift in Sources */, + F7E27CF91E97306600DCF068 /* ViewController.swift in Sources */, + F7E27D091E97381600DCF068 /* RealmUtils.swift in Sources */, + F7E27CC71E972A8300DCF068 /* AppDelegate.swift in Sources */, + F7E27D031E97381600DCF068 /* BaseViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E27CD31E972A8400DCF068 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E27CDC1E972A8400DCF068 /* StockWatchlistTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F7E27CDE1E972A8400DCF068 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7E27CE71E972A8400DCF068 /* StockWatchlistUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F7E27CD91E972A8400DCF068 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F7E27CC21E972A8300DCF068 /* StockWatchlist */; + targetProxy = F7E27CD81E972A8400DCF068 /* PBXContainerItemProxy */; + }; + F7E27CE41E972A8400DCF068 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F7E27CC21E972A8300DCF068 /* StockWatchlist */; + targetProxy = F7E27CE31E972A8400DCF068 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + F7E27CCF1E972A8300DCF068 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F7E27CD01E972A8300DCF068 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + F7E27CE91E972A8400DCF068 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F7E27CEA1E972A8400DCF068 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F7E27CEC1E972A8400DCF068 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B6180AB0AA77DC4B2BAEFA9C /* Pods-StockWatchlist.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = VLF9HQZ98F; + INFOPLIST_FILE = StockWatchlist/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = hnswave.StockWatchlist; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + F7E27CED1E972A8400DCF068 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 95A41A7B18CC644A48B3DFCD /* Pods-StockWatchlist.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = VLF9HQZ98F; + INFOPLIST_FILE = StockWatchlist/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = hnswave.StockWatchlist; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + F7E27CEF1E972A8400DCF068 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 515E04A874A586C716ABD3A5 /* Pods-StockWatchlistTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = VLF9HQZ98F; + INFOPLIST_FILE = StockWatchlistTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = hnswave.StockWatchlistTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StockWatchlist.app/StockWatchlist"; + }; + name = Debug; + }; + F7E27CF01E972A8400DCF068 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 199E7326BFC67AD91E902ED0 /* Pods-StockWatchlistTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = VLF9HQZ98F; + INFOPLIST_FILE = StockWatchlistTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = hnswave.StockWatchlistTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StockWatchlist.app/StockWatchlist"; + }; + name = Release; + }; + F7E27CF21E972A8400DCF068 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 900CA4BB3001BFB6AF40B87E /* Pods-StockWatchlistUITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + DEVELOPMENT_TEAM = VLF9HQZ98F; + INFOPLIST_FILE = StockWatchlistUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = hnswave.StockWatchlistUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = StockWatchlist; + }; + name = Debug; + }; + F7E27CF31E972A8400DCF068 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1FE6CD27A2353DA97BDFD543 /* Pods-StockWatchlistUITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + DEVELOPMENT_TEAM = VLF9HQZ98F; + INFOPLIST_FILE = StockWatchlistUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = hnswave.StockWatchlistUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_TARGET_NAME = StockWatchlist; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F7E27CBE1E972A8300DCF068 /* Build configuration list for PBXProject "StockWatchlist" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F7E27CE91E972A8400DCF068 /* Debug */, + F7E27CEA1E972A8400DCF068 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F7E27CEB1E972A8400DCF068 /* Build configuration list for PBXNativeTarget "StockWatchlist" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F7E27CEC1E972A8400DCF068 /* Debug */, + F7E27CED1E972A8400DCF068 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F7E27CEE1E972A8400DCF068 /* Build configuration list for PBXNativeTarget "StockWatchlistTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F7E27CEF1E972A8400DCF068 /* Debug */, + F7E27CF01E972A8400DCF068 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F7E27CF11E972A8400DCF068 /* Build configuration list for PBXNativeTarget "StockWatchlistUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F7E27CF21E972A8400DCF068 /* Debug */, + F7E27CF31E972A8400DCF068 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F7E27CBB1E972A8300DCF068 /* Project object */; +} diff --git a/StockWatchlist/StockWatchlist.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/StockWatchlist/StockWatchlist.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..69b5e49 --- /dev/null +++ b/StockWatchlist/StockWatchlist.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/StockWatchlist/StockWatchlist.xcworkspace/contents.xcworkspacedata b/StockWatchlist/StockWatchlist.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..04ead32 --- /dev/null +++ b/StockWatchlist/StockWatchlist.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/StockWatchlist/StockWatchlist/AppDelegate.swift b/StockWatchlist/StockWatchlist/AppDelegate.swift new file mode 100644 index 0000000..9ce5951 --- /dev/null +++ b/StockWatchlist/StockWatchlist/AppDelegate.swift @@ -0,0 +1,37 @@ +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? = UIWindow(frame: UIScreen.main.bounds) + let rootViewController = ViewController() + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + setRootViewController() + return true + } + + func applicationWillResignActive(_ application: UIApplication) {} + + func applicationDidEnterBackground(_ application: UIApplication) {} + + func applicationWillEnterForeground(_ application: UIApplication) {} + + func applicationDidBecomeActive(_ application: UIApplication) {} + + func applicationWillTerminate(_ application: UIApplication) {} + + func setRootViewController() { + window?.rootViewController = rootViewController + window?.makeKeyAndVisible() + } + + func setRootViewController(view: UIViewController) { + window?.rootViewController = view + } + + func restoreRootViewController() { + window?.rootViewController = rootViewController + } + +} diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Contents.json b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..f1a4d4b --- /dev/null +++ b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,133 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon-App-57x57@1x.png", + "scale" : "1x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon-App-57x57@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..c33e064 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..49ad45d Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..9fd604e Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..85182f8 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..40ab4bb Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..50808c8 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..49ad45d Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..ff9d9de Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..324bb8c Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000..ab6e256 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000..7c24ed5 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..324bb8c Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..918ad7b Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..ab54c57 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..80db8f2 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0c2411a Binary files /dev/null and b/StockWatchlist/StockWatchlist/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/StockWatchlist/StockWatchlist/Base.lproj/LaunchScreen.storyboard b/StockWatchlist/StockWatchlist/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..7b60ad2 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StockWatchlist/StockWatchlist/Info.plist b/StockWatchlist/StockWatchlist/Info.plist new file mode 100644 index 0000000..6ffe16c --- /dev/null +++ b/StockWatchlist/StockWatchlist/Info.plist @@ -0,0 +1,54 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + LSApplicationQueriesSchemes + + twitter + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/StockWatchlist/StockWatchlist/Resources/Images/launch.png b/StockWatchlist/StockWatchlist/Resources/Images/launch.png new file mode 100644 index 0000000..d4e1f27 Binary files /dev/null and b/StockWatchlist/StockWatchlist/Resources/Images/launch.png differ diff --git a/StockWatchlist/StockWatchlist/Sources/BaseViewController.swift b/StockWatchlist/StockWatchlist/Sources/BaseViewController.swift new file mode 100644 index 0000000..104168f --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/BaseViewController.swift @@ -0,0 +1,13 @@ +import UIKit + +class BaseViewController: UIViewController { + + var app: AppDelegate { + return UIApplication.shared.delegate as! AppDelegate + } + + override var prefersStatusBarHidden: Bool { + return true + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/Constants.swift b/StockWatchlist/StockWatchlist/Sources/Constants.swift new file mode 100644 index 0000000..863c076 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/Constants.swift @@ -0,0 +1,7 @@ +import Material + +struct AppColor { + + static let base = Color.deepPurple.lighten2 + +} diff --git a/StockWatchlist/StockWatchlist/Sources/Dialog.swift b/StockWatchlist/StockWatchlist/Sources/Dialog.swift new file mode 100644 index 0000000..06d88d4 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/Dialog.swift @@ -0,0 +1,17 @@ +import ZAlertView + +class Dialog: ZAlertView { + + init(type: AlertType) { + super.init(title: nil, message: nil, alertType: type) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override var prefersStatusBarHidden: Bool { + return true + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/Extensions.swift b/StockWatchlist/StockWatchlist/Sources/Extensions.swift new file mode 100644 index 0000000..af8ea64 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/Extensions.swift @@ -0,0 +1,30 @@ +import SwiftyUserDefaults + +extension DefaultsKeys {} + +extension Int { + + var isEmpty: Bool { + return self == 0 + } + +} + +extension String { + + var isNotEmpty: Bool { + return !self.isEmpty + } + +} + +extension UITableViewCell { + + func removeMargins() { + layoutMargins = UIEdgeInsets.zero + preservesSuperviewLayoutMargins = false + selectionStyle = .none + separatorInset = UIEdgeInsets.zero + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/RealmControllers.swift b/StockWatchlist/StockWatchlist/Sources/RealmControllers.swift new file mode 100644 index 0000000..cd363a7 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/RealmControllers.swift @@ -0,0 +1,41 @@ +import RealmSwift + +class PortfolioController { + + let realm: Realm! + + init(realm: Realm) { + self.realm = realm + } + + convenience init() { + self.init(realm: try! Realm()) + } + + func addPortfolio(_ portfolio: Portfolio) { + try! realm.write { + realm.add(portfolio, update: true) + } + } + + func addStock(_ stock: Stock, to portfolio: Portfolio) { + try! realm.write { + portfolio.stocks.append(stock) + realm.add(portfolio, update: true) + } + } + + func deletePortfolio(_ portfolio: Portfolio) { + try! realm.write { + portfolio.stocks.forEach { realm.delete($0) } + realm.delete(portfolio) + } + } + + func deleteStock(_ stock: Stock) { + try! realm.write { + realm.delete(stock) + } + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/RealmModels.swift b/StockWatchlist/StockWatchlist/Sources/RealmModels.swift new file mode 100644 index 0000000..8d0dcd4 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/RealmModels.swift @@ -0,0 +1,24 @@ +import RealmSwift + +class Portfolio: Object { + + dynamic var id = 0 + dynamic var name = "" + internal var stocks = List() + + override static func primaryKey() -> String? { + return "id" + } + +} + +class Stock: Object { + + dynamic var id = 0 + dynamic var name = "" + + override static func primaryKey() -> String? { + return "id" + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/RealmUtils.swift b/StockWatchlist/StockWatchlist/Sources/RealmUtils.swift new file mode 100644 index 0000000..1c48556 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/RealmUtils.swift @@ -0,0 +1,18 @@ +import RealmSwift + +class RealmUtils { + + class func logDebugInfo() { + let realm = try! Realm() + print("realm => \(realm)") + print("realm path => \(realm.configuration.fileURL!.absoluteString)") + } + + class func deleteAllData() { + let realm = try! Realm() + try! realm.write { + realm.deleteAll() + } + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/TableViewCell.swift b/StockWatchlist/StockWatchlist/Sources/TableViewCell.swift new file mode 100644 index 0000000..de76147 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/TableViewCell.swift @@ -0,0 +1,58 @@ +import Material +import UIKit + +class GenericTableViewCell: UITableViewCell { + + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + applyGenericStyle() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + func applyGenericStyle() { + backgroundColor = Color.clear + removeMargins() + } + +} + +class CustomTableViewCell: GenericTableViewCell { + + let customView = UIView() + let simpleLabel = UILabel() + + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + applyCustomStyle() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + func applyCustomStyle() { + customView.removeFromSuperview() + contentView.addSubview(customView) + customView.snp.makeConstraints { make -> Void in + make.center.equalTo(contentView) + make.height.equalTo(contentView) + make.width.equalTo(contentView) + } + buildSimpleCell() + simpleLabel.textColor = Color.darkText.secondary + } + + func buildSimpleCell() { + customView.addSubview(simpleLabel) + simpleLabel.snp.makeConstraints { make -> Void in + make.bottom.equalTo(contentView) + make.top.equalTo(contentView) + make.left.equalTo(contentView).offset(10.0) + make.right.equalTo(contentView).offset(-10.0) + } + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/Utils.swift b/StockWatchlist/StockWatchlist/Sources/Utils.swift new file mode 100644 index 0000000..e2d8167 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/Utils.swift @@ -0,0 +1,17 @@ +import UIKit + +struct Utils { + + static func openUrl(_ url: String) { + openUrl(URL(string: url)!) + } + + static func openUrl(_ url: URL) { + if #available(iOS 10.0, *) { + UIApplication.shared.open(url) + } else { + UIApplication.shared.openURL(url) + } + } + +} diff --git a/StockWatchlist/StockWatchlist/Sources/ViewController.swift b/StockWatchlist/StockWatchlist/Sources/ViewController.swift new file mode 100644 index 0000000..71e9273 --- /dev/null +++ b/StockWatchlist/StockWatchlist/Sources/ViewController.swift @@ -0,0 +1,299 @@ +import Material +import RealmSwift +import SnapKit +import UIKit +import ZAlertView + +class ViewController: BaseViewController { + + fileprivate var toolbar: Toolbar! + fileprivate var toolbarBackButton: IconButton! + fileprivate var toolbarAddButton: IconButton! + fileprivate var toolbarShareButton: IconButton! + let realm = try! Realm() + let tableView = UITableView() + let portfolioController = PortfolioController() + var portfolios: Results { + return realm.objects(Portfolio.self).sorted(by: [ "name" ]) + } + var selectedPortfolio: Portfolio? + var selectedPortfolioStocks: [Stock] { + return selectedPortfolio?.stocks.sorted { $0.name < $1.name } ?? [] + } + + override func viewDidLoad() { + super.viewDidLoad() + RealmUtils.logDebugInfo() + ZAlertView.neutralColor = AppColor.base + setupInterface() + } + + func setupInterface() { + view.backgroundColor = .white + createToolbar() + createTableView() + addContraintsToViews() + } + + func addContraintsToViews() { + addToolbarConstraints() + addTableViewContraints() + } + +} + +extension ViewController: UITableViewDelegate, UITableViewDataSource { + + func addTableViewContraints() { + tableView.snp.remakeConstraints { make -> Void in + make.bottom.equalTo(view) + make.left.equalTo(view) + make.right.equalTo(view) + make.top.equalTo(toolbar.snp.bottom) + } + } + + func createTableView() { + tableView.backgroundColor = Color.clear + tableView.cellLayoutMarginsFollowReadableWidth = false + tableView.dataSource = self + tableView.delegate = self + tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell") + tableView.tableFooterView = UIView(frame: .zero) + view.addSubview(tableView) + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 44.0 + } + + func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { + return true + } + + func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + let dialog = Dialog(type: .confirmation) + dialog.alertTitle = "Confirm Delete" + dialog.message = "Are you sure you want to delete this?" + dialog.okHandler = { alert in + if self.selectedPortfolio == nil { + self.portfolioController.deletePortfolio(self.portfolios[indexPath.row]) + } else { + self.portfolioController.deleteStock(self.selectedPortfolioStocks[indexPath.row]) + } + tableView.reloadData() + alert.dismissAlertView() + } + dialog.show() + } + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return getNumberOfRows() + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = (tableView.dequeueReusableCell(withIdentifier: "cell") as? CustomTableViewCell) ?? CustomTableViewCell.init(style: .default, reuseIdentifier: "cell") + cell.simpleLabel.text = getTextForRow(indexPath.row) + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if selectedPortfolio == nil { + selectedPortfolio = portfolios[indexPath.row] + tableView.reloadData() + showToolbarBackButton() + showToolbarShareButton() + setToolbarTitle() + } else { + let ticker = selectedPortfolioStocks[indexPath.row].name + let dialog = Dialog(type: .multipleChoice) + dialog.addButton("Open Finviz") { alert in + Utils.openUrl("https://finviz.com/quote.ashx?t=\(ticker)&ty=c&ta=0&p=d") + } + dialog.addButton("Open Twitter") { alert in + let query = "$\(ticker)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + if let twitterDeepLinkUrl = URL(string: "twitter://search?query=\(query)"), UIApplication.shared.canOpenURL(twitterDeepLinkUrl) { + Utils.openUrl(twitterDeepLinkUrl) + } else { + Utils.openUrl("https://mobile.twitter.com/search/live?q=\(query)") + } + } + dialog.show() + } + } + + func getNumberOfRows() -> Int { + guard selectedPortfolio == nil else { + return selectedPortfolioStocks.count + } + return portfolios.count + } + + func getTextForRow(_ row: Int) -> String { + guard selectedPortfolio == nil else { + return selectedPortfolioStocks[row].name + } + return portfolios[row].name + } + +} + +extension ViewController { + + func addToolbarConstraints() { + toolbar.snp.remakeConstraints { make -> Void in + make.bottom.equalTo(tableView.snp.top) + make.height.equalTo(50.0) + make.top.width.equalTo(view) + } + } + + func createToolbar() { + createToolbarButtons() + toolbar = Toolbar() + toolbar.backgroundColor = AppColor.base + toolbar.detailLabel.textColor = Color.white + toolbar.titleLabel.textColor = Color.white + toolbar.rightViews = [ toolbarAddButton ] + setToolbarTitle() + view.addSubview(toolbar) + } + + func createToolbarButtons() { + toolbarBackButton = createToolbarBackButton() + toolbarAddButton = createToolbarAddButton() + toolbarShareButton = createToolbarShareButton() + } + + func createToolbarBackButton() -> IconButton { + let backImage = Icon.cm.arrowBack + let backButton = IconButton() + backButton.pulseColor = Color.white + backButton.tintColor = Color.white + backButton.setImage(backImage, for: .normal) + backButton.setImage(backImage, for: .highlighted) + backButton.addTarget(self, action: #selector(handleToolbarBackButtonPressed), for: .touchUpInside) + return backButton + } + + func createToolbarAddButton() -> IconButton { + let addImage = Icon.cm.add + let addButton = IconButton() + addButton.pulseColor = Color.white + addButton.tintColor = Color.white + addButton.setImage(addImage, for: .normal) + addButton.setImage(addImage, for: .highlighted) + addButton.addTarget(self, action: #selector(handleToolbarAddButtonPressed), for: .touchUpInside) + return addButton + } + + func createToolbarShareButton() -> IconButton { + let addImage = Icon.cm.share + let addButton = IconButton() + addButton.pulseColor = Color.white + addButton.tintColor = Color.white + addButton.setImage(addImage, for: .normal) + addButton.setImage(addImage, for: .highlighted) + addButton.addTarget(self, action: #selector(handleToolbarShareButtonPressed), for: .touchUpInside) + return addButton + } + + func showToolbarBackButton() { + toolbar.leftViews = [ toolbarBackButton ] + } + + func hideToolbarBackButton() { + toolbar.leftViews = [] + } + + func showToolbarShareButton() { + toolbar.rightViews = [ toolbarShareButton, toolbarAddButton ] + } + + func hideToolbarShareButton() { + toolbar.rightViews = [ toolbarAddButton ] + } + + func handleToolbarBackButtonPressed() { + selectedPortfolio = nil + setToolbarTitle() + hideToolbarBackButton() + hideToolbarShareButton() + tableView.reloadData() + } + + func handleToolbarAddButtonPressed() { + let dialog = Dialog(type: .confirmation) + dialog.addTextField("name", placeHolder: selectedPortfolio == nil ? "Enter Name" : "Enter Ticker") + dialog.alertTitle = selectedPortfolio == nil ? "Create Portfolio" : "Add Stock" + dialog.allowTouchOutsideToDismiss = false + dialog.okHandler = { alert in + if let name = alert.getTextFieldWithIdentifier("name")!.text, !name.isEmpty { + if self.selectedPortfolio == nil { + let portfolio = Portfolio() + portfolio.id = (self.realm.objects(Portfolio.self).sorted(byKeyPath: "id", ascending: false).first?.id ?? -1) + 1 + portfolio.name = name + self.portfolioController.addPortfolio(portfolio) + } else { + let stock = Stock() + stock.id = (self.realm.objects(Stock.self).sorted(byKeyPath: "id", ascending: false).first?.id ?? -1) + 1 + stock.name = name.uppercased() + self.portfolioController.addStock(stock, to: self.selectedPortfolio!) + } + self.tableView.reloadData() + alert.dismissAlertView() + } + } + dialog.show() + } + + func handleToolbarShareButtonPressed() { + let dialog = Dialog(type: .multipleChoice) + dialog.alertTitle = "Share" + dialog.addButton("Open Finviz") { alert in + Utils.openUrl("https://finviz.com/screener.ashx?v=211&t=\(self.getStockListForUrl())&ta=0&o=change") + } + dialog.addButton("Open Twitter") { alert in + let query = self.getStockQueryForTwitter().addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + if let twitterDeepLinkUrl = URL(string: "twitter://search?query=\(query)"), UIApplication.shared.canOpenURL(twitterDeepLinkUrl) { + Utils.openUrl(twitterDeepLinkUrl) + } else { + Utils.openUrl("https://mobile.twitter.com/search/live?q=\(query)") + } + } + dialog.addButton("Copy Finviz Url") { alert in + UIPasteboard.general.string = "https://finviz.com/screener.ashx?v=211&t=\(self.getStockListForUrl())&ta=0&o=change" + } + dialog.addButton("Copy Twitter Search") { alert in + UIPasteboard.general.string = self.getStockQueryForTwitter() + } + dialog.show() + } + + func getStockListForUrl() -> String { + return (selectedPortfolioStocks.reduce([]) { (accumulation: [String], nextValue: Stock) -> [String] in + var accumulation = accumulation + accumulation.append(nextValue.name) + return accumulation + }).joined(separator: ",") + } + + func getStockQueryForTwitter() -> String { + return (selectedPortfolioStocks.reduce([]) { (accumulation: [String], nextValue: Stock) -> [String] in + var accumulation = accumulation + accumulation.append("\"$\(nextValue.name)\"") + return accumulation + }).joined(separator: " OR ") + } + + func setToolbarTitle() { + if selectedPortfolio == nil { + toolbar.title = "Stock Portfolios" + } else { + toolbar.title = selectedPortfolio!.name + } + } + +} diff --git a/StockWatchlist/StockWatchlistTests/Info.plist b/StockWatchlist/StockWatchlistTests/Info.plist new file mode 100644 index 0000000..6c6c23c --- /dev/null +++ b/StockWatchlist/StockWatchlistTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/StockWatchlist/StockWatchlistTests/StockWatchlistTests.swift b/StockWatchlist/StockWatchlistTests/StockWatchlistTests.swift new file mode 100644 index 0000000..b14932d --- /dev/null +++ b/StockWatchlist/StockWatchlistTests/StockWatchlistTests.swift @@ -0,0 +1,21 @@ +import XCTest + +@testable import StockWatchlist + +class StockWatchlistTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testExample() {} + + func testPerformanceExample() { + self.measure {} + } + +} diff --git a/StockWatchlist/StockWatchlistUITests/Info.plist b/StockWatchlist/StockWatchlistUITests/Info.plist new file mode 100644 index 0000000..6c6c23c --- /dev/null +++ b/StockWatchlist/StockWatchlistUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/StockWatchlist/StockWatchlistUITests/StockWatchlistUITests.swift b/StockWatchlist/StockWatchlistUITests/StockWatchlistUITests.swift new file mode 100644 index 0000000..2de7a98 --- /dev/null +++ b/StockWatchlist/StockWatchlistUITests/StockWatchlistUITests.swift @@ -0,0 +1,17 @@ +import XCTest + +class StockWatchlistUITests: XCTestCase { + + override func setUp() { + super.setUp() + continueAfterFailure = false + XCUIApplication().launch() + } + + override func tearDown() { + super.tearDown() + } + + func testExample() {} + +} diff --git a/StockWatchlist/TODO.txt b/StockWatchlist/TODO.txt new file mode 100644 index 0000000..e69de29