├── Cartfile
├── Cartfile.lock
├── Vendor
└── HockeySDK-iOS
│ └── BuildAgent
├── Coins
├── Resources
│ ├── Settings.bundle
│ │ ├── en.lproj
│ │ │ └── Root.strings
│ │ └── Root.plist
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── iPad.png
│ │ │ ├── iPad@2x.png
│ │ │ ├── Settings.png
│ │ │ ├── Spotlight.png
│ │ │ ├── iPhone@2x.png
│ │ │ ├── iPhone@3x.png
│ │ │ ├── Settings@2x.png
│ │ │ ├── Settings@3x.png
│ │ │ ├── Spotlight@2x.png
│ │ │ ├── Spotlight@3x.png
│ │ │ ├── Settings@2x-1.png
│ │ │ ├── Spotlight@2x-1.png
│ │ │ └── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ ├── iPad Landscape.png
│ │ │ ├── iPad Portrait.png
│ │ │ ├── iPad Landscape@2x.png
│ │ │ ├── iPad Portrait@2x.png
│ │ │ ├── 4" iPhone Portrait@2x.png
│ │ │ ├── 3.5" iPhone Portrait@2x.png
│ │ │ ├── 4.7" iPhone Portrait@2x.png
│ │ │ ├── 5.5" iPhone Landscape@3x.png
│ │ │ ├── 5.5" iPhone Portrait@3x.png
│ │ │ └── Contents.json
│ ├── en.lproj
│ │ └── Localizable.strings
│ ├── Coins.entitlements
│ ├── Coins-Info.plist
│ └── currencies.json
├── Other Sources
│ └── Coins-Bridging-Header.h
└── Classes
│ ├── PullToRefreshView.swift
│ ├── TickingButton.swift
│ ├── TextField.swift
│ ├── NSDate+Coins.swift
│ ├── TableViewCell.swift
│ ├── CurrencyPickerTableViewController.swift
│ ├── AppDelegate.swift
│ └── ValueViewController.swift
├── .gitignore
├── Coins.xcworkspace
└── contents.xcworkspacedata
├── Podfile
├── Coins.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── Coins Today
├── Classes
│ ├── BTCTodayValueView.h
│ ├── BTCTodayViewController.h
│ ├── BTCTodayValueView.m
│ └── BTCTodayViewController.m
└── Resources
│ ├── Coins Today.entitlements
│ └── Info.plist
├── CoinsKit
├── Classes
│ ├── NSUserDefaults+Coins.h
│ ├── CoinsKit.h
│ ├── BTCConversionProvider.h
│ ├── BTCValueView.h
│ ├── NSUserDefaults+Coins.m
│ ├── BTCPreferences.h
│ ├── BTCDefines.h
│ ├── BTCDefines.m
│ ├── BTCConversionProvider.m
│ ├── BTCPreferences.m
│ └── BTCValueView.m
├── CoinsKit.h
├── CoinsKit.swift
└── Info.plist
├── Podfile.lock
├── LICENSE
├── Changelog.markdown
└── Readme.markdown
/Cartfile:
--------------------------------------------------------------------------------
1 | github "soffes/GradientView"
2 |
--------------------------------------------------------------------------------
/Cartfile.lock:
--------------------------------------------------------------------------------
1 | github "soffes/GradientView" "v2.0"
2 |
--------------------------------------------------------------------------------
/Vendor/HockeySDK-iOS/BuildAgent:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Vendor/HockeySDK-iOS/BuildAgent
--------------------------------------------------------------------------------
/Coins/Resources/Settings.bundle/en.lproj/Root.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Settings.bundle/en.lproj/Root.strings
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *xcuserdata/
3 | *.mode1v3
4 | *.pbxuser
5 | *.moved-aside/
6 | Pods
7 | xcshareddata
8 | Carthage.build
9 | Carthage.checkout
10 |
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPad.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPad@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPad@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPhone@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPhone@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPhone@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/iPhone@3x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings@3x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight@3x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Settings@2x-1.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/AppIcon.appiconset/Spotlight@2x-1.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Landscape.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Portrait.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Landscape@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Landscape@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/iPad Portrait@2x.png
--------------------------------------------------------------------------------
/Coins.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 |
3 | platform :ios, '8.0'
4 |
5 | target 'Coins' do
6 | pod 'HockeySDK'
7 | pod 'SSPullToRefresh'
8 | pod 'Mixpanel'
9 | end
10 |
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/4" iPhone Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/4" iPhone Portrait@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/3.5" iPhone Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/3.5" iPhone Portrait@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/4.7" iPhone Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/4.7" iPhone Portrait@2x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/5.5" iPhone Landscape@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/5.5" iPhone Landscape@3x.png
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/5.5" iPhone Portrait@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soffes/coins/HEAD/Coins/Resources/Images.xcassets/LaunchImage.launchimage/5.5" iPhone Portrait@3x.png
--------------------------------------------------------------------------------
/Coins.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Coins/Other Sources/Coins-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import
6 | #import
7 | #import
8 |
--------------------------------------------------------------------------------
/Coins Today/Classes/BTCTodayValueView.h:
--------------------------------------------------------------------------------
1 | //
2 | // BTCTodayValueView.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | @import CoinsKit;
10 |
11 | @interface BTCTodayValueView : BTCValueView
12 | @end
13 |
--------------------------------------------------------------------------------
/Coins Today/Classes/BTCTodayViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // BTCTodayViewController.h
3 | // Coins Today
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface BTCTodayViewController : UIViewController
12 | @end
13 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/NSUserDefaults+Coins.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSUserDefaults+Coins.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 | @interface NSUserDefaults (Coins)
12 |
13 | + (instancetype)btc_sharedDefaults;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/CoinsKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoinsKit.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCPreferences.h"
10 | #import "BTCConversionProvider.h"
11 | #import "BTCValueView.h"
12 | #import "BTCDefines.h"
13 |
14 | #import "NSUserDefaults+Coins.h"
15 |
--------------------------------------------------------------------------------
/Coins/Resources/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | Coins
4 |
5 | Created by Sam Soffes on 12/20/13.
6 | Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | */
8 |
9 | "CURRENCY" = "Currency";
10 | "DONE" = "Done";
11 | "UPDATING" = "Updating…";
12 | "UPDATED_FORMAT" = "Updated %@";
13 | "NEVER_UPDATED" = "Never updated";
14 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - HockeySDK (3.6.1)
3 | - Mixpanel (2.6.0):
4 | - Mixpanel/MPCategoryHelpers (= 2.6.0)
5 | - Mixpanel/MPCategoryHelpers (2.6.0)
6 | - SSPullToRefresh (1.2.0)
7 |
8 | DEPENDENCIES:
9 | - HockeySDK
10 | - Mixpanel
11 | - SSPullToRefresh
12 |
13 | SPEC CHECKSUMS:
14 | HockeySDK: 15b24068466aa5ee421eed0cc1d58428d698edf6
15 | Mixpanel: e919d14f07a34ee01f81f97e535b7a240af2f793
16 | SSPullToRefresh: bb513a1ccbf08fdd67e4139bc1bbe3fc2ed34228
17 |
18 | COCOAPODS: 0.35.0
19 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCConversionProvider.h:
--------------------------------------------------------------------------------
1 | //
2 | // BTCConversionProvider.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 12/20/13.
6 | // Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface BTCConversionProvider : NSObject
12 |
13 | + (instancetype)sharedProvider;
14 |
15 | - (void)getConversionRates:(void(^)(NSDictionary *conversionRates, UIBackgroundFetchResult result))completion;
16 | - (NSDictionary *)latestConversionRates;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCValueView.h:
--------------------------------------------------------------------------------
1 | //
2 | // BTCValueView.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 4/23/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface BTCValueView : UIView
12 |
13 | @property (nonatomic) NSDictionary *conversionRates;
14 |
15 | @property (nonatomic, readonly) UIButton *valueButton;
16 | @property (nonatomic, readonly) UIButton *quantityButton;
17 |
18 | - (CGFloat)verticalSpacing;
19 | - (void)setupViews;
20 | - (void)setupConstraints;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Coins/Resources/Coins.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.icloud-container-identifiers
6 |
7 | com.apple.developer.ubiquity-kvstore-identifier
8 | $(TeamIdentifierPrefix)group.com.nothingmagical.coins
9 | com.apple.security.application-groups
10 |
11 | group.com.nothingmagical.coins
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/CoinsKit/CoinsKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoinsKit.h
3 | // CoinsKit
4 | //
5 | // Created by Sam Soffes on 11/26/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for CoinsKit.
12 | FOUNDATION_EXPORT double CoinsKitVersionNumber;
13 |
14 | //! Project version string for CoinsKit.
15 | FOUNDATION_EXPORT const unsigned char CoinsKitVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/NSUserDefaults+Coins.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSUserDefaults+Coins.m
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "NSUserDefaults+Coins.h"
10 |
11 | @implementation NSUserDefaults (Coins)
12 |
13 | + (instancetype)btc_sharedDefaults {
14 | static NSUserDefaults *defaults;
15 | static dispatch_once_t onceToken;
16 | dispatch_once(&onceToken, ^{
17 | defaults = [[self alloc] initWithSuiteName:@"group.com.nothingmagical.coins"];
18 | });
19 | return defaults;
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Coins Today/Resources/Coins Today.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.icloud-container-identifiers
6 |
7 | com.apple.developer.ubiquity-kvstore-identifier
8 | $(TeamIdentifierPrefix)group.com.nothingmagical.coins
9 | com.apple.security.application-groups
10 |
11 | group.com.nothingmagical.coins
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCPreferences.h:
--------------------------------------------------------------------------------
1 | //
2 | // BTCPreferences.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 | @interface BTCPreferences : NSObject
12 |
13 | + (instancetype)sharedPreferences;
14 |
15 | - (void)registerDefaults:(NSDictionary *)defaults;
16 | - (id)objectForKey:(NSString *)key;
17 | - (double)doubleForKey:(NSString *)key;
18 | - (void)setObject:(id)object forKey:(NSString *)key;
19 | - (void)removeObjectForKey:(NSString *)key;
20 |
21 | - (void)synchronize;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // BTCDefines.h
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 12/20/13.
6 | // Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #ifndef BTCDEFINES
10 | #define BTCDEFINES 1
11 |
12 | @import Foundation;
13 |
14 | extern NSString *const kBTCSelectedCurrencyKey;
15 | extern NSString *const kBTCNumberOfCoinsKey;
16 | extern NSString *const kBTCControlsHiddenKey;
17 | extern NSString *const kBTCAutomaticallyRefreshKey;
18 | extern NSString *const kBTCDisableSleepKey;
19 |
20 | extern NSString *const kBTCCurrencyDidChangeNotificationName;
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCDefines.m:
--------------------------------------------------------------------------------
1 | //
2 | // BTCDefines.m
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 12/20/13.
6 | // Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCDefines.h"
10 |
11 | NSString *const kBTCSelectedCurrencyKey = @"BTCSelectedCurrency";
12 | NSString *const kBTCNumberOfCoinsKey = @"BTCNumberOfCoins";
13 | NSString *const kBTCControlsHiddenKey = @"BTCControlsHidden";
14 | NSString *const kBTCAutomaticallyRefreshKey = @"BTCAutomaticallyRefresh";
15 | NSString *const kBTCDisableSleepKey = @"BTCDisableSleep";
16 |
17 | NSString *const kBTCCurrencyDidChangeNotificationName = @"BTCCurrencyDidChangeNotification";
18 |
--------------------------------------------------------------------------------
/CoinsKit/CoinsKit.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoinsKit.swift
3 | // CoinsKit
4 | //
5 | // Created by Sam Soffes on 11/25/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public struct CoinsKit {
12 | public static let blueColor: UIColor = {
13 | return UIColor(red: 0.129, green: 0.455, blue: 0.627, alpha: 1.0)
14 | }()
15 |
16 | public static let purpleColor: UIColor = {
17 | return UIColor(red: 0.369, green: 0.173, blue: 0.6, alpha: 1.0)
18 | }()
19 |
20 | public static let isPad = UIDevice.currentDevice().userInterfaceIdiom == .Pad
21 | }
22 |
23 | public func LocalizedString(key: String, comment: String = "") -> String {
24 | return NSLocalizedString(key, comment: comment)
25 | }
26 |
27 | public let LayoutPriorityRequired = UILayoutPriority(1000)
28 | public let LayoutPriorityDefaultLow = UILayoutPriority(250)
29 |
--------------------------------------------------------------------------------
/CoinsKit/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.nothingmagical.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Coins/Classes/PullToRefreshView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PullToRefreshView.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 11/26/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PullToRefreshView: SSPullToRefreshView {
12 |
13 | // MARK: - Initializers
14 |
15 | override init(scrollView: UIScrollView!, delegate: SSPullToRefreshViewDelegate!) {
16 | super.init(scrollView: scrollView, delegate: delegate)
17 |
18 | defaultContentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
19 |
20 | let contentView = SSPullToRefreshSimpleContentView()
21 | contentView.statusLabel.textColor = UIColor(white: 1, alpha: 0.8)
22 | contentView.statusLabel.font = UIFont(name: "Avenir-Light", size: 12)
23 | contentView.activityIndicatorView.activityIndicatorViewStyle = .White
24 | self.contentView = contentView
25 | }
26 |
27 | override init(frame: CGRect) {
28 | super.init(frame: frame)
29 | }
30 |
31 | required init(coder aDecoder: NSCoder) {
32 | fatalError("init(coder:) has not been implemented")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Coins Today/Resources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Coins
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | com.nothingmagical.coins.today
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0.2
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 6
25 | NSExtension
26 |
27 | NSExtensionPointIdentifier
28 | com.apple.widget-extension
29 | NSExtensionPrincipalClass
30 | BTCTodayViewController
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2014 Nothing Magical Inc., http://nothingmagical.com
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/Changelog.markdown:
--------------------------------------------------------------------------------
1 | # Coins Changelog
2 |
3 | Version history for [Coins for iOS](http://getcoinsapp.com).
4 |
5 | ## Version 1.1.3
6 | *Unrelased*
7 |
8 | * Fix a bug causing your bitcoin quanity to get reset for some users
9 | * Other improvements
10 |
11 |
12 | ## Version 1.1.2
13 | *Released October 23, 2014*
14 |
15 | Bug fixes for today widget
16 |
17 |
18 | ## Version 1.1.1
19 | *Released October 6, 2014*
20 |
21 | * Fix typing decimals
22 | * Other bug fixes
23 |
24 |
25 | ## Version 1.1
26 | *Released September 19, 2014*
27 |
28 | * Added support for iPhone 6 & iPhone 6 Plus
29 | * New today widget for iOS 8
30 | * New iCloud sync
31 | * Automatically refresh in the background
32 |
33 |
34 | ## Version 1.0.3
35 | *Released April 24, 2014*
36 |
37 | Bug fixes
38 |
39 |
40 | ## Version 1.0.1
41 | *Released January 11, 2014*
42 |
43 | * Automatically refresh when you come back to the app
44 | * Use 0 as the placeholder when entering your BTC
45 | * Fix a few rounding bugs
46 | * Added pull to refresh
47 | * Larger text on iPad
48 | * Fixed a bug that would prompt you to enter your BTC if you have less than one.
49 |
50 |
51 | ## Version 1.0
52 | *Released January 3, 2014*
53 |
54 | Initial release.
55 |
--------------------------------------------------------------------------------
/Coins/Classes/TickingButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TickingButton.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 11/25/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoinsKit
11 |
12 | class TickingButton: UIButton {
13 |
14 | // MARK: - Properties
15 |
16 | var ticking = false
17 |
18 | var date: NSDate? {
19 | didSet {
20 | tick()
21 | }
22 | }
23 |
24 | var format: String = "" {
25 | didSet {
26 | tick()
27 | }
28 | }
29 |
30 | var timer: NSTimer?
31 |
32 |
33 | // MARK: - Public
34 |
35 | func startTicking() {
36 | ticking = true
37 | let timer = NSTimer(timeInterval: 1, target: self, selector: "tick", userInfo: nil, repeats: true)
38 | NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
39 | self.timer = timer
40 | }
41 |
42 | func stopTicking() {
43 | if !ticking {
44 | return
45 | }
46 |
47 | ticking = false
48 | timer?.invalidate()
49 | timer = nil
50 | }
51 |
52 | func tick() {
53 | var title = LocalizedString("NEVER_UPDATED")
54 | if let date = date {
55 | // This is gross
56 | title = (format as NSString).stringByReplacingOccurrencesOfString("%@", withString: date.timeAgoInWords)
57 | }
58 | setTitle(title, forState: .Normal)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Readme.markdown:
--------------------------------------------------------------------------------
1 | # Coins
2 |
3 | A simple app to see how much your wallet is worth. It's like [Shares](http://getsharesapp.com) but for Bitcoin.
4 |
5 |
6 | ## Building
7 |
8 | You’ll need [CocoaPods](http://cocoapods.org) to build Coins. See their [getting start guide](http://guides.cocoapods.org/using/getting-started.html#getting-started) if you don’t already have CocoaPods.
9 |
10 | You'll also need [Carthage](https://github.com/Carthage/Carthage). See their [installation guide](https://github.com/Carthage/Carthage#installing-carthage) if you don't already have Carthage installed. (Eventually, I'd love to just have Carthage instead of both.)
11 |
12 | Xcode 6.0 or higher is required.
13 |
14 | Simply run `pod install`, `carthage update`, open `Coins.xcworkspace`, and build the *Coins* target to run the app.
15 |
16 |
17 | ## Related Repos
18 |
19 | * [Coins Website](https://github.com/nothingmagical/getcoinsapp.com)
20 | * [Coins for Android](https://github.com/nothingmagical/coins-android)
21 |
22 |
23 | ## License
24 |
25 | Coins is released under the [MIT license](LICENSE). While the license says you can do whatever you want with it, I'd apprecaite it if you don't release an exact copy to the App Store. This is released as an open source project primarily for educational purposes. That said, there's nothing stopping you from doing whatever you want with it.
26 |
--------------------------------------------------------------------------------
/Coins/Resources/Settings.bundle/Root.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | Title
9 | GENERAL
10 | Type
11 | PSGroupSpecifier
12 |
13 |
14 | DefaultValue
15 |
16 | Key
17 | BTCAutomaticallyRefresh
18 | Title
19 | AUTOMATICALLY_REFRESH
20 | Type
21 | PSToggleSwitchSpecifier
22 |
23 |
24 | DefaultValue
25 |
26 | Key
27 | BTCDisableSleep
28 | Title
29 | DISABLE_SLEEP
30 | Type
31 | PSToggleSwitchSpecifier
32 |
33 |
34 | Title
35 | ABOUT
36 | Type
37 | PSGroupSpecifier
38 |
39 |
40 | Type
41 | PSTitleValueSpecifier
42 | Title
43 | VERSION
44 | DefaultValue
45 |
46 | Key
47 | BTCVersion
48 |
49 |
50 | StringsTable
51 | Root
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Coins/Classes/TextField.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextField.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 11/25/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TextField: UITextField {
12 |
13 | // MARK: - Initializers
14 |
15 | override convenience init() {
16 | self.init(frame: CGRectZero)
17 | }
18 |
19 | override init(frame: CGRect) {
20 | super.init(frame: frame)
21 |
22 | keyboardType = .DecimalPad
23 | font = UIFont(name: "Avenir-Light", size: 24)
24 | textColor = UIColor.whiteColor()
25 | textAlignment = .Center
26 | tintColor = UIColor.whiteColor()
27 | backgroundColor = UIColor(white: 1, alpha: 0.1)
28 | layer.cornerRadius = 5
29 |
30 | attributedPlaceholder = NSAttributedString(string: "0", attributes: [
31 | NSForegroundColorAttributeName: UIColor(white: 1, alpha: 0.3),
32 | NSFontAttributeName: font
33 | ])
34 |
35 | let suffix = UILabel(frame: CGRect(x: 0, y: 0, width: 60, height: 54))
36 | suffix.text = "BTC"
37 | suffix.textColor = UIColor(white: 1, alpha: 0.3)
38 | suffix.font = font
39 | rightView = suffix
40 | rightViewMode = .Always
41 | }
42 |
43 | required init(coder aDecoder: NSCoder) {
44 | fatalError("init(coder:) has not been implemented")
45 | }
46 |
47 |
48 | // MARK: - UITextField
49 |
50 | override func textRectForBounds(bounds: CGRect) -> CGRect {
51 | return UIEdgeInsetsInsetRect(super.textRectForBounds(bounds), UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
52 | }
53 |
54 | override func editingRectForBounds(bounds: CGRect) -> CGRect {
55 | return textRectForBounds(bounds)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Settings@2x-1.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Settings@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Spotlight@2x-1.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Spotlight@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "iPhone@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "iPhone@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Settings.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Settings@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Spotlight.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Spotlight@2x.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "iPad.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "iPad@2x.png",
73 | "scale" : "2x"
74 | }
75 | ],
76 | "info" : {
77 | "version" : 1,
78 | "author" : "xcode"
79 | }
80 | }
--------------------------------------------------------------------------------
/Coins/Classes/NSDate+Coins.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+Coins.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 11/25/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension NSDate {
12 | var timeAgoInWords: String {
13 | let intervalInSeconds = fabs(timeIntervalSinceNow)
14 | // let includeSeconds = true
15 | let intervalInMinutes = round(intervalInSeconds / 60.0)
16 |
17 | if intervalInMinutes >= 0 && intervalInMinutes <= 1 {
18 | // if !includeSeconds {
19 | // return intervalInMinutes <= 0 ? "less than a minute ago" : "1 minute ago"
20 | // }
21 | if intervalInSeconds >= 0 && intervalInSeconds < 10 {
22 | return "just now"
23 | } else if intervalInSeconds >= 10 && intervalInSeconds < 60 {
24 | return "\(Int(intervalInSeconds)) seconds ago"
25 | } else {
26 | return "1 minute ago"
27 | }
28 | } else if intervalInMinutes >= 2 && intervalInMinutes <= 44 {
29 | return "\(Int(intervalInMinutes)) minutes ago"
30 | } else if intervalInMinutes >= 45 && intervalInMinutes <= 89 {
31 | return "about 1 hour ago"
32 | } else if intervalInMinutes >= 90 && intervalInMinutes <= 1439 {
33 | return "\(Int(ceil(intervalInMinutes / 60.0))) hours ago"
34 | } else if intervalInMinutes >= 1440 && intervalInMinutes <= 2879 {
35 | return "1 day ago"
36 | } else if intervalInMinutes >= 2880 && intervalInMinutes <= 43199 {
37 | return "\(Int(ceil(intervalInMinutes / 1440.0))) days ago"
38 | } else if intervalInMinutes >= 43200 && intervalInMinutes <= 86399 {
39 | return "1 month ago"
40 | } else if intervalInMinutes >= 86400 && intervalInMinutes <= 525599 {
41 | return "\(Int(ceil(intervalInMinutes / 43200.0))) months ago"
42 | } else if intervalInMinutes >= 525600 && intervalInMinutes <= 1051199 {
43 | return "1 year ago"
44 | }
45 |
46 | return "\(Int(ceil(intervalInMinutes / 525600.0))) years ago"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Coins/Classes/TableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TableViewCell.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 11/25/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoinsKit
11 |
12 | class TableViewCell: UITableViewCell {
13 |
14 | // MARK: - Initializers
15 |
16 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
17 | super.init(style: .Value1, reuseIdentifier: reuseIdentifier)
18 |
19 | textLabel?.font = UIFont(name: "Avenir-Heavy", size: 18)
20 | textLabel?.textColor = UIColor(white: 0.4, alpha: 1)
21 | textLabel?.highlightedTextColor = UIColor.whiteColor()
22 | textLabel?.adjustsFontSizeToFitWidth = true
23 |
24 | if let detailTextLabel = detailTextLabel {
25 | detailTextLabel.font = UIFont(name: "Avenir-Book", size: 18)
26 | detailTextLabel.textColor = UIColor(white: 0.4, alpha: 0.5)
27 | detailTextLabel.highlightedTextColor = UIColor.whiteColor()
28 | }
29 |
30 | if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
31 | let background = UIView()
32 | background.backgroundColor = UIColor(white: 1, alpha: 0.3)
33 | backgroundView = background
34 | }
35 |
36 | let selected = UIView()
37 | selected.backgroundColor = CoinsKit.blueColor
38 | selectedBackgroundView = selected
39 | }
40 |
41 | required init(coder aDecoder: NSCoder) {
42 | fatalError("init(coder:) has not been implemented")
43 | }
44 |
45 |
46 | // MARK: - UIView
47 |
48 | override func layoutSubviews() {
49 | super.layoutSubviews()
50 |
51 | if let textLabel = textLabel {
52 | var rect = textLabel.frame
53 | rect.size.width = min(rect.size.width, 240)
54 | textLabel.frame = rect
55 | }
56 |
57 | if let detailTextLabel = detailTextLabel {
58 | let size = contentView.bounds.size
59 | detailTextLabel.frame = CGRect(x: size.width - 70, y: 10, width: 60, height: size.height - 20)
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Coins/Resources/Coins-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.nothingmagical.coins
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.1.3
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleTypeRole
27 | Editor
28 | CFBundleURLName
29 | coins
30 | CFBundleURLSchemes
31 |
32 | coins
33 |
34 |
35 |
36 | CFBundleVersion
37 | 17
38 | LSRequiresIPhoneOS
39 |
40 | UIBackgroundModes
41 |
42 | fetch
43 |
44 | UIRequiredDeviceCapabilities
45 |
46 | armv7
47 |
48 | UIStatusBarHidden
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 | UIInterfaceOrientationPortraitUpsideDown
56 |
57 | UISupportedInterfaceOrientations~ipad
58 |
59 | UIInterfaceOrientationPortrait
60 | UIInterfaceOrientationPortraitUpsideDown
61 | UIInterfaceOrientationLandscapeLeft
62 | UIInterfaceOrientationLandscapeRight
63 |
64 | UIViewControllerBasedStatusBarAppearance
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/Coins/Resources/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "736h",
7 | "filename" : "5.5\" iPhone Portrait@3x.png",
8 | "minimum-system-version" : "8.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "736h",
16 | "filename" : "5.5\" iPhone Landscape@3x.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "landscape",
19 | "scale" : "3x"
20 | },
21 | {
22 | "extent" : "full-screen",
23 | "idiom" : "iphone",
24 | "subtype" : "667h",
25 | "filename" : "4.7\" iPhone Portrait@2x.png",
26 | "minimum-system-version" : "8.0",
27 | "orientation" : "portrait",
28 | "scale" : "2x"
29 | },
30 | {
31 | "orientation" : "portrait",
32 | "idiom" : "iphone",
33 | "extent" : "full-screen",
34 | "minimum-system-version" : "7.0",
35 | "filename" : "3.5\" iPhone Portrait@2x.png",
36 | "scale" : "2x"
37 | },
38 | {
39 | "extent" : "full-screen",
40 | "idiom" : "iphone",
41 | "subtype" : "retina4",
42 | "filename" : "4\" iPhone Portrait@2x.png",
43 | "minimum-system-version" : "7.0",
44 | "orientation" : "portrait",
45 | "scale" : "2x"
46 | },
47 | {
48 | "orientation" : "portrait",
49 | "idiom" : "ipad",
50 | "extent" : "full-screen",
51 | "minimum-system-version" : "7.0",
52 | "filename" : "iPad Portrait.png",
53 | "scale" : "1x"
54 | },
55 | {
56 | "orientation" : "landscape",
57 | "idiom" : "ipad",
58 | "extent" : "full-screen",
59 | "minimum-system-version" : "7.0",
60 | "filename" : "iPad Landscape.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "orientation" : "portrait",
65 | "idiom" : "ipad",
66 | "extent" : "full-screen",
67 | "minimum-system-version" : "7.0",
68 | "filename" : "iPad Portrait@2x.png",
69 | "scale" : "2x"
70 | },
71 | {
72 | "orientation" : "landscape",
73 | "idiom" : "ipad",
74 | "extent" : "full-screen",
75 | "minimum-system-version" : "7.0",
76 | "filename" : "iPad Landscape@2x.png",
77 | "scale" : "2x"
78 | }
79 | ],
80 | "info" : {
81 | "version" : 1,
82 | "author" : "xcode"
83 | }
84 | }
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCConversionProvider.m:
--------------------------------------------------------------------------------
1 | //
2 | // BTCConversionProvider.m
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 12/20/13.
6 | // Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCConversionProvider.h"
10 | #import "BTCPreferences.h"
11 |
12 | @implementation BTCConversionProvider
13 |
14 | static NSString *const BTCConversionProviderCacheKey = @"BTCConversion";
15 |
16 | + (instancetype)sharedProvider {
17 | static BTCConversionProvider *provider = nil;
18 | static dispatch_once_t onceToken;
19 | dispatch_once(&onceToken, ^{
20 | provider = [[self alloc] init];
21 | });
22 |
23 | return provider;
24 | }
25 |
26 |
27 | - (void)getConversionRates:(void (^)(NSDictionary *, UIBackgroundFetchResult))completion {
28 | NSURL *URL = [[NSURL alloc] initWithString:@"https://coinbase.com/api/v1/currencies/exchange_rates"];
29 | NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL];
30 | NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
31 | BTCPreferences *preferences = [BTCPreferences sharedPreferences];
32 | NSMutableDictionary *current = [[preferences objectForKey:BTCConversionProviderCacheKey] mutableCopy];
33 | NSDictionary *conversions = current;
34 |
35 | UIBackgroundFetchResult result = UIBackgroundFetchResultFailed;
36 |
37 | if (response && [(NSHTTPURLResponse *)response statusCode] == 200) {
38 | NSData *data = [[NSData alloc] initWithContentsOfURL:location];
39 | NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:nil];
40 |
41 | NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
42 | for (NSString *longKey in JSON) {
43 | if (![longKey hasPrefix:@"btc_to_"]) {
44 | continue;
45 | }
46 |
47 | NSString *key = [[longKey stringByReplacingOccurrencesOfString:@"btc_to_" withString:@""] uppercaseString];
48 | dictionary[key] = @([JSON[longKey] doubleValue]);
49 | }
50 |
51 | [current removeObjectForKey:@"updatedAt"];
52 |
53 | result = [current isEqualToDictionary:dictionary] ? UIBackgroundFetchResultNoData : UIBackgroundFetchResultNewData;
54 |
55 | dictionary[@"updatedAt"] = [NSDate date];
56 | [preferences setObject:dictionary forKey:BTCConversionProviderCacheKey];
57 | [preferences synchronize];
58 |
59 | conversions = dictionary;
60 | }
61 |
62 | dispatch_async(dispatch_get_main_queue(), ^{
63 | if (completion) {
64 | completion(conversions, result);
65 | }
66 | });
67 | }];
68 |
69 | [task resume];
70 | }
71 |
72 |
73 | - (NSDictionary *)latestConversionRates {
74 | return [[BTCPreferences sharedPreferences] objectForKey:BTCConversionProviderCacheKey];
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/Coins Today/Classes/BTCTodayValueView.m:
--------------------------------------------------------------------------------
1 | //
2 | // BTCTodayValueView.m
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCTodayValueView.h"
10 |
11 | @import NotificationCenter;
12 |
13 | @interface BTCTodayValueView ()
14 | @property (nonatomic, readonly) UIVisualEffectView *effectView;
15 | @end
16 |
17 | @implementation BTCTodayValueView
18 |
19 | #pragma mark - Accessors
20 |
21 | @synthesize effectView = _effectView;
22 |
23 | - (UIVisualEffectView *)effectView {
24 | if (!_effectView) {
25 | _effectView = [[UIVisualEffectView alloc] initWithEffect:[UIVibrancyEffect notificationCenterVibrancyEffect]];
26 | _effectView.translatesAutoresizingMaskIntoConstraints = NO;
27 | }
28 | return _effectView;
29 | }
30 |
31 |
32 | #pragma mark - UIView
33 |
34 | - (instancetype)initWithFrame:(CGRect)frame {
35 | if ((self = [super initWithFrame:frame])) {
36 | self.userInteractionEnabled = NO;
37 | }
38 | return self;
39 | }
40 |
41 |
42 | #pragma mark - BTCValueView
43 |
44 | - (void)setupViews {
45 | self.valueButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:40.0];
46 | self.valueButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
47 | [self addSubview:self.valueButton];
48 |
49 | [self.quantityButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
50 | self.quantityButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:18.0];
51 | self.quantityButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
52 | [self.effectView.contentView addSubview:self.quantityButton];
53 | [self addSubview:self.effectView];
54 | }
55 |
56 |
57 | - (void)setupConstraints {
58 | NSDictionary *views = @{
59 | @"valueButton": self.valueButton,
60 | @"quantityView": self.quantityButton,
61 | @"effectView": self.effectView
62 | };
63 |
64 | CGFloat verticalSpacing = [self verticalSpacing];
65 |
66 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[valueButton]-8-|" options:kNilOptions metrics:nil views:views]];
67 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.valueButton attribute:NSLayoutAttributeBaseline relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:-verticalSpacing]];
68 |
69 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[quantityView]|" options:kNilOptions metrics:nil views:views]];
70 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[quantityView]|" options:kNilOptions metrics:nil views:views]];
71 |
72 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[effectView]-8-|" options:kNilOptions metrics:nil views:views]];
73 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.effectView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.valueButton attribute:NSLayoutAttributeBaseline multiplier:1.0 constant:verticalSpacing / 2.0]];
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/Coins/Classes/CurrencyPickerTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CurrencyPickerTableViewController.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 12/20/13.
6 | // Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoinsKit
11 |
12 | class CurrencyPickerTableViewController: UITableViewController {
13 |
14 | // MARK: - Properties
15 |
16 | let currencies: [String: String]
17 | let order: [String]
18 | var selectedKey: String = BTCPreferences.sharedPreferences().objectForKey(kBTCSelectedCurrencyKey) as String
19 |
20 |
21 | // MARK: - Initializers
22 |
23 | override convenience init() {
24 | self.init(nibName: nil, bundle: nil)
25 | }
26 |
27 | override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
28 | let path = NSBundle.mainBundle().pathForResource("currencies", ofType: "json")!
29 | let data = NSData(contentsOfFile: path)!
30 | let JSON = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as [String: AnyObject]
31 | currencies = JSON["currencies"] as [String: String]
32 | order = JSON["order"] as [String]
33 |
34 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
35 | }
36 |
37 | required init(coder aDecoder: NSCoder) {
38 | fatalError("init(coder:) has not been implemented")
39 | }
40 |
41 |
42 | // MARK: - UIViewController
43 |
44 | override func viewDidLoad() {
45 | super.viewDidLoad()
46 |
47 | title = LocalizedString("CURRENCY")
48 |
49 | tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "Cell")
50 | }
51 |
52 | override func viewWillAppear(animated: Bool) {
53 | super.viewWillAppear(animated)
54 |
55 | if let index = find(order, selectedKey) {
56 | let indexPath = NSIndexPath(forRow: index, inSection: 0)
57 | tableView.selectRowAtIndexPath(indexPath, animated: animated, scrollPosition: .Middle)
58 | }
59 |
60 | navigationController?.setNavigationBarHidden(false, animated: animated)
61 | }
62 |
63 |
64 | // MARK: - UITableViewDataSource
65 |
66 | override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
67 | return countElements(order)
68 | }
69 |
70 | override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
71 | let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TableViewCell
72 | cell.selectionStyle = .Blue
73 |
74 | let key = order[indexPath.row]
75 |
76 | cell.textLabel?.text = currencies[key]
77 | cell.detailTextLabel?.text = key
78 |
79 | return cell
80 | }
81 |
82 |
83 | // MARK: - UITableViewDelegate
84 |
85 | override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
86 | let key = order[indexPath.row]
87 | let preferences = BTCPreferences.sharedPreferences()
88 | preferences.setObject(key, forKey: kBTCSelectedCurrencyKey)
89 | preferences.synchronize()
90 |
91 | NSNotificationCenter.defaultCenter().postNotificationName(kBTCCurrencyDidChangeNotificationName, object: key)
92 | navigationController?.popViewControllerAnimated(true)
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCPreferences.m:
--------------------------------------------------------------------------------
1 | //
2 | // BTCPreferences.m
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCPreferences.h"
10 | #import "NSUserDefaults+Coins.h"
11 |
12 | @interface BTCPreferences ()
13 | @property (nonatomic) NSDictionary *defaults;
14 | @end
15 |
16 | @implementation BTCPreferences
17 |
18 | #pragma mark - Accessors
19 |
20 | @synthesize defaults = _defaults;
21 |
22 | - (void)registerDefaults:(NSDictionary *)defaults {
23 | self.defaults = defaults;
24 | }
25 |
26 |
27 | - (id)objectForKey:(NSString *)key {
28 | id value = [[self defaultsStore] objectForKey:key];
29 | if (value) {
30 | return value;
31 | }
32 | return self.defaults[key];
33 | }
34 |
35 |
36 | - (double)doubleForKey:(NSString *)key {
37 | return [[self objectForKey:key] doubleValue];
38 | }
39 |
40 |
41 | - (void)setObject:(id)object forKey:(NSString *)key {
42 | [[self defaultsStore] setObject:object forKey:key];
43 | [[self iCloudStore] setObject:object forKey:key];
44 | }
45 |
46 |
47 | - (void)removeObjectForKey:(NSString *)key {
48 | [[self defaultsStore] removeObjectForKey:key];
49 | [[self iCloudStore] removeObjectForKey:key];
50 | }
51 |
52 |
53 | - (void)synchronize {
54 | [[self iCloudStore] synchronize];
55 | [[self defaultsStore] synchronize];
56 | }
57 |
58 |
59 | #pragma mark - Singleton
60 |
61 | + (instancetype)sharedPreferences {
62 | static BTCPreferences *preferences;
63 | static dispatch_once_t onceToken;
64 | dispatch_once(&onceToken, ^{
65 | preferences = [[self alloc] init];
66 | });
67 | return preferences;
68 | }
69 |
70 |
71 | #pragma mark - NSObject
72 |
73 | - (instancetype)init {
74 | if ((self = [super init])) {
75 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(iCloudStoreDidChange:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:nil];
76 | }
77 | return self;
78 | }
79 |
80 |
81 | - (void)dealloc {
82 | [[NSNotificationCenter defaultCenter] removeObserver:self];
83 | }
84 |
85 |
86 | #pragma mark - Private
87 |
88 | - (NSUserDefaults *)defaultsStore {
89 | return [NSUserDefaults btc_sharedDefaults];
90 | }
91 |
92 |
93 | - (NSUbiquitousKeyValueStore *)iCloudStore {
94 | return [NSUbiquitousKeyValueStore defaultStore];
95 | }
96 |
97 |
98 | - (void)iCloudStoreDidChange:(NSNotification *)notification {
99 | NSDictionary *userInfo = [notification userInfo];
100 | NSNumber *changeReason = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];
101 | NSInteger reason = -1;
102 |
103 | if (!changeReason) {
104 | return;
105 | } else {
106 | reason = [changeReason integerValue];
107 | }
108 |
109 | if (reason == NSUbiquitousKeyValueStoreServerChange || reason == NSUbiquitousKeyValueStoreInitialSyncChange) {
110 | NSArray *changedKeys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
111 | NSUbiquitousKeyValueStore *store = [self iCloudStore];
112 |
113 | for (NSString *key in changedKeys) {
114 | [[self defaultsStore] setObject:[store objectForKey:key] forKey:key];
115 | }
116 | }
117 | }
118 |
119 | @end
120 |
--------------------------------------------------------------------------------
/Coins Today/Classes/BTCTodayViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // BTCTodayViewController.m
3 | // Coins Today
4 | //
5 | // Created by Sam Soffes on 9/17/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCTodayViewController.h"
10 | #import "BTCTodayValueView.h"
11 |
12 | @import CoinsKit;
13 |
14 | @import NotificationCenter;
15 |
16 | @interface BTCTodayViewController ()
17 | @property (nonatomic, readonly) BTCValueView *valueView;
18 | @end
19 |
20 | @implementation BTCTodayViewController
21 |
22 | #pragma mark - Accessors
23 |
24 | @synthesize valueView = _valueView;
25 |
26 | - (BTCValueView *)valueView {
27 | if (!_valueView) {
28 | _valueView = [[BTCTodayValueView alloc] init];
29 | _valueView.translatesAutoresizingMaskIntoConstraints = NO;
30 | _valueView.conversionRates = [[BTCConversionProvider sharedProvider] latestConversionRates];
31 | }
32 | return _valueView;
33 | }
34 |
35 |
36 | #pragma mark - NSObject
37 |
38 | - (void)dealloc {
39 | [[NSNotificationCenter defaultCenter] removeObserver:self];
40 | }
41 |
42 |
43 | #pragma mark - UIViewController
44 |
45 | - (void)viewDidLoad {
46 | [super viewDidLoad];
47 |
48 | [self.view addSubview:self.valueView];
49 |
50 | NSDictionary *views = @{ @"valueView": self.valueView };
51 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[valueView]|" options:kNilOptions metrics:nil views:views]];
52 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[valueView(120)]|" options:kNilOptions metrics:nil views:views]];
53 |
54 | UIControl *control = [[UIControl alloc] init];
55 | control.frame = self.view.bounds;
56 | control.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
57 | [control addTarget:self action:@selector(openCoins:) forControlEvents:UIControlEventTouchUpInside];
58 | [self.view addSubview:control];
59 |
60 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:nil];
61 | }
62 |
63 |
64 | - (CGSize)preferredContentSize {
65 | return CGSizeMake(self.view.bounds.size.width, 88.0);
66 | }
67 |
68 |
69 | #pragma mark - Actions
70 |
71 | - (void)openCoins:(id)sender {
72 | [self.extensionContext openURL:[NSURL URLWithString:@"coins://open?ref=today"] completionHandler:nil];
73 | }
74 |
75 |
76 | #pragma mark - Private
77 |
78 | - (void)update {
79 | self.valueView.conversionRates = [[BTCConversionProvider sharedProvider] latestConversionRates];
80 | }
81 |
82 |
83 | #pragma mark - NCWidgetProviding
84 |
85 | - (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
86 | [[BTCConversionProvider sharedProvider] getConversionRates:^(NSDictionary *conversionRates, UIBackgroundFetchResult result) {
87 | [self update];
88 |
89 | if (completionHandler) {
90 | completionHandler((NCUpdateResult)result);
91 | }
92 | }];
93 | }
94 |
95 |
96 | - (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
97 | defaultMarginInsets.top = 8.0;
98 | defaultMarginInsets.bottom = 8.0;
99 | defaultMarginInsets.left += 2.0;
100 | return defaultMarginInsets;
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/Coins/Classes/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 11/25/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoinsKit
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 | // MARK: - Properties
16 |
17 | lazy var window: UIWindow = {
18 | let window = UIWindow(frame: UIScreen.mainScreen().bounds)
19 | window.backgroundColor = UIColor.blackColor()
20 | window.rootViewController = UINavigationController(rootViewController: BTCValueViewController())
21 | return window
22 | }()
23 |
24 |
25 | // MARK: - Private
26 |
27 | private func configureAnalytics() {
28 | #if !DEBUG
29 | // Hockey
30 | BITHockeyManager.sharedHockeyManager().configureWithIdentifier("d0d82a50debc14c4fde0cb3430893bd6")
31 | BITHockeyManager.sharedHockeyManager().startManager()
32 | BITHockeyManager.sharedHockeyManager().authenticator.authenticateInstallation()
33 |
34 | // Mixpanel
35 | let mixpanel = Mixpanel.sharedInstanceWithToken("a487667944fcb1107bcaa025b3ca744c")
36 | mixpanel.showNetworkActivityIndicator = false
37 | #endif
38 | }
39 |
40 | private func configureAppearance() {
41 | let navigationBar = UINavigationBar.appearance()
42 | navigationBar.barTintColor = CoinsKit.blueColor
43 | navigationBar.tintColor = UIColor(white: 1, alpha: 0.5)
44 | navigationBar.titleTextAttributes = [
45 | NSForegroundColorAttributeName: UIColor.whiteColor(),
46 | NSFontAttributeName: UIFont(name: "Avenir-Heavy", size: 20)!
47 | ]
48 | }
49 |
50 |
51 | private func configureDefaults() {
52 | let standardDefaults = NSUserDefaults.standardUserDefaults()
53 | standardDefaults.registerDefaults([
54 | kBTCAutomaticallyRefreshKey: true,
55 | kBTCDisableSleepKey: false,
56 | kBTCControlsHiddenKey: false,
57 | "BTCMigrated": false
58 | ])
59 |
60 | let preferences = BTCPreferences.sharedPreferences()
61 | preferences.registerDefaults([
62 | kBTCSelectedCurrencyKey: "USD",
63 | kBTCNumberOfCoinsKey: 0
64 | ])
65 |
66 | if standardDefaults.boolForKey("BTCMigrated") {
67 | let keys = [kBTCSelectedCurrencyKey, kBTCNumberOfCoinsKey]
68 | for key in keys {
69 | if let value = standardDefaults.objectForKey(key) as? NSCoding {
70 | preferences.setObject(value, forKey: key)
71 | }
72 | }
73 | preferences.synchronize()
74 |
75 | standardDefaults.setBool(true, forKey: "BTCMigrated")
76 | standardDefaults.synchronize()
77 | }
78 | }
79 |
80 |
81 | // MARK: - UIApplicationDelegate
82 |
83 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
84 | configureAnalytics()
85 |
86 | application.statusBarStyle = .LightContent
87 | application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
88 |
89 | configureAppearance()
90 | configureDefaults()
91 |
92 | window.makeKeyAndVisible()
93 |
94 | dispatch_async(dispatch_get_main_queue()) {
95 | let info = NSBundle.mainBundle().infoDictionary!
96 | let shortVersion = (info["CFBundleShortVersionString"] as String)
97 | let version = (info["CFBundleVersion"] as String)
98 | let versionString = "\(shortVersion) (\(version))"
99 | let standardDefaults = NSUserDefaults.standardUserDefaults()
100 | standardDefaults.setObject(versionString, forKey: "BTCVersion")
101 | standardDefaults.synchronize()
102 | }
103 |
104 | return true
105 | }
106 |
107 | func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
108 | BTCConversionProvider.sharedProvider().getConversionRates { conversionRate, result in
109 | completionHandler(result)
110 | }
111 | }
112 |
113 | func applicationDidBecomeActive(application: UIApplication) {
114 | #if !DEBUG
115 | Mixpanel.sharedInstance().track("Active")
116 | #endif
117 | }
118 |
119 | func applicationWillResignActive(application: UIApplication) {
120 | #if !DEBUG
121 | Mixpanel.sharedInstance().flush()
122 | #endif
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/CoinsKit/Classes/BTCValueView.m:
--------------------------------------------------------------------------------
1 | //
2 | // BTCValueView.m
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 4/23/14.
6 | // Copyright (c) 2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | #import "BTCValueView.h"
10 | #import "BTCPreferences.h"
11 | #import "BTCDefines.h"
12 |
13 | @implementation BTCValueView
14 |
15 | #pragma mark - Accessors
16 |
17 | @synthesize conversionRates = _conversionRates;
18 | @synthesize valueButton = _valueButton;
19 | @synthesize quantityButton = _quantityButton;
20 |
21 | - (void)setConversionRates:(NSDictionary *)conversionRates {
22 | _conversionRates = conversionRates;
23 |
24 | static NSNumberFormatter *currencyFormatter = nil;
25 | static dispatch_once_t currencyOnceToken;
26 | dispatch_once(¤cyOnceToken, ^{
27 | currencyFormatter = [[NSNumberFormatter alloc] init];
28 | currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
29 | });
30 |
31 | BTCPreferences *preferences = [BTCPreferences sharedPreferences];
32 | currencyFormatter.currencyCode = [preferences objectForKey:kBTCSelectedCurrencyKey];
33 | double value = [[preferences objectForKey:kBTCNumberOfCoinsKey] doubleValue] * [conversionRates[currencyFormatter.currencyCode] doubleValue];
34 | [self.valueButton setTitle:[currencyFormatter stringFromNumber:@(value)] forState:UIControlStateNormal];
35 |
36 | static NSNumberFormatter *numberFormatter = nil;
37 | static dispatch_once_t numberOnceToken;
38 | dispatch_once(&numberOnceToken, ^{
39 | numberFormatter = [[NSNumberFormatter alloc] init];
40 | numberFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
41 | numberFormatter.currencySymbol = @"";
42 | numberFormatter.minimumFractionDigits = 0;
43 | numberFormatter.maximumFractionDigits = 10;
44 | numberFormatter.roundingMode = NSNumberFormatterRoundDown;
45 | });
46 |
47 | NSNumber *number = [preferences objectForKey:kBTCNumberOfCoinsKey];
48 |
49 | NSString *title = [numberFormatter stringFromNumber:number];
50 | [self.quantityButton setTitle:[NSString stringWithFormat:@"%@ BTC", title ? title : @"0"] forState:UIControlStateNormal];
51 | }
52 |
53 | - (UIButton *)valueButton {
54 | if (!_valueButton) {
55 | _valueButton = [[UIButton alloc] init];
56 | _valueButton.translatesAutoresizingMaskIntoConstraints = NO;
57 | _valueButton.titleLabel.font = [UIFont fontWithName:@"Avenir-Heavy" size:UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 80.0 : 50.0];
58 | _valueButton.titleLabel.adjustsFontSizeToFitWidth = YES;
59 | _valueButton.titleLabel.textAlignment = NSTextAlignmentCenter;
60 | [_valueButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
61 | }
62 | return _valueButton;
63 | }
64 |
65 |
66 | - (UIButton *)quantityButton {
67 | if (!_quantityButton) {
68 | _quantityButton = [[UIButton alloc] init];
69 | _quantityButton.translatesAutoresizingMaskIntoConstraints = NO;
70 | _quantityButton.titleLabel.font = [UIFont fontWithName:@"Avenir-Light" size:UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 30.0 : 20.0];
71 | [_quantityButton setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.5f] forState:UIControlStateNormal];
72 | }
73 | return _quantityButton;
74 | }
75 |
76 |
77 | #pragma mark - UIView
78 |
79 | - (instancetype)initWithFrame:(CGRect)frame {
80 | if ((self = [super initWithFrame:frame])) {
81 | self.translatesAutoresizingMaskIntoConstraints = NO;
82 | self.backgroundColor = [UIColor clearColor];
83 |
84 | [self setupViews];
85 | [self setupConstraints];
86 | }
87 | return self;
88 | }
89 |
90 |
91 | #pragma mark - Configuration
92 |
93 | - (CGFloat)verticalSpacing {
94 | return 16.0;
95 | }
96 |
97 |
98 | - (void)setupViews {
99 | [self addSubview:self.valueButton];
100 | [self addSubview:self.quantityButton];
101 | }
102 |
103 |
104 | #pragma mark - Private
105 |
106 | - (void)setupConstraints {
107 | NSDictionary *views = @{
108 | @"valueButton": self.valueButton,
109 | @"quantityView": self.quantityButton
110 | };
111 |
112 | CGFloat verticalSpacing = [self verticalSpacing];
113 |
114 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[valueButton]-|" options:kNilOptions metrics:nil views:views]];
115 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.valueButton attribute:NSLayoutAttributeBaseline relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:-verticalSpacing]];
116 |
117 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[quantityView]-|" options:kNilOptions metrics:nil views:views]];
118 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.quantityButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.valueButton attribute:NSLayoutAttributeBaseline multiplier:1.0 constant:verticalSpacing / 2.0]];
119 | }
120 |
121 | @end
122 |
--------------------------------------------------------------------------------
/Coins/Resources/currencies.json:
--------------------------------------------------------------------------------
1 | {
2 | "currencies": {
3 | "AED": "United Arab Emirates dirham",
4 | "AFN": "Afghan afghani",
5 | "ALL": "Albanian lek",
6 | "AMD": "Armenian dram",
7 | "ANG": "Netherlands Antillean guilder",
8 | "AOA": "Angolan kwanza",
9 | "ARS": "Argentine peso",
10 | "AUD": "Australian dollar",
11 | "AWG": "Aruban florin",
12 | "AZN": "Azerbaijani manat",
13 | "BAM": "Bosnia and Herzegovina convertible mark",
14 | "BBD": "Barbadian dollar",
15 | "BDT": "Bangladeshi taka",
16 | "BGN": "Bulgarian lev",
17 | "BHD": "Bahraini dinar",
18 | "BIF": "Burundian franc",
19 | "BMD": "Bermudian dollar",
20 | "BND": "Brunei dollar",
21 | "BOB": "Bolivian boliviano",
22 | "BRL": "Brazilian real",
23 | "BSD": "Bahamian dollar",
24 | "BTN": "Bhutanese ngultrum",
25 | "BWP": "Botswana pula",
26 | "BYR": "Belarusian ruble",
27 | "BZD": "Belize dollar",
28 | "CAD": "Canadian dollar",
29 | "CDF": "Congolese franc",
30 | "CHF": "Swiss franc",
31 | "CLP": "Chilean peso",
32 | "CNY": "Chinese yuan",
33 | "COP": "Colombian peso",
34 | "CRC": "Costa Rican col\u00f3n",
35 | "CUP": "Cuban peso",
36 | "CVE": "Cape Verdean escudo",
37 | "CZK": "Czech koruna",
38 | "DJF": "Djiboutian franc",
39 | "DKK": "Danish krone",
40 | "DOP": "Dominican peso",
41 | "DZD": "Algerian dinar",
42 | "EGP": "Egyptian pound",
43 | "ETB": "Ethiopian birr",
44 | "EUR": "Euro",
45 | "FJD": "Fijian dollar",
46 | "FKP": "Falkland Islands pound",
47 | "GBP": "Pound sterling",
48 | "GEL": "Georgian lari",
49 | "GHS": "Ghana cedi",
50 | "GIP": "Gibraltar pound",
51 | "GMD": "Gambian dalasi",
52 | "GNF": "Guinean franc",
53 | "GTQ": "Guatemalan quetzal",
54 | "GYD": "Guyanese dollar",
55 | "HKD": "Hong Kong dollar",
56 | "HNL": "Honduran lempira",
57 | "HRK": "Croatian kuna",
58 | "HTG": "Haitian gourde",
59 | "HUF": "Hungarian forint",
60 | "IDR": "Indonesian rupiah",
61 | "ILS": "Israeli new shekel",
62 | "INR": "Indian rupee",
63 | "IQD": "Iraqi dinar",
64 | "IRR": "Iranian rial",
65 | "ISK": "Icelandic kr\u00f3na",
66 | "JEP": "Jersey pound",
67 | "JMD": "Jamaican dollar",
68 | "JOD": "Jordanian dinar",
69 | "JPY": "Japanese yen",
70 | "KES": "Kenyan shilling",
71 | "KGS": "Kyrgyzstani som",
72 | "KHR": "Cambodian riel",
73 | "KMF": "Comorian franc",
74 | "KPW": "North Korean won",
75 | "KRW": "South Korean won",
76 | "KWD": "Kuwaiti dinar",
77 | "KYD": "Cayman Islands dollar",
78 | "KZT": "Kazakhstani tenge",
79 | "LAK": "Lao kip",
80 | "LBP": "Lebanese pound",
81 | "LKR": "Sri Lankan rupee",
82 | "LRD": "Liberian dollar",
83 | "LSL": "Lesotho loti",
84 | "LTL": "Lithuanian litas",
85 | "LVL": "Latvian lats",
86 | "LYD": "Libyan dinar",
87 | "MAD": "Moroccan dirham",
88 | "MDL": "Moldovan leu",
89 | "MGA": "Malagasy ariary",
90 | "MKD": "Macedonian denar",
91 | "MMK": "Burmese kyat",
92 | "MNT": "Mongolian t\u00f6gr\u00f6g",
93 | "MOP": "Macanese pataca",
94 | "MRO": "Mauritanian ouguiya",
95 | "MUR": "Mauritian rupee",
96 | "MVR": "Maldivian rufiyaa",
97 | "MWK": "Malawian kwacha",
98 | "MXN": "Mexican peso",
99 | "MYR": "Malaysian ringgit",
100 | "MZN": "Mozambican metical",
101 | "NAD": "Namibian dollar",
102 | "NGN": "Nigerian naira",
103 | "NIO": "Nicaraguan c\u00f3rdoba",
104 | "NOK": "Norwegian krone",
105 | "NPR": "Nepalese rupee",
106 | "NZD": "New Zealand dollar",
107 | "OMR": "Omani rial",
108 | "PAB": "Panamanian balboa",
109 | "PEN": "Peruvian nuevo sol",
110 | "PGK": "Papua New Guinean kina",
111 | "PHP": "Philippine peso",
112 | "PKR": "Pakistani rupee",
113 | "PLN": "Polish z\u0142oty",
114 | "PYG": "Paraguayan guaran\u00ed",
115 | "QAR": "Qatari riyal",
116 | "RMB": "Renminbi",
117 | "RON": "Romanian leu",
118 | "RSD": "Serbian dinar",
119 | "RUB": "Russian ruble",
120 | "RWF": "Rwandan franc",
121 | "SAR": "Saudi riyal",
122 | "SBD": "Solomon Islands dollar",
123 | "SCR": "Seychellois rupee",
124 | "SDG": "Sudanese pound",
125 | "SEK": "Swedish krona",
126 | "SGD": "Singapore dollar",
127 | "SHP": "Saint Helena pound",
128 | "SLL": "Sierra Leonean leone",
129 | "SOS": "Somali shilling",
130 | "SRD": "Surinamese dollar",
131 | "STD": "S\u00e3o Tom\u00e9 and Pr\u00edncipe dobra",
132 | "SVC": "Salvadoran col\u00f3n",
133 | "SYP": "Syrian pound",
134 | "SZL": "Swazi lilangeni",
135 | "THB": "Thai baht",
136 | "TJS": "Tajikistani somoni",
137 | "TMT": "Turkmenistan manat",
138 | "TND": "Tunisian dinar",
139 | "TRY": "Turkish lira",
140 | "TTD": "Trinidad and Tobago dollar",
141 | "TWD": "New Taiwan dollar",
142 | "TZS": "Tanzanian shilling",
143 | "UAH": "Ukrainian hryvnia",
144 | "UGX": "Ugandan shilling",
145 | "USD": "United States dollar",
146 | "UYU": "Uruguayan peso",
147 | "UZS": "Uzbekistani som",
148 | "VEF": "Venezuelan bol\u00edvar",
149 | "VND": "Vietnamese \u0111\u1ed3ng",
150 | "VUV": "Vanuatu vatu",
151 | "WST": "Samoan t\u0101l\u0101",
152 | "XAF": "Central African CFA franc",
153 | "XCD": "East Caribbean dollar",
154 | "XOF": "West African CFA franc",
155 | "XPF": "CFP franc",
156 | "YER": "Yemeni rial",
157 | "ZAR": "South African rand",
158 | "ZMW": "Zambian kwacha",
159 | "ZWL": "Zimbabwean dollar"
160 | },
161 | "order": [
162 | "USD",
163 | "GBP",
164 | "HKD",
165 | "CAD",
166 | "EUR",
167 | "AUD",
168 | "AED",
169 | "AFN",
170 | "ALL",
171 | "AMD",
172 | "ANG",
173 | "AOA",
174 | "ARS",
175 | "AWG",
176 | "AZN",
177 | "BAM",
178 | "BBD",
179 | "BDT",
180 | "BGN",
181 | "BHD",
182 | "BIF",
183 | "BMD",
184 | "BND",
185 | "BOB",
186 | "BRL",
187 | "BSD",
188 | "BTN",
189 | "BWP",
190 | "BYR",
191 | "BZD",
192 | "CDF",
193 | "CHF",
194 | "CLP",
195 | "CNY",
196 | "COP",
197 | "CRC",
198 | "CUP",
199 | "CVE",
200 | "CZK",
201 | "DJF",
202 | "DKK",
203 | "DOP",
204 | "DZD",
205 | "EGP",
206 | "ETB",
207 | "FJD",
208 | "FKP",
209 | "GEL",
210 | "GHS",
211 | "GIP",
212 | "GMD",
213 | "GNF",
214 | "GTQ",
215 | "GYD",
216 | "HNL",
217 | "HRK",
218 | "HTG",
219 | "HUF",
220 | "IDR",
221 | "ILS",
222 | "INR",
223 | "IQD",
224 | "IRR",
225 | "ISK",
226 | "JMD",
227 | "JOD",
228 | "JPY",
229 | "KES",
230 | "KGS",
231 | "KHR",
232 | "KMF",
233 | "KPW",
234 | "KRW",
235 | "KWD",
236 | "KYD",
237 | "KZT",
238 | "LAK",
239 | "LBP",
240 | "LKR",
241 | "LRD",
242 | "LSL",
243 | "LTL",
244 | "LVL",
245 | "LYD",
246 | "MAD",
247 | "MDL",
248 | "MGA",
249 | "MKD",
250 | "MMK",
251 | "MNT",
252 | "MOP",
253 | "MRO",
254 | "MUR",
255 | "MVR",
256 | "MWK",
257 | "MXN",
258 | "MYR",
259 | "MZN",
260 | "NAD",
261 | "NGN",
262 | "NIO",
263 | "NOK",
264 | "NPR",
265 | "NZD",
266 | "OMR",
267 | "PAB",
268 | "PEN",
269 | "PGK",
270 | "PHP",
271 | "PKR",
272 | "PLN",
273 | "PYG",
274 | "QAR",
275 | "RON",
276 | "RSD",
277 | "RUB",
278 | "RWF",
279 | "SAR",
280 | "SBD",
281 | "SCR",
282 | "SDG",
283 | "SEK",
284 | "SGD",
285 | "SHP",
286 | "SLL",
287 | "SOS",
288 | "SRD",
289 | "STD",
290 | "SVC",
291 | "SYP",
292 | "SZL",
293 | "THB",
294 | "TJS",
295 | "TND",
296 | "TRY",
297 | "TTD",
298 | "TWD",
299 | "TZS",
300 | "UAH",
301 | "UGX",
302 | "UYU",
303 | "UZS",
304 | "VEF",
305 | "VND",
306 | "VUV",
307 | "WST",
308 | "XAF",
309 | "XCD",
310 | "XOF",
311 | "XPF",
312 | "YER",
313 | "ZAR",
314 | "ZWL"
315 | ]
316 | }
317 |
--------------------------------------------------------------------------------
/Coins/Classes/ValueViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ValueViewController.swift
3 | // Coins
4 | //
5 | // Created by Sam Soffes on 12/20/13.
6 | // Copyright (c) 2013-2014 Nothing Magical, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoinsKit
11 | import GradientView
12 |
13 | class BTCValueViewController: UIViewController, UITextFieldDelegate, SSPullToRefreshViewDelegate {
14 |
15 | // MARK: - Properties
16 |
17 | let flapsView: GradientView = {
18 | let view = GradientView()
19 | view.autoresizingMask = .FlexibleWidth | .FlexibleHeight
20 | view.colors = [CoinsKit.blueColor, CoinsKit.purpleColor]
21 | view.locations = [0.5, 0.51]
22 | return view
23 | }()
24 |
25 | let scrollView: UIScrollView = {
26 | let view = UIScrollView()
27 | view.setTranslatesAutoresizingMaskIntoConstraints(false)
28 | view.showsHorizontalScrollIndicator = false
29 | view.showsVerticalScrollIndicator = false
30 | view.alwaysBounceVertical = true
31 | return view
32 | }()
33 |
34 | var pullToRefresh: SSPullToRefreshView!
35 |
36 | let backgroundView: GradientView = {
37 | let view = GradientView()
38 | view.setTranslatesAutoresizingMaskIntoConstraints(false)
39 | view.colors = [CoinsKit.blueColor, CoinsKit.purpleColor]
40 | return view
41 | }()
42 |
43 | let valueView = BTCValueView()
44 |
45 | let updateButton: TickingButton = {
46 | let view = TickingButton()
47 | view.setTranslatesAutoresizingMaskIntoConstraints(false)
48 | view.setTitleColor(UIColor(white: 1, alpha: 0.3), forState: .Normal)
49 | view.setTitleColor(UIColor(white: 1, alpha: 0.8), forState: .Highlighted)
50 | view.titleLabel?.font = UIFont(name: "Avenir-Light", size: 12)
51 | view.titleLabel?.textAlignment = .Center
52 | return view
53 | }()
54 |
55 | let textField: TextField = {
56 | let view = TextField()
57 | view.setTranslatesAutoresizingMaskIntoConstraints(false)
58 | view.alpha = 0
59 | return view
60 | }()
61 |
62 | let doneButton: UIButton = {
63 | let view = UIButton()
64 | view.setTranslatesAutoresizingMaskIntoConstraints(false)
65 | view.titleLabel?.font = UIFont(name: "Avenir-Light", size: 14)
66 | view.alpha = 0
67 | view.setTitleColor(UIColor(white: 1, alpha: 0.5), forState: .Normal)
68 | view.setTitleColor(UIColor.whiteColor(), forState: .Highlighted)
69 | view.setTitle(LocalizedString("DONE"), forState: .Normal)
70 | view.contentEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
71 | view.layer.borderColor = UIColor(white: 1, alpha: 0.5).CGColor
72 | view.layer.borderWidth = 1
73 | view.layer.cornerRadius = 5
74 | return view
75 | }()
76 |
77 | var currencyPopover: UIPopoverController?
78 |
79 | var controlsHidden: Bool = false
80 |
81 | var loading: Bool = false {
82 | didSet {
83 | UIApplication.sharedApplication().networkActivityIndicatorVisible = loading
84 |
85 | if loading {
86 | updateButton.format = LocalizedString("UPDATING")
87 | pullToRefresh.startLoading()
88 | } else {
89 | updateButton.format = LocalizedString("UPDATED_FORMAT")
90 | pullToRefresh.finishLoading()
91 | }
92 | }
93 | }
94 |
95 | var autoRefreshing: Bool = false {
96 | didSet {
97 | if autoRefreshing && autoRefreshTimer == nil {
98 | let timer = NSTimer(timeInterval: 60, target: self, selector: "refresh:", userInfo: nil, repeats: true)
99 | NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
100 | autoRefreshTimer = timer
101 | } else {
102 | autoRefreshTimer?.invalidate()
103 | }
104 | }
105 | }
106 |
107 | var autoRefreshTimer: NSTimer?
108 |
109 | var doneButtonTopConstraint: NSLayoutConstraint!
110 |
111 | var textFieldTopConstraint: NSLayoutConstraint!
112 |
113 | var keyboardFrame: CGRect = CGRectZero
114 |
115 |
116 | // MARK: - Initializers
117 |
118 | deinit {
119 | NSNotificationCenter.defaultCenter().removeObserver(self)
120 | }
121 |
122 |
123 | // MARK: - UIViewController
124 |
125 | override func viewDidLoad() {
126 | super.viewDidLoad()
127 |
128 | automaticallyAdjustsScrollViewInsets = false
129 | navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
130 |
131 | textField.delegate = self
132 | doneButton.addTarget(self, action: "toggleControls", forControlEvents: .TouchUpInside)
133 | valueView.valueButton.addTarget(self, action: "pickCurrency", forControlEvents: .TouchUpInside)
134 | valueView.quantityButton.addTarget(self, action: "startEditing", forControlEvents: .TouchUpInside)
135 | updateButton.addTarget(self, action: "refresh", forControlEvents: .TouchUpInside)
136 |
137 | flapsView.frame = view.bounds
138 | view.addSubview(flapsView)
139 |
140 | view.addSubview(scrollView)
141 | self.pullToRefresh = PullToRefreshView(scrollView: scrollView, delegate: self)
142 |
143 | scrollView.addSubview(backgroundView)
144 | backgroundView.addSubview(valueView)
145 | view.addSubview(updateButton)
146 | view.addSubview(textField)
147 | view.addSubview(doneButton)
148 |
149 | setupViewConstraints()
150 |
151 | let tap = UITapGestureRecognizer(target: self, action: "toggleControls")
152 | scrollView.addGestureRecognizer(tap)
153 |
154 | let notificationCenter = NSNotificationCenter.defaultCenter()
155 | notificationCenter.addObserver(self, selector: "textFieldDidChange:", name: UITextFieldTextDidChangeNotification, object: nil)
156 | notificationCenter.addObserver(self, selector: "updateTimerPaused", name: UIApplicationDidEnterBackgroundNotification, object: nil)
157 | notificationCenter.addObserver(self, selector: "updateTimerPaused", name: UIApplicationDidBecomeActiveNotification, object: nil)
158 | notificationCenter.addObserver(self, selector: "keyboardWillChangeFrame:", name: UIKeyboardWillChangeFrameNotification, object: nil)
159 |
160 | notificationCenter.addObserver(self, selector: "update", name: kBTCCurrencyDidChangeNotificationName, object: nil)
161 | notificationCenter.addObserver(self, selector: "update", name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification, object: nil)
162 | update()
163 |
164 | notificationCenter.addObserver(self, selector: "refresh", name: UIApplicationDidBecomeActiveNotification, object: nil)
165 | refresh()
166 |
167 | notificationCenter.addObserver(self, selector: "preferencesDidChange", name: NSUserDefaultsDidChangeNotification, object: nil)
168 | preferencesDidChange()
169 |
170 | setControlsHidden(NSUserDefaults.standardUserDefaults().boolForKey(kBTCControlsHiddenKey), animated: false)
171 | }
172 |
173 | override func viewWillAppear(animated: Bool) {
174 | super.viewWillAppear(animated)
175 |
176 | update()
177 | navigationController?.setNavigationBarHidden(true, animated: animated)
178 |
179 | updateButton.startTicking()
180 | autoRefreshing = NSUserDefaults.standardUserDefaults().boolForKey(kBTCAutomaticallyRefreshKey)
181 |
182 | if BTCPreferences.sharedPreferences().doubleForKey(kBTCNumberOfCoinsKey) == 0.0 {
183 | setEditing(true, animated: animated)
184 | }
185 | }
186 |
187 | override func viewDidDisappear(animated: Bool) {
188 | super.viewDidDisappear(animated)
189 | updateButton.stopTicking()
190 | autoRefreshing = false
191 | }
192 |
193 | override func setEditing(editing: Bool, animated: Bool) {
194 | super.setEditing(editing, animated: animated)
195 |
196 | if editing {
197 | view.addConstraint(doneButtonTopConstraint)
198 | view.addConstraint(textFieldTopConstraint)
199 | textField.becomeFirstResponder()
200 | } else {
201 | view.removeConstraint(doneButtonTopConstraint)
202 | view.removeConstraint(textFieldTopConstraint)
203 | textField.resignFirstResponder()
204 | BTCPreferences.sharedPreferences().synchronize()
205 | }
206 |
207 | let animations: () -> Void = {
208 | self.textField.alpha = editing ? 1 : 0
209 | self.doneButton.alpha = self.textField.alpha
210 | self.valueView.valueButton.alpha = editing ? 0.0 : 1.0
211 | self.valueView.quantityButton.alpha = self.valueView.valueButton.alpha
212 | }
213 |
214 | if (animated) {
215 | UIView.animateWithDuration(0.3, animations: animations)
216 | UIView.animateWithDuration(0.8, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 1, options: nil, animations: { () -> Void in
217 | self.view.layoutIfNeeded()
218 | }, completion: nil)
219 | } else {
220 | animations()
221 | }
222 | }
223 |
224 |
225 | override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
226 | super.didRotateFromInterfaceOrientation(fromInterfaceOrientation)
227 |
228 | currencyPopover?.dismissPopoverAnimated(true)
229 | updateDoneButtonTopLayoutConstraint()
230 | }
231 |
232 |
233 | // MARK - Actions
234 |
235 | func refresh() {
236 | if loading {
237 | return
238 | }
239 |
240 | loading = true
241 |
242 | BTCConversionProvider.sharedProvider().getConversionRates() { conversionRates, result in
243 | self.update()
244 | self.loading = false
245 | }
246 | }
247 |
248 | func pickCurrency() {
249 | let viewController = CurrencyPickerTableViewController()
250 |
251 | if CoinsKit.isPad {
252 | let navigationController = UINavigationController(rootViewController: viewController)
253 | let popover = UIPopoverController(contentViewController: navigationController)
254 | popover.presentPopoverFromRect(valueView.valueButton.frame, inView: view, permittedArrowDirections: .Down, animated: true)
255 | self.currencyPopover = popover
256 | return
257 | }
258 |
259 | self.navigationController?.pushViewController(viewController, animated: true)
260 | }
261 |
262 | func toggleControls() {
263 | if editing {
264 | setEditing(false, animated: true)
265 | return
266 | }
267 |
268 | setControlsHidden(!controlsHidden, animated: true)
269 | }
270 |
271 | func startEditing() {
272 | setEditing(true, animated: true)
273 | }
274 |
275 |
276 | // MARK: - Private
277 |
278 | private func setupViewConstraints() {
279 | doneButtonTopConstraint = NSLayoutConstraint(item: doneButton, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: 0)
280 | doneButtonTopConstraint.priority = LayoutPriorityRequired
281 | updateDoneButtonTopLayoutConstraint()
282 |
283 | textFieldTopConstraint = NSLayoutConstraint(item: textField, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)
284 | textFieldTopConstraint.priority = LayoutPriorityRequired
285 |
286 | let views = [
287 | "scrollView": scrollView,
288 | "backgroundView": backgroundView,
289 | "valueView": valueView,
290 | "updateButton": updateButton,
291 | "textField": textField,
292 | "doneButton": doneButton
293 | ]
294 |
295 | view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|[scrollView]|", options: nil, metrics: nil, views: views))
296 | view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: nil, metrics: nil, views: views))
297 |
298 | var attributes: [NSLayoutAttribute] = [.Top, .Left, .Bottom, .Right]
299 | for attribute in attributes {
300 | view.addConstraint(NSLayoutConstraint(item: backgroundView, attribute: attribute, relatedBy: .Equal, toItem: view, attribute: attribute, multiplier: 1, constant: 0))
301 | view.addConstraint(NSLayoutConstraint(item: valueView, attribute: attribute, relatedBy: .Equal, toItem: view, attribute: attribute, multiplier: 1, constant: 0))
302 | }
303 |
304 | view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-[updateButton]-|", options: nil, metrics: nil, views: views))
305 | view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[updateButton]-10-|", options: nil, metrics: nil, views: views))
306 |
307 | let doneBottomConstraint = NSLayoutConstraint(item: doneButton, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: 0)
308 | doneBottomConstraint.priority = LayoutPriorityDefaultLow
309 | view.addConstraint(doneBottomConstraint)
310 |
311 | view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("[doneButton]-|", options: nil, metrics: nil, views: views))
312 |
313 | view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-(20@500)-[textField(<=500@600)]-(20@500)-|", options: nil, metrics: nil, views: views))
314 |
315 | let weakTextFieldTopConstraint = NSLayoutConstraint(item: textField, attribute: .Top, relatedBy: .Equal, toItem: valueView.valueButton, attribute: .Bottom, multiplier: 1, constant: 0)
316 | weakTextFieldTopConstraint.priority = LayoutPriorityDefaultLow
317 | view.addConstraint(weakTextFieldTopConstraint)
318 |
319 | view.addConstraint(NSLayoutConstraint(item: textField, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0))
320 |
321 | let requiredTextFieldTopConstraint = NSLayoutConstraint(item: textField, attribute: .Top, relatedBy: .GreaterThanOrEqual, toItem: doneButton, attribute: .Bottom, multiplier: 1, constant: 20)
322 | requiredTextFieldTopConstraint.priority = LayoutPriorityRequired
323 | view.addConstraint(requiredTextFieldTopConstraint)
324 | }
325 |
326 | func textFieldDidChange(notification: NSNotification?) {
327 | var string = textField.text ?? ""
328 | string = string.stringByReplacingOccurrencesOfString(",", withString: ".")
329 |
330 | let preferences = BTCPreferences.sharedPreferences()
331 | preferences.setObject(strtod(string, nil), forKey: kBTCNumberOfCoinsKey)
332 | preferences.synchronize()
333 |
334 | update()
335 | }
336 |
337 | func update() {
338 | if CoinsKit.isPad {
339 | currencyPopover?.dismissPopoverAnimated(true)
340 | }
341 |
342 | if let conversionRates = BTCConversionProvider.sharedProvider().latestConversionRates() {
343 | updateButton.date = conversionRates["updatedAt"] as? NSDate
344 | valueView.conversionRates = conversionRates
345 | }
346 |
347 | if !textField.editing {
348 | let number = BTCPreferences.sharedPreferences().objectForKey(kBTCNumberOfCoinsKey).description
349 | textField.text = number == "0" ? nil : number
350 | }
351 | }
352 |
353 | func preferencesDidChange() {
354 | UIApplication.sharedApplication().idleTimerDisabled = NSUserDefaults.standardUserDefaults().boolForKey(kBTCDisableSleepKey)
355 | updateTimerPaused()
356 | }
357 |
358 | private func setControlsHidden(controlsHidden: Bool, animated: Bool) {
359 | let application = UIApplication.sharedApplication()
360 | let statusBarAnimation: UIStatusBarAnimation = animated ? .Fade : .None
361 |
362 | if self.controlsHidden == controlsHidden {
363 | if application.statusBarHidden != controlsHidden {
364 | application.setStatusBarHidden(controlsHidden, withAnimation: statusBarAnimation)
365 | }
366 | return
367 | }
368 |
369 | self.controlsHidden = controlsHidden
370 |
371 | application.setStatusBarHidden(controlsHidden, withAnimation: statusBarAnimation)
372 | updateDoneButtonTopLayoutConstraint()
373 |
374 | let userDefaults = NSUserDefaults.standardUserDefaults()
375 | userDefaults.setBool(controlsHidden, forKey: kBTCControlsHiddenKey)
376 | userDefaults.synchronize()
377 |
378 | let animations: () -> Void = {
379 | self.updateButton.alpha = controlsHidden ? 0 : 1
380 | self.view.layoutIfNeeded()
381 | }
382 |
383 | if animated {
384 | UIView.animateWithDuration(0.6, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .AllowUserInteraction, animations: animations, completion: nil)
385 | } else {
386 | animations()
387 | }
388 | }
389 |
390 | func updateTimerPaused() {
391 | let isActive = UIApplication.sharedApplication().applicationState == .Active
392 | autoRefreshing = isActive && NSUserDefaults.standardUserDefaults().boolForKey(kBTCAutomaticallyRefreshKey)
393 | }
394 |
395 | func keyboardWillChangeFrame(notification: NSNotification?) {
396 | if let value = notification?.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
397 | keyboardFrame = value.CGRectValue()
398 | textFieldTopConstraint.constant = min(keyboardFrame.size.height, keyboardFrame.size.width) / -2.0
399 | }
400 | }
401 |
402 | private func updateDoneButtonTopLayoutConstraint() {
403 | var constant: CGFloat = 10.0
404 |
405 | if !controlsHidden {
406 | constant += 20.0
407 | }
408 |
409 | if CoinsKit.isPad || UIInterfaceOrientationIsPortrait(self.interfaceOrientation) {
410 | constant += 6.0
411 | }
412 |
413 | doneButtonTopConstraint.constant = constant
414 | }
415 |
416 |
417 | // MARK: - UITextFieldDelegate
418 |
419 | func textFieldShouldReturn(textField: UITextField) -> Bool {
420 | toggleControls()
421 | return false
422 | }
423 |
424 | func textFieldDidEndEditing(textField: UITextField) {
425 | if editing {
426 | setEditing(false, animated: true)
427 | }
428 | }
429 |
430 |
431 | // MARK: - SSPullToRefreshViewDelegate
432 |
433 | func pullToRefreshViewDidStartLoading(view: SSPullToRefreshView!) {
434 | refresh()
435 | }
436 |
437 | func pullToRefreshViewShouldStartLoading(view: SSPullToRefreshView!) -> Bool {
438 | return !loading && !editing
439 | }
440 | }
441 |
--------------------------------------------------------------------------------
/Coins.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 21104E5C1A253C67009B0D3C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21104E5B1A253C67009B0D3C /* AppDelegate.swift */; };
11 | 21104E641A2541F6009B0D3C /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21104E631A2541F6009B0D3C /* TableViewCell.swift */; };
12 | 21104E661A25441B009B0D3C /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21104E651A25441B009B0D3C /* TextField.swift */; };
13 | 2130E1691864AD58006D3470 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2130E1681864AD58006D3470 /* Foundation.framework */; };
14 | 2130E16B1864AD58006D3470 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2130E16A1864AD58006D3470 /* CoreGraphics.framework */; };
15 | 2130E16D1864AD58006D3470 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2130E16C1864AD58006D3470 /* UIKit.framework */; };
16 | 21363FF519C9434A0073FA6C /* BTCTodayValueView.m in Sources */ = {isa = PBXBuildFile; fileRef = 21363FF419C9434A0073FA6C /* BTCTodayValueView.m */; };
17 | 213D0A721A25FF0500FA254B /* CoinsKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 213D0A5B1A25FF0500FA254B /* CoinsKit.framework */; };
18 | 213D0A741A25FF0500FA254B /* CoinsKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 213D0A5B1A25FF0500FA254B /* CoinsKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
19 | 213D0A7C1A25FF4E00FA254B /* BTCConversionProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 21C103F119C921DD00CC5F36 /* BTCConversionProvider.m */; };
20 | 213D0A7D1A25FF4E00FA254B /* BTCValueView.m in Sources */ = {isa = PBXBuildFile; fileRef = 21C14D2519C91BBB0011C908 /* BTCValueView.m */; };
21 | 213D0A7E1A25FF4E00FA254B /* BTCDefines.m in Sources */ = {isa = PBXBuildFile; fileRef = 21C103ED19C91EE700CC5F36 /* BTCDefines.m */; };
22 | 213D0A801A25FF4E00FA254B /* NSUserDefaults+Coins.m in Sources */ = {isa = PBXBuildFile; fileRef = 21C103E919C91E4000CC5F36 /* NSUserDefaults+Coins.m */; };
23 | 213D0A811A25FF4E00FA254B /* BTCPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 21363FF719C955170073FA6C /* BTCPreferences.m */; };
24 | 213D0A821A25FF5800FA254B /* CoinsKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 21C14D2C19C91BCA0011C908 /* CoinsKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25 | 213D0A831A25FF5800FA254B /* BTCConversionProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 21C103F019C921DD00CC5F36 /* BTCConversionProvider.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | 213D0A841A25FF5800FA254B /* BTCValueView.h in Headers */ = {isa = PBXBuildFile; fileRef = 21C14D2419C91BBB0011C908 /* BTCValueView.h */; settings = {ATTRIBUTES = (Public, ); }; };
27 | 213D0A851A25FF5800FA254B /* BTCDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 21C103EC19C91EE700CC5F36 /* BTCDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
28 | 213D0A871A25FF5800FA254B /* NSUserDefaults+Coins.h in Headers */ = {isa = PBXBuildFile; fileRef = 21C103E819C91E4000CC5F36 /* NSUserDefaults+Coins.h */; settings = {ATTRIBUTES = (Public, ); }; };
29 | 213D0A881A25FF5800FA254B /* BTCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 21363FF619C955170073FA6C /* BTCPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; };
30 | 213D0A891A25FF5D00FA254B /* CoinsKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21104E601A253E3F009B0D3C /* CoinsKit.swift */; };
31 | 213D0A8A1A25FFFD00FA254B /* CoinsKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 213D0A5B1A25FF0500FA254B /* CoinsKit.framework */; };
32 | 21900F5E1A254DE300C0CA2C /* TickingButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21900F5D1A254DE300C0CA2C /* TickingButton.swift */; };
33 | 21900F601A25506C00C0CA2C /* NSDate+Coins.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21900F5F1A25506C00C0CA2C /* NSDate+Coins.swift */; };
34 | 21C14CEF19C910F80011C908 /* CurrencyPickerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C14CCE19C910F80011C908 /* CurrencyPickerTableViewController.swift */; };
35 | 21C14CF419C910F80011C908 /* ValueViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C14CD819C910F80011C908 /* ValueViewController.swift */; };
36 | 21C14CFB19C910F80011C908 /* currencies.json in Resources */ = {isa = PBXBuildFile; fileRef = 21C14CE519C910F80011C908 /* currencies.json */; };
37 | 21C14CFC19C910F80011C908 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 21C14CE619C910F80011C908 /* Localizable.strings */; };
38 | 21C14CFD19C910F80011C908 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 21C14CE819C910F80011C908 /* Images.xcassets */; };
39 | 21C14CFE19C910F80011C908 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 21C14CE919C910F80011C908 /* Settings.bundle */; };
40 | 21C14D0919C91A370011C908 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21C14D0819C91A370011C908 /* NotificationCenter.framework */; };
41 | 21C14D1419C91A370011C908 /* Coins Today.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 21C14D0719C91A370011C908 /* Coins Today.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
42 | 21C14D2019C91B9F0011C908 /* BTCTodayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 21C14D1D19C91B9F0011C908 /* BTCTodayViewController.m */; };
43 | 21FD2C4C1A26085700F8615D /* PullToRefreshView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD2C4B1A26085700F8615D /* PullToRefreshView.swift */; };
44 | 21FD42651A26B12500772B53 /* GradientView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21FD42621A26B11500772B53 /* GradientView.framework */; };
45 | 21FD42661A26B12E00772B53 /* GradientView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 21FD42621A26B11500772B53 /* GradientView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
46 | 32A93DCF17EE721A2B4BF684 /* libPods-Coins.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 421E383A04144C6A8624166B /* libPods-Coins.a */; };
47 | /* End PBXBuildFile section */
48 |
49 | /* Begin PBXContainerItemProxy section */
50 | 213D0A701A25FF0500FA254B /* PBXContainerItemProxy */ = {
51 | isa = PBXContainerItemProxy;
52 | containerPortal = 2130E15D1864AD57006D3470 /* Project object */;
53 | proxyType = 1;
54 | remoteGlobalIDString = 213D0A5A1A25FF0500FA254B;
55 | remoteInfo = CoinsKit;
56 | };
57 | 213D0A8B1A26000200FA254B /* PBXContainerItemProxy */ = {
58 | isa = PBXContainerItemProxy;
59 | containerPortal = 2130E15D1864AD57006D3470 /* Project object */;
60 | proxyType = 1;
61 | remoteGlobalIDString = 213D0A5A1A25FF0500FA254B;
62 | remoteInfo = CoinsKit;
63 | };
64 | 21C14D1219C91A370011C908 /* PBXContainerItemProxy */ = {
65 | isa = PBXContainerItemProxy;
66 | containerPortal = 2130E15D1864AD57006D3470 /* Project object */;
67 | proxyType = 1;
68 | remoteGlobalIDString = 21C14D0619C91A370011C908;
69 | remoteInfo = "Coins Today";
70 | };
71 | 21C14D1519C91A370011C908 /* PBXContainerItemProxy */ = {
72 | isa = PBXContainerItemProxy;
73 | containerPortal = 2130E15D1864AD57006D3470 /* Project object */;
74 | proxyType = 1;
75 | remoteGlobalIDString = 21C14D0619C91A370011C908;
76 | remoteInfo = "Coins Today";
77 | };
78 | 21FD425F1A26B11500772B53 /* PBXContainerItemProxy */ = {
79 | isa = PBXContainerItemProxy;
80 | containerPortal = 21FD425A1A26B11400772B53 /* Gradient View.xcodeproj */;
81 | proxyType = 2;
82 | remoteGlobalIDString = 2163B9F61A25FBF000610B0C;
83 | remoteInfo = Example;
84 | };
85 | 21FD42611A26B11500772B53 /* PBXContainerItemProxy */ = {
86 | isa = PBXContainerItemProxy;
87 | containerPortal = 21FD425A1A26B11400772B53 /* Gradient View.xcodeproj */;
88 | proxyType = 2;
89 | remoteGlobalIDString = 2163BA201A25FBFD00610B0C;
90 | remoteInfo = GradientView;
91 | };
92 | 21FD42631A26B11F00772B53 /* PBXContainerItemProxy */ = {
93 | isa = PBXContainerItemProxy;
94 | containerPortal = 21FD425A1A26B11400772B53 /* Gradient View.xcodeproj */;
95 | proxyType = 1;
96 | remoteGlobalIDString = 2163BA1F1A25FBFD00610B0C;
97 | remoteInfo = GradientView;
98 | };
99 | /* End PBXContainerItemProxy section */
100 |
101 | /* Begin PBXCopyFilesBuildPhase section */
102 | 213D0A731A25FF0500FA254B /* Embed Frameworks */ = {
103 | isa = PBXCopyFilesBuildPhase;
104 | buildActionMask = 2147483647;
105 | dstPath = "";
106 | dstSubfolderSpec = 10;
107 | files = (
108 | 21FD42661A26B12E00772B53 /* GradientView.framework in Embed Frameworks */,
109 | 213D0A741A25FF0500FA254B /* CoinsKit.framework in Embed Frameworks */,
110 | );
111 | name = "Embed Frameworks";
112 | runOnlyForDeploymentPostprocessing = 0;
113 | };
114 | 21C14D1A19C91A370011C908 /* Embed App Extensions */ = {
115 | isa = PBXCopyFilesBuildPhase;
116 | buildActionMask = 2147483647;
117 | dstPath = "";
118 | dstSubfolderSpec = 13;
119 | files = (
120 | 21C14D1419C91A370011C908 /* Coins Today.appex in Embed App Extensions */,
121 | );
122 | name = "Embed App Extensions";
123 | runOnlyForDeploymentPostprocessing = 0;
124 | };
125 | /* End PBXCopyFilesBuildPhase section */
126 |
127 | /* Begin PBXFileReference section */
128 | 21104E5B1A253C67009B0D3C /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
129 | 21104E5D1A253D3C009B0D3C /* Coins-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Coins-Bridging-Header.h"; sourceTree = ""; };
130 | 21104E601A253E3F009B0D3C /* CoinsKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinsKit.swift; sourceTree = ""; };
131 | 21104E631A2541F6009B0D3C /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; };
132 | 21104E651A25441B009B0D3C /* TextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; };
133 | 2130E1651864AD58006D3470 /* Coins.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Coins.app; sourceTree = BUILT_PRODUCTS_DIR; };
134 | 2130E1681864AD58006D3470 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
135 | 2130E16A1864AD58006D3470 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
136 | 2130E16C1864AD58006D3470 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
137 | 2130E1811864AD58006D3470 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
138 | 21363FF319C9434A0073FA6C /* BTCTodayValueView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTCTodayValueView.h; sourceTree = ""; };
139 | 21363FF419C9434A0073FA6C /* BTCTodayValueView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTCTodayValueView.m; sourceTree = ""; };
140 | 21363FF619C955170073FA6C /* BTCPreferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTCPreferences.h; sourceTree = ""; };
141 | 21363FF719C955170073FA6C /* BTCPreferences.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTCPreferences.m; sourceTree = ""; };
142 | 213D0A5B1A25FF0500FA254B /* CoinsKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoinsKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
143 | 213D0A5E1A25FF0500FA254B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
144 | 21900F5D1A254DE300C0CA2C /* TickingButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TickingButton.swift; sourceTree = ""; };
145 | 21900F5F1A25506C00C0CA2C /* NSDate+Coins.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Coins.swift"; sourceTree = ""; };
146 | 21B148BA19C92DB200972BEF /* Coins.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Coins.entitlements; sourceTree = ""; };
147 | 21B148BB19C92DB900972BEF /* Coins Today.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Coins Today.entitlements"; sourceTree = ""; };
148 | 21C103E819C91E4000CC5F36 /* NSUserDefaults+Coins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+Coins.h"; sourceTree = ""; };
149 | 21C103E919C91E4000CC5F36 /* NSUserDefaults+Coins.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+Coins.m"; sourceTree = ""; };
150 | 21C103EC19C91EE700CC5F36 /* BTCDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTCDefines.h; sourceTree = ""; };
151 | 21C103ED19C91EE700CC5F36 /* BTCDefines.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTCDefines.m; sourceTree = ""; };
152 | 21C103F019C921DD00CC5F36 /* BTCConversionProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTCConversionProvider.h; sourceTree = ""; };
153 | 21C103F119C921DD00CC5F36 /* BTCConversionProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTCConversionProvider.m; sourceTree = ""; };
154 | 21C14CCE19C910F80011C908 /* CurrencyPickerTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyPickerTableViewController.swift; sourceTree = ""; };
155 | 21C14CD819C910F80011C908 /* ValueViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValueViewController.swift; sourceTree = ""; };
156 | 21C14CE319C910F80011C908 /* Coins-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Coins-Info.plist"; sourceTree = ""; };
157 | 21C14CE519C910F80011C908 /* currencies.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = currencies.json; sourceTree = ""; };
158 | 21C14CE719C910F80011C908 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
159 | 21C14CE819C910F80011C908 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
160 | 21C14CE919C910F80011C908 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; };
161 | 21C14D0719C91A370011C908 /* Coins Today.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Coins Today.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
162 | 21C14D0819C91A370011C908 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; };
163 | 21C14D1C19C91B9F0011C908 /* BTCTodayViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTCTodayViewController.h; sourceTree = ""; };
164 | 21C14D1D19C91B9F0011C908 /* BTCTodayViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTCTodayViewController.m; sourceTree = ""; };
165 | 21C14D1F19C91B9F0011C908 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
166 | 21C14D2419C91BBB0011C908 /* BTCValueView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTCValueView.h; sourceTree = ""; };
167 | 21C14D2519C91BBB0011C908 /* BTCValueView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTCValueView.m; sourceTree = ""; };
168 | 21C14D2C19C91BCA0011C908 /* CoinsKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoinsKit.h; sourceTree = ""; };
169 | 21FD2C4B1A26085700F8615D /* PullToRefreshView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PullToRefreshView.swift; sourceTree = ""; };
170 | 21FD425A1A26B11400772B53 /* Gradient View.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Gradient View.xcodeproj"; path = "Carthage.checkout/GradientView/Gradient View.xcodeproj"; sourceTree = SOURCE_ROOT; };
171 | 421E383A04144C6A8624166B /* libPods-Coins.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Coins.a"; sourceTree = BUILT_PRODUCTS_DIR; };
172 | 7C733206B69A4AA88CE1C3A3 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
173 | C1BD2968FA93A53EDFA565AD /* Pods-Coins.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coins.release.xcconfig"; path = "Pods/Target Support Files/Pods-Coins/Pods-Coins.release.xcconfig"; sourceTree = ""; };
174 | DD6A6B0D5AE336003EBD8FCE /* Pods-Coins.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coins.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Coins/Pods-Coins.debug.xcconfig"; sourceTree = ""; };
175 | E7F6998536F74DFE984E7C8A /* libPods-Coins Today.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Coins Today.a"; sourceTree = BUILT_PRODUCTS_DIR; };
176 | /* End PBXFileReference section */
177 |
178 | /* Begin PBXFrameworksBuildPhase section */
179 | 2130E1621864AD58006D3470 /* Frameworks */ = {
180 | isa = PBXFrameworksBuildPhase;
181 | buildActionMask = 2147483647;
182 | files = (
183 | 21FD42651A26B12500772B53 /* GradientView.framework in Frameworks */,
184 | 2130E16B1864AD58006D3470 /* CoreGraphics.framework in Frameworks */,
185 | 2130E16D1864AD58006D3470 /* UIKit.framework in Frameworks */,
186 | 213D0A721A25FF0500FA254B /* CoinsKit.framework in Frameworks */,
187 | 2130E1691864AD58006D3470 /* Foundation.framework in Frameworks */,
188 | 32A93DCF17EE721A2B4BF684 /* libPods-Coins.a in Frameworks */,
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | };
192 | 213D0A571A25FF0500FA254B /* Frameworks */ = {
193 | isa = PBXFrameworksBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | );
197 | runOnlyForDeploymentPostprocessing = 0;
198 | };
199 | 21C14D0419C91A370011C908 /* Frameworks */ = {
200 | isa = PBXFrameworksBuildPhase;
201 | buildActionMask = 2147483647;
202 | files = (
203 | 213D0A8A1A25FFFD00FA254B /* CoinsKit.framework in Frameworks */,
204 | 21C14D0919C91A370011C908 /* NotificationCenter.framework in Frameworks */,
205 | );
206 | runOnlyForDeploymentPostprocessing = 0;
207 | };
208 | /* End PBXFrameworksBuildPhase section */
209 |
210 | /* Begin PBXGroup section */
211 | 2130E15C1864AD57006D3470 = {
212 | isa = PBXGroup;
213 | children = (
214 | 21C14CC719C910F80011C908 /* Coins */,
215 | 21C14D0A19C91A370011C908 /* Coins Today */,
216 | 21C14D2219C91BBB0011C908 /* CoinsKit */,
217 | 21F9D1971876952A00F36678 /* Vendor */,
218 | 2130E1671864AD58006D3470 /* Frameworks */,
219 | 2130E1661864AD58006D3470 /* Products */,
220 | 9625555A56EE5EEE4742E258 /* Pods */,
221 | );
222 | sourceTree = "";
223 | };
224 | 2130E1661864AD58006D3470 /* Products */ = {
225 | isa = PBXGroup;
226 | children = (
227 | 2130E1651864AD58006D3470 /* Coins.app */,
228 | 21C14D0719C91A370011C908 /* Coins Today.appex */,
229 | 213D0A5B1A25FF0500FA254B /* CoinsKit.framework */,
230 | );
231 | name = Products;
232 | sourceTree = "";
233 | };
234 | 2130E1671864AD58006D3470 /* Frameworks */ = {
235 | isa = PBXGroup;
236 | children = (
237 | 2130E1681864AD58006D3470 /* Foundation.framework */,
238 | 2130E16A1864AD58006D3470 /* CoreGraphics.framework */,
239 | 2130E16C1864AD58006D3470 /* UIKit.framework */,
240 | 2130E1811864AD58006D3470 /* XCTest.framework */,
241 | 7C733206B69A4AA88CE1C3A3 /* libPods.a */,
242 | 21C14D0819C91A370011C908 /* NotificationCenter.framework */,
243 | 421E383A04144C6A8624166B /* libPods-Coins.a */,
244 | E7F6998536F74DFE984E7C8A /* libPods-Coins Today.a */,
245 | );
246 | name = Frameworks;
247 | sourceTree = "";
248 | };
249 | 213D0A5D1A25FF0500FA254B /* Supporting Files */ = {
250 | isa = PBXGroup;
251 | children = (
252 | 213D0A5E1A25FF0500FA254B /* Info.plist */,
253 | );
254 | name = "Supporting Files";
255 | sourceTree = "";
256 | };
257 | 21C14CC719C910F80011C908 /* Coins */ = {
258 | isa = PBXGroup;
259 | children = (
260 | 21C14CC819C910F80011C908 /* Classes */,
261 | 21C14CDD19C910F80011C908 /* Other Sources */,
262 | 21C14CE219C910F80011C908 /* Resources */,
263 | );
264 | path = Coins;
265 | sourceTree = "";
266 | };
267 | 21C14CC819C910F80011C908 /* Classes */ = {
268 | isa = PBXGroup;
269 | children = (
270 | 21FD2C4D1A2619E100F8615D /* Application */,
271 | 21FD2C4E1A2619E900F8615D /* View Controllers */,
272 | 21FD2C4F1A2619F400F8615D /* Views */,
273 | 21FD2C501A2619F700F8615D /* Extensions */,
274 | );
275 | path = Classes;
276 | sourceTree = "";
277 | };
278 | 21C14CDD19C910F80011C908 /* Other Sources */ = {
279 | isa = PBXGroup;
280 | children = (
281 | 21104E5D1A253D3C009B0D3C /* Coins-Bridging-Header.h */,
282 | );
283 | path = "Other Sources";
284 | sourceTree = "";
285 | };
286 | 21C14CE219C910F80011C908 /* Resources */ = {
287 | isa = PBXGroup;
288 | children = (
289 | 21B148BA19C92DB200972BEF /* Coins.entitlements */,
290 | 21C14CE319C910F80011C908 /* Coins-Info.plist */,
291 | 21C14CE519C910F80011C908 /* currencies.json */,
292 | 21C14CE619C910F80011C908 /* Localizable.strings */,
293 | 21C14CE819C910F80011C908 /* Images.xcassets */,
294 | 21C14CE919C910F80011C908 /* Settings.bundle */,
295 | );
296 | path = Resources;
297 | sourceTree = "";
298 | };
299 | 21C14D0A19C91A370011C908 /* Coins Today */ = {
300 | isa = PBXGroup;
301 | children = (
302 | 21C14D1B19C91B9F0011C908 /* Classes */,
303 | 21C14D1E19C91B9F0011C908 /* Resources */,
304 | );
305 | path = "Coins Today";
306 | sourceTree = "";
307 | };
308 | 21C14D1B19C91B9F0011C908 /* Classes */ = {
309 | isa = PBXGroup;
310 | children = (
311 | 21C14D1C19C91B9F0011C908 /* BTCTodayViewController.h */,
312 | 21C14D1D19C91B9F0011C908 /* BTCTodayViewController.m */,
313 | 21363FF319C9434A0073FA6C /* BTCTodayValueView.h */,
314 | 21363FF419C9434A0073FA6C /* BTCTodayValueView.m */,
315 | );
316 | path = Classes;
317 | sourceTree = "";
318 | };
319 | 21C14D1E19C91B9F0011C908 /* Resources */ = {
320 | isa = PBXGroup;
321 | children = (
322 | 21B148BB19C92DB900972BEF /* Coins Today.entitlements */,
323 | 21C14D1F19C91B9F0011C908 /* Info.plist */,
324 | );
325 | path = Resources;
326 | sourceTree = "";
327 | };
328 | 21C14D2219C91BBB0011C908 /* CoinsKit */ = {
329 | isa = PBXGroup;
330 | children = (
331 | 21104E601A253E3F009B0D3C /* CoinsKit.swift */,
332 | 21C14D2319C91BBB0011C908 /* Classes */,
333 | 213D0A5D1A25FF0500FA254B /* Supporting Files */,
334 | );
335 | path = CoinsKit;
336 | sourceTree = "";
337 | };
338 | 21C14D2319C91BBB0011C908 /* Classes */ = {
339 | isa = PBXGroup;
340 | children = (
341 | 21C14D2C19C91BCA0011C908 /* CoinsKit.h */,
342 | 21C103F019C921DD00CC5F36 /* BTCConversionProvider.h */,
343 | 21C103F119C921DD00CC5F36 /* BTCConversionProvider.m */,
344 | 21C14D2419C91BBB0011C908 /* BTCValueView.h */,
345 | 21C14D2519C91BBB0011C908 /* BTCValueView.m */,
346 | 21C103EC19C91EE700CC5F36 /* BTCDefines.h */,
347 | 21C103ED19C91EE700CC5F36 /* BTCDefines.m */,
348 | 21C103E819C91E4000CC5F36 /* NSUserDefaults+Coins.h */,
349 | 21C103E919C91E4000CC5F36 /* NSUserDefaults+Coins.m */,
350 | 21363FF619C955170073FA6C /* BTCPreferences.h */,
351 | 21363FF719C955170073FA6C /* BTCPreferences.m */,
352 | );
353 | path = Classes;
354 | sourceTree = "";
355 | };
356 | 21F9D1971876952A00F36678 /* Vendor */ = {
357 | isa = PBXGroup;
358 | children = (
359 | 21FD425A1A26B11400772B53 /* Gradient View.xcodeproj */,
360 | );
361 | path = Vendor;
362 | sourceTree = "";
363 | };
364 | 21FD2C4D1A2619E100F8615D /* Application */ = {
365 | isa = PBXGroup;
366 | children = (
367 | 21104E5B1A253C67009B0D3C /* AppDelegate.swift */,
368 | );
369 | name = Application;
370 | sourceTree = "";
371 | };
372 | 21FD2C4E1A2619E900F8615D /* View Controllers */ = {
373 | isa = PBXGroup;
374 | children = (
375 | 21C14CD819C910F80011C908 /* ValueViewController.swift */,
376 | 21C14CCE19C910F80011C908 /* CurrencyPickerTableViewController.swift */,
377 | );
378 | name = "View Controllers";
379 | sourceTree = "";
380 | };
381 | 21FD2C4F1A2619F400F8615D /* Views */ = {
382 | isa = PBXGroup;
383 | children = (
384 | 21900F5D1A254DE300C0CA2C /* TickingButton.swift */,
385 | 21104E651A25441B009B0D3C /* TextField.swift */,
386 | 21104E631A2541F6009B0D3C /* TableViewCell.swift */,
387 | 21FD2C4B1A26085700F8615D /* PullToRefreshView.swift */,
388 | );
389 | name = Views;
390 | sourceTree = "";
391 | };
392 | 21FD2C501A2619F700F8615D /* Extensions */ = {
393 | isa = PBXGroup;
394 | children = (
395 | 21900F5F1A25506C00C0CA2C /* NSDate+Coins.swift */,
396 | );
397 | name = Extensions;
398 | sourceTree = "";
399 | };
400 | 21FD425B1A26B11400772B53 /* Products */ = {
401 | isa = PBXGroup;
402 | children = (
403 | 21FD42601A26B11500772B53 /* Example.app */,
404 | 21FD42621A26B11500772B53 /* GradientView.framework */,
405 | );
406 | name = Products;
407 | sourceTree = "";
408 | };
409 | 9625555A56EE5EEE4742E258 /* Pods */ = {
410 | isa = PBXGroup;
411 | children = (
412 | DD6A6B0D5AE336003EBD8FCE /* Pods-Coins.debug.xcconfig */,
413 | C1BD2968FA93A53EDFA565AD /* Pods-Coins.release.xcconfig */,
414 | );
415 | name = Pods;
416 | sourceTree = "";
417 | };
418 | /* End PBXGroup section */
419 |
420 | /* Begin PBXHeadersBuildPhase section */
421 | 213D0A581A25FF0500FA254B /* Headers */ = {
422 | isa = PBXHeadersBuildPhase;
423 | buildActionMask = 2147483647;
424 | files = (
425 | 213D0A871A25FF5800FA254B /* NSUserDefaults+Coins.h in Headers */,
426 | 213D0A821A25FF5800FA254B /* CoinsKit.h in Headers */,
427 | 213D0A851A25FF5800FA254B /* BTCDefines.h in Headers */,
428 | 213D0A831A25FF5800FA254B /* BTCConversionProvider.h in Headers */,
429 | 213D0A881A25FF5800FA254B /* BTCPreferences.h in Headers */,
430 | 213D0A841A25FF5800FA254B /* BTCValueView.h in Headers */,
431 | );
432 | runOnlyForDeploymentPostprocessing = 0;
433 | };
434 | /* End PBXHeadersBuildPhase section */
435 |
436 | /* Begin PBXNativeTarget section */
437 | 2130E1641864AD58006D3470 /* Coins */ = {
438 | isa = PBXNativeTarget;
439 | buildConfigurationList = 2130E1911864AD58006D3470 /* Build configuration list for PBXNativeTarget "Coins" */;
440 | buildPhases = (
441 | A6D58084BA76E5D8F77E64E1 /* Check Pods Manifest.lock */,
442 | 2130E1611864AD58006D3470 /* Sources */,
443 | 2130E1621864AD58006D3470 /* Frameworks */,
444 | 2130E1631864AD58006D3470 /* Resources */,
445 | 21C14D0219C9196B0011C908 /* Hockey */,
446 | 21C14D1A19C91A370011C908 /* Embed App Extensions */,
447 | 0B7B534546DA5F32F0701796 /* Copy Pods Resources */,
448 | 213D0A731A25FF0500FA254B /* Embed Frameworks */,
449 | );
450 | buildRules = (
451 | );
452 | dependencies = (
453 | 21FD42641A26B11F00772B53 /* PBXTargetDependency */,
454 | 21C14D1319C91A370011C908 /* PBXTargetDependency */,
455 | 21C14D1619C91A370011C908 /* PBXTargetDependency */,
456 | 213D0A711A25FF0500FA254B /* PBXTargetDependency */,
457 | );
458 | name = Coins;
459 | productName = Coins;
460 | productReference = 2130E1651864AD58006D3470 /* Coins.app */;
461 | productType = "com.apple.product-type.application";
462 | };
463 | 213D0A5A1A25FF0500FA254B /* CoinsKit */ = {
464 | isa = PBXNativeTarget;
465 | buildConfigurationList = 213D0A751A25FF0500FA254B /* Build configuration list for PBXNativeTarget "CoinsKit" */;
466 | buildPhases = (
467 | 213D0A561A25FF0500FA254B /* Sources */,
468 | 213D0A571A25FF0500FA254B /* Frameworks */,
469 | 213D0A581A25FF0500FA254B /* Headers */,
470 | 213D0A591A25FF0500FA254B /* Resources */,
471 | );
472 | buildRules = (
473 | );
474 | dependencies = (
475 | );
476 | name = CoinsKit;
477 | productName = CoinsKit;
478 | productReference = 213D0A5B1A25FF0500FA254B /* CoinsKit.framework */;
479 | productType = "com.apple.product-type.framework";
480 | };
481 | 21C14D0619C91A370011C908 /* Coins Today */ = {
482 | isa = PBXNativeTarget;
483 | buildConfigurationList = 21C14D1719C91A370011C908 /* Build configuration list for PBXNativeTarget "Coins Today" */;
484 | buildPhases = (
485 | 21C14D0319C91A370011C908 /* Sources */,
486 | 21C14D0419C91A370011C908 /* Frameworks */,
487 | 21C14D0519C91A370011C908 /* Resources */,
488 | );
489 | buildRules = (
490 | );
491 | dependencies = (
492 | 213D0A8C1A26000200FA254B /* PBXTargetDependency */,
493 | );
494 | name = "Coins Today";
495 | productName = "Coins Today";
496 | productReference = 21C14D0719C91A370011C908 /* Coins Today.appex */;
497 | productType = "com.apple.product-type.app-extension";
498 | };
499 | /* End PBXNativeTarget section */
500 |
501 | /* Begin PBXProject section */
502 | 2130E15D1864AD57006D3470 /* Project object */ = {
503 | isa = PBXProject;
504 | attributes = {
505 | CLASSPREFIX = BTC;
506 | LastUpgradeCheck = 0510;
507 | ORGANIZATIONNAME = "Nothing Magical, Inc.";
508 | TargetAttributes = {
509 | 2130E1641864AD58006D3470 = {
510 | DevelopmentTeam = UP9C8XM22A;
511 | SystemCapabilities = {
512 | com.apple.ApplicationGroups.iOS = {
513 | enabled = 1;
514 | };
515 | com.apple.BackgroundModes = {
516 | enabled = 1;
517 | };
518 | com.apple.iCloud = {
519 | enabled = 1;
520 | };
521 | };
522 | };
523 | 213D0A5A1A25FF0500FA254B = {
524 | CreatedOnToolsVersion = 6.2;
525 | DevelopmentTeam = UP9C8XM22A;
526 | };
527 | 21C14D0619C91A370011C908 = {
528 | CreatedOnToolsVersion = 6.0;
529 | DevelopmentTeam = UP9C8XM22A;
530 | SystemCapabilities = {
531 | com.apple.ApplicationGroups.iOS = {
532 | enabled = 1;
533 | };
534 | com.apple.iCloud = {
535 | enabled = 1;
536 | };
537 | };
538 | };
539 | };
540 | };
541 | buildConfigurationList = 2130E1601864AD57006D3470 /* Build configuration list for PBXProject "Coins" */;
542 | compatibilityVersion = "Xcode 3.2";
543 | developmentRegion = English;
544 | hasScannedForEncodings = 0;
545 | knownRegions = (
546 | en,
547 | );
548 | mainGroup = 2130E15C1864AD57006D3470;
549 | productRefGroup = 2130E1661864AD58006D3470 /* Products */;
550 | projectDirPath = "";
551 | projectReferences = (
552 | {
553 | ProductGroup = 21FD425B1A26B11400772B53 /* Products */;
554 | ProjectRef = 21FD425A1A26B11400772B53 /* Gradient View.xcodeproj */;
555 | },
556 | );
557 | projectRoot = "";
558 | targets = (
559 | 2130E1641864AD58006D3470 /* Coins */,
560 | 21C14D0619C91A370011C908 /* Coins Today */,
561 | 213D0A5A1A25FF0500FA254B /* CoinsKit */,
562 | );
563 | };
564 | /* End PBXProject section */
565 |
566 | /* Begin PBXReferenceProxy section */
567 | 21FD42601A26B11500772B53 /* Example.app */ = {
568 | isa = PBXReferenceProxy;
569 | fileType = wrapper.application;
570 | path = Example.app;
571 | remoteRef = 21FD425F1A26B11500772B53 /* PBXContainerItemProxy */;
572 | sourceTree = BUILT_PRODUCTS_DIR;
573 | };
574 | 21FD42621A26B11500772B53 /* GradientView.framework */ = {
575 | isa = PBXReferenceProxy;
576 | fileType = wrapper.framework;
577 | path = GradientView.framework;
578 | remoteRef = 21FD42611A26B11500772B53 /* PBXContainerItemProxy */;
579 | sourceTree = BUILT_PRODUCTS_DIR;
580 | };
581 | /* End PBXReferenceProxy section */
582 |
583 | /* Begin PBXResourcesBuildPhase section */
584 | 2130E1631864AD58006D3470 /* Resources */ = {
585 | isa = PBXResourcesBuildPhase;
586 | buildActionMask = 2147483647;
587 | files = (
588 | 21C14CFD19C910F80011C908 /* Images.xcassets in Resources */,
589 | 21C14CFC19C910F80011C908 /* Localizable.strings in Resources */,
590 | 21C14CFE19C910F80011C908 /* Settings.bundle in Resources */,
591 | 21C14CFB19C910F80011C908 /* currencies.json in Resources */,
592 | );
593 | runOnlyForDeploymentPostprocessing = 0;
594 | };
595 | 213D0A591A25FF0500FA254B /* Resources */ = {
596 | isa = PBXResourcesBuildPhase;
597 | buildActionMask = 2147483647;
598 | files = (
599 | );
600 | runOnlyForDeploymentPostprocessing = 0;
601 | };
602 | 21C14D0519C91A370011C908 /* Resources */ = {
603 | isa = PBXResourcesBuildPhase;
604 | buildActionMask = 2147483647;
605 | files = (
606 | );
607 | runOnlyForDeploymentPostprocessing = 0;
608 | };
609 | /* End PBXResourcesBuildPhase section */
610 |
611 | /* Begin PBXShellScriptBuildPhase section */
612 | 0B7B534546DA5F32F0701796 /* Copy Pods Resources */ = {
613 | isa = PBXShellScriptBuildPhase;
614 | buildActionMask = 2147483647;
615 | files = (
616 | );
617 | inputPaths = (
618 | );
619 | name = "Copy Pods Resources";
620 | outputPaths = (
621 | );
622 | runOnlyForDeploymentPostprocessing = 0;
623 | shellPath = /bin/sh;
624 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Coins/Pods-Coins-resources.sh\"\n";
625 | showEnvVarsInLog = 0;
626 | };
627 | 21C14D0219C9196B0011C908 /* Hockey */ = {
628 | isa = PBXShellScriptBuildPhase;
629 | buildActionMask = 2147483647;
630 | files = (
631 | );
632 | inputPaths = (
633 | );
634 | name = Hockey;
635 | outputPaths = (
636 | );
637 | runOnlyForDeploymentPostprocessing = 0;
638 | shellPath = /bin/sh;
639 | shellScript = "FILE=\"${SRCROOT}/Vendor/HockeySDK-iOS/BuildAgent\"\nif [ -f \"$FILE\" ]; then\n\"$FILE\"\nfi";
640 | };
641 | A6D58084BA76E5D8F77E64E1 /* Check Pods Manifest.lock */ = {
642 | isa = PBXShellScriptBuildPhase;
643 | buildActionMask = 2147483647;
644 | files = (
645 | );
646 | inputPaths = (
647 | );
648 | name = "Check Pods Manifest.lock";
649 | outputPaths = (
650 | );
651 | runOnlyForDeploymentPostprocessing = 0;
652 | shellPath = /bin/sh;
653 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
654 | showEnvVarsInLog = 0;
655 | };
656 | /* End PBXShellScriptBuildPhase section */
657 |
658 | /* Begin PBXSourcesBuildPhase section */
659 | 2130E1611864AD58006D3470 /* Sources */ = {
660 | isa = PBXSourcesBuildPhase;
661 | buildActionMask = 2147483647;
662 | files = (
663 | 21104E641A2541F6009B0D3C /* TableViewCell.swift in Sources */,
664 | 21900F5E1A254DE300C0CA2C /* TickingButton.swift in Sources */,
665 | 21900F601A25506C00C0CA2C /* NSDate+Coins.swift in Sources */,
666 | 21104E661A25441B009B0D3C /* TextField.swift in Sources */,
667 | 21104E5C1A253C67009B0D3C /* AppDelegate.swift in Sources */,
668 | 21FD2C4C1A26085700F8615D /* PullToRefreshView.swift in Sources */,
669 | 21C14CF419C910F80011C908 /* ValueViewController.swift in Sources */,
670 | 21C14CEF19C910F80011C908 /* CurrencyPickerTableViewController.swift in Sources */,
671 | );
672 | runOnlyForDeploymentPostprocessing = 0;
673 | };
674 | 213D0A561A25FF0500FA254B /* Sources */ = {
675 | isa = PBXSourcesBuildPhase;
676 | buildActionMask = 2147483647;
677 | files = (
678 | 213D0A7D1A25FF4E00FA254B /* BTCValueView.m in Sources */,
679 | 213D0A891A25FF5D00FA254B /* CoinsKit.swift in Sources */,
680 | 213D0A7C1A25FF4E00FA254B /* BTCConversionProvider.m in Sources */,
681 | 213D0A7E1A25FF4E00FA254B /* BTCDefines.m in Sources */,
682 | 213D0A811A25FF4E00FA254B /* BTCPreferences.m in Sources */,
683 | 213D0A801A25FF4E00FA254B /* NSUserDefaults+Coins.m in Sources */,
684 | );
685 | runOnlyForDeploymentPostprocessing = 0;
686 | };
687 | 21C14D0319C91A370011C908 /* Sources */ = {
688 | isa = PBXSourcesBuildPhase;
689 | buildActionMask = 2147483647;
690 | files = (
691 | 21363FF519C9434A0073FA6C /* BTCTodayValueView.m in Sources */,
692 | 21C14D2019C91B9F0011C908 /* BTCTodayViewController.m in Sources */,
693 | );
694 | runOnlyForDeploymentPostprocessing = 0;
695 | };
696 | /* End PBXSourcesBuildPhase section */
697 |
698 | /* Begin PBXTargetDependency section */
699 | 213D0A711A25FF0500FA254B /* PBXTargetDependency */ = {
700 | isa = PBXTargetDependency;
701 | target = 213D0A5A1A25FF0500FA254B /* CoinsKit */;
702 | targetProxy = 213D0A701A25FF0500FA254B /* PBXContainerItemProxy */;
703 | };
704 | 213D0A8C1A26000200FA254B /* PBXTargetDependency */ = {
705 | isa = PBXTargetDependency;
706 | target = 213D0A5A1A25FF0500FA254B /* CoinsKit */;
707 | targetProxy = 213D0A8B1A26000200FA254B /* PBXContainerItemProxy */;
708 | };
709 | 21C14D1319C91A370011C908 /* PBXTargetDependency */ = {
710 | isa = PBXTargetDependency;
711 | target = 21C14D0619C91A370011C908 /* Coins Today */;
712 | targetProxy = 21C14D1219C91A370011C908 /* PBXContainerItemProxy */;
713 | };
714 | 21C14D1619C91A370011C908 /* PBXTargetDependency */ = {
715 | isa = PBXTargetDependency;
716 | target = 21C14D0619C91A370011C908 /* Coins Today */;
717 | targetProxy = 21C14D1519C91A370011C908 /* PBXContainerItemProxy */;
718 | };
719 | 21FD42641A26B11F00772B53 /* PBXTargetDependency */ = {
720 | isa = PBXTargetDependency;
721 | name = GradientView;
722 | targetProxy = 21FD42631A26B11F00772B53 /* PBXContainerItemProxy */;
723 | };
724 | /* End PBXTargetDependency section */
725 |
726 | /* Begin PBXVariantGroup section */
727 | 21C14CE619C910F80011C908 /* Localizable.strings */ = {
728 | isa = PBXVariantGroup;
729 | children = (
730 | 21C14CE719C910F80011C908 /* en */,
731 | );
732 | name = Localizable.strings;
733 | sourceTree = "";
734 | };
735 | /* End PBXVariantGroup section */
736 |
737 | /* Begin XCBuildConfiguration section */
738 | 2130E18F1864AD58006D3470 /* Debug */ = {
739 | isa = XCBuildConfiguration;
740 | buildSettings = {
741 | ALWAYS_SEARCH_USER_PATHS = NO;
742 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
743 | CLANG_CXX_LIBRARY = "libc++";
744 | CLANG_ENABLE_MODULES = YES;
745 | CLANG_ENABLE_OBJC_ARC = YES;
746 | CLANG_WARN_BOOL_CONVERSION = YES;
747 | CLANG_WARN_CONSTANT_CONVERSION = YES;
748 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
749 | CLANG_WARN_EMPTY_BODY = YES;
750 | CLANG_WARN_ENUM_CONVERSION = YES;
751 | CLANG_WARN_INT_CONVERSION = YES;
752 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
753 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
754 | COPY_PHASE_STRIP = NO;
755 | GCC_C_LANGUAGE_STANDARD = gnu99;
756 | GCC_DYNAMIC_NO_PIC = NO;
757 | GCC_OPTIMIZATION_LEVEL = 0;
758 | GCC_PREPROCESSOR_DEFINITIONS = (
759 | "DEBUG=1",
760 | "$(inherited)",
761 | );
762 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
763 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
764 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
765 | GCC_WARN_UNDECLARED_SELECTOR = YES;
766 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
767 | GCC_WARN_UNUSED_FUNCTION = YES;
768 | GCC_WARN_UNUSED_VARIABLE = YES;
769 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
770 | ONLY_ACTIVE_ARCH = YES;
771 | SDKROOT = iphoneos;
772 | TARGETED_DEVICE_FAMILY = "1,2";
773 | WARNING_CFLAGS = "-Weverything";
774 | };
775 | name = Debug;
776 | };
777 | 2130E1901864AD58006D3470 /* Release */ = {
778 | isa = XCBuildConfiguration;
779 | buildSettings = {
780 | ALWAYS_SEARCH_USER_PATHS = NO;
781 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
782 | CLANG_CXX_LIBRARY = "libc++";
783 | CLANG_ENABLE_MODULES = YES;
784 | CLANG_ENABLE_OBJC_ARC = YES;
785 | CLANG_WARN_BOOL_CONVERSION = YES;
786 | CLANG_WARN_CONSTANT_CONVERSION = YES;
787 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
788 | CLANG_WARN_EMPTY_BODY = YES;
789 | CLANG_WARN_ENUM_CONVERSION = YES;
790 | CLANG_WARN_INT_CONVERSION = YES;
791 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
792 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
793 | COPY_PHASE_STRIP = YES;
794 | ENABLE_NS_ASSERTIONS = NO;
795 | GCC_C_LANGUAGE_STANDARD = gnu99;
796 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
797 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
798 | GCC_WARN_UNDECLARED_SELECTOR = YES;
799 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
800 | GCC_WARN_UNUSED_FUNCTION = YES;
801 | GCC_WARN_UNUSED_VARIABLE = YES;
802 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
803 | SDKROOT = iphoneos;
804 | TARGETED_DEVICE_FAMILY = "1,2";
805 | VALIDATE_PRODUCT = YES;
806 | WARNING_CFLAGS = "-Weverything";
807 | };
808 | name = Release;
809 | };
810 | 2130E1921864AD58006D3470 /* Debug */ = {
811 | isa = XCBuildConfiguration;
812 | baseConfigurationReference = DD6A6B0D5AE336003EBD8FCE /* Pods-Coins.debug.xcconfig */;
813 | buildSettings = {
814 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
815 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
816 | CLANG_ENABLE_MODULES = YES;
817 | CODE_SIGN_ENTITLEMENTS = Coins/Resources/Coins.entitlements;
818 | CODE_SIGN_IDENTITY = "iPhone Developer";
819 | FRAMEWORK_SEARCH_PATHS = (
820 | "$(inherited)",
821 | "$(PROJECT_DIR)",
822 | "$(PROJECT_DIR)/Vendor",
823 | "$(PROJECT_DIR)/Carthage.build/iOS",
824 | );
825 | INFOPLIST_FILE = "$(SRCROOT)/Coins/Resources/Coins-Info.plist";
826 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
827 | LIBRARY_SEARCH_PATHS = "$(inherited)";
828 | OTHER_SWIFT_FLAGS = "-DDEBUG=1";
829 | PRODUCT_NAME = "$(TARGET_NAME)";
830 | SWIFT_OBJC_BRIDGING_HEADER = "Coins/Other Sources/Coins-Bridging-Header.h";
831 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
832 | WRAPPER_EXTENSION = app;
833 | };
834 | name = Debug;
835 | };
836 | 2130E1931864AD58006D3470 /* Release */ = {
837 | isa = XCBuildConfiguration;
838 | baseConfigurationReference = C1BD2968FA93A53EDFA565AD /* Pods-Coins.release.xcconfig */;
839 | buildSettings = {
840 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
841 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
842 | CLANG_ENABLE_MODULES = YES;
843 | CODE_SIGN_ENTITLEMENTS = Coins/Resources/Coins.entitlements;
844 | CODE_SIGN_IDENTITY = "iPhone Developer";
845 | FRAMEWORK_SEARCH_PATHS = (
846 | "$(inherited)",
847 | "$(PROJECT_DIR)",
848 | "$(PROJECT_DIR)/Vendor",
849 | "$(PROJECT_DIR)/Carthage.build/iOS",
850 | );
851 | INFOPLIST_FILE = "$(SRCROOT)/Coins/Resources/Coins-Info.plist";
852 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
853 | LIBRARY_SEARCH_PATHS = "$(inherited)";
854 | PRODUCT_NAME = "$(TARGET_NAME)";
855 | SWIFT_OBJC_BRIDGING_HEADER = "Coins/Other Sources/Coins-Bridging-Header.h";
856 | WRAPPER_EXTENSION = app;
857 | };
858 | name = Release;
859 | };
860 | 213D0A761A25FF0500FA254B /* Debug */ = {
861 | isa = XCBuildConfiguration;
862 | buildSettings = {
863 | APPLICATION_EXTENSION_API_ONLY = YES;
864 | CLANG_WARN_UNREACHABLE_CODE = YES;
865 | CODE_SIGN_IDENTITY = "iPhone Developer";
866 | CURRENT_PROJECT_VERSION = 1;
867 | DEFINES_MODULE = YES;
868 | DYLIB_COMPATIBILITY_VERSION = 1;
869 | DYLIB_CURRENT_VERSION = 1;
870 | DYLIB_INSTALL_NAME_BASE = "@rpath";
871 | ENABLE_STRICT_OBJC_MSGSEND = YES;
872 | GCC_PREPROCESSOR_DEFINITIONS = (
873 | "DEBUG=1",
874 | "$(inherited)",
875 | );
876 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
877 | INFOPLIST_FILE = CoinsKit/Info.plist;
878 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
879 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
880 | MTL_ENABLE_DEBUG_INFO = YES;
881 | PRODUCT_NAME = "$(TARGET_NAME)";
882 | SKIP_INSTALL = YES;
883 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
884 | VERSIONING_SYSTEM = "apple-generic";
885 | VERSION_INFO_PREFIX = "";
886 | WARNING_CFLAGS = (
887 | "-Weverything",
888 | "-Wno-missing-variable-declarations",
889 | );
890 | };
891 | name = Debug;
892 | };
893 | 213D0A771A25FF0500FA254B /* Release */ = {
894 | isa = XCBuildConfiguration;
895 | buildSettings = {
896 | APPLICATION_EXTENSION_API_ONLY = YES;
897 | CLANG_WARN_UNREACHABLE_CODE = YES;
898 | CODE_SIGN_IDENTITY = "iPhone Distribution";
899 | CURRENT_PROJECT_VERSION = 1;
900 | DEFINES_MODULE = YES;
901 | DYLIB_COMPATIBILITY_VERSION = 1;
902 | DYLIB_CURRENT_VERSION = 1;
903 | DYLIB_INSTALL_NAME_BASE = "@rpath";
904 | ENABLE_STRICT_OBJC_MSGSEND = YES;
905 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
906 | INFOPLIST_FILE = CoinsKit/Info.plist;
907 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
908 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
909 | MTL_ENABLE_DEBUG_INFO = NO;
910 | PRODUCT_NAME = "$(TARGET_NAME)";
911 | SKIP_INSTALL = YES;
912 | VERSIONING_SYSTEM = "apple-generic";
913 | VERSION_INFO_PREFIX = "";
914 | WARNING_CFLAGS = (
915 | "-Weverything",
916 | "-Wno-missing-variable-declarations",
917 | );
918 | };
919 | name = Release;
920 | };
921 | 21C14D1819C91A370011C908 /* Debug */ = {
922 | isa = XCBuildConfiguration;
923 | buildSettings = {
924 | CLANG_WARN_UNREACHABLE_CODE = YES;
925 | CODE_SIGN_ENTITLEMENTS = "Coins Today/Resources/Coins Today.entitlements";
926 | CODE_SIGN_IDENTITY = "iPhone Developer";
927 | ENABLE_STRICT_OBJC_MSGSEND = YES;
928 | GCC_PREPROCESSOR_DEFINITIONS = (
929 | "DEBUG=1",
930 | "$(inherited)",
931 | );
932 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
933 | INFOPLIST_FILE = "$(SRCROOT)/Coins Today/Resources/Info.plist";
934 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
935 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
936 | MTL_ENABLE_DEBUG_INFO = YES;
937 | PRODUCT_NAME = "$(TARGET_NAME)";
938 | SKIP_INSTALL = YES;
939 | };
940 | name = Debug;
941 | };
942 | 21C14D1919C91A370011C908 /* Release */ = {
943 | isa = XCBuildConfiguration;
944 | buildSettings = {
945 | CLANG_WARN_UNREACHABLE_CODE = YES;
946 | CODE_SIGN_ENTITLEMENTS = "Coins Today/Resources/Coins Today.entitlements";
947 | CODE_SIGN_IDENTITY = "iPhone Developer";
948 | ENABLE_STRICT_OBJC_MSGSEND = YES;
949 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
950 | INFOPLIST_FILE = "$(SRCROOT)/Coins Today/Resources/Info.plist";
951 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
952 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
953 | MTL_ENABLE_DEBUG_INFO = NO;
954 | PRODUCT_NAME = "$(TARGET_NAME)";
955 | SKIP_INSTALL = YES;
956 | };
957 | name = Release;
958 | };
959 | /* End XCBuildConfiguration section */
960 |
961 | /* Begin XCConfigurationList section */
962 | 2130E1601864AD57006D3470 /* Build configuration list for PBXProject "Coins" */ = {
963 | isa = XCConfigurationList;
964 | buildConfigurations = (
965 | 2130E18F1864AD58006D3470 /* Debug */,
966 | 2130E1901864AD58006D3470 /* Release */,
967 | );
968 | defaultConfigurationIsVisible = 0;
969 | defaultConfigurationName = Release;
970 | };
971 | 2130E1911864AD58006D3470 /* Build configuration list for PBXNativeTarget "Coins" */ = {
972 | isa = XCConfigurationList;
973 | buildConfigurations = (
974 | 2130E1921864AD58006D3470 /* Debug */,
975 | 2130E1931864AD58006D3470 /* Release */,
976 | );
977 | defaultConfigurationIsVisible = 0;
978 | defaultConfigurationName = Release;
979 | };
980 | 213D0A751A25FF0500FA254B /* Build configuration list for PBXNativeTarget "CoinsKit" */ = {
981 | isa = XCConfigurationList;
982 | buildConfigurations = (
983 | 213D0A761A25FF0500FA254B /* Debug */,
984 | 213D0A771A25FF0500FA254B /* Release */,
985 | );
986 | defaultConfigurationIsVisible = 0;
987 | defaultConfigurationName = Release;
988 | };
989 | 21C14D1719C91A370011C908 /* Build configuration list for PBXNativeTarget "Coins Today" */ = {
990 | isa = XCConfigurationList;
991 | buildConfigurations = (
992 | 21C14D1819C91A370011C908 /* Debug */,
993 | 21C14D1919C91A370011C908 /* Release */,
994 | );
995 | defaultConfigurationIsVisible = 0;
996 | defaultConfigurationName = Release;
997 | };
998 | /* End XCConfigurationList section */
999 | };
1000 | rootObject = 2130E15D1864AD57006D3470 /* Project object */;
1001 | }
1002 |
--------------------------------------------------------------------------------