├── .github
└── images
│ ├── preview.jpg
│ └── preview2.jpg
├── Supporting Files
├── Assets.xcassets
│ ├── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── AppIcon-16.0x16.0@1x.png
│ │ ├── AppIcon-16.0x16.0@2x.png
│ │ ├── AppIcon-32.0x32.0@1x.png
│ │ ├── AppIcon-32.0x32.0@2x.png
│ │ ├── AppIcon-128.0x128.0@1x.png
│ │ ├── AppIcon-128.0x128.0@2x.png
│ │ ├── AppIcon-256.0x256.0@1x.png
│ │ ├── AppIcon-256.0x256.0@2x.png
│ │ ├── AppIcon-512.0x512.0@1x.png
│ │ ├── AppIcon-512.0x512.0@2x.png
│ │ └── Contents.json
│ └── AccentColor.colorset
│ │ └── Contents.json
├── upbitBar.entitlements
├── ko.lproj
│ ├── Localizable.strings
│ └── Main.strings
├── en.lproj
│ └── Localizable.strings
├── Info.plist
└── Base.lproj
│ └── Main.storyboard
├── upbitBar.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── sung.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── xcuserdata
│ ├── sung.xcuserdatad
│ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ └── fernando.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── project.pbxproj
├── Sources
├── Utils
│ ├── Notifications.swift
│ ├── UserInfo.swift
│ ├── Attributes.swift
│ └── Localized.swift
├── Models
│ ├── Market.swift
│ ├── CryptoAsset.swift
│ ├── RefreshInterval.swift
│ ├── Ticker.swift
│ └── Cryptocurrency.swift
├── Constants
│ └── Constants.swift
├── Networking
│ ├── UPbitAPI.swift
│ └── UpbitServices.swift
├── SettingViewController.swift
└── AppDelegate.swift
├── LICENSE
├── README.md
└── .gitignore
/.github/images/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/.github/images/preview.jpg
--------------------------------------------------------------------------------
/.github/images/preview2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/.github/images/preview2.jpg
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-16.0x16.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-16.0x16.0@1x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-16.0x16.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-16.0x16.0@2x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-32.0x32.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-32.0x32.0@1x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-32.0x32.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-32.0x32.0@2x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-128.0x128.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-128.0x128.0@1x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-128.0x128.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-128.0x128.0@2x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-256.0x256.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-256.0x256.0@1x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-256.0x256.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-256.0x256.0@2x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-512.0x512.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-512.0x512.0@1x.png
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-512.0x512.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/Supporting Files/Assets.xcassets/AppIcon.appiconset/AppIcon-512.0x512.0@2x.png
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/project.xcworkspace/xcuserdata/sung.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinpark/upbitBar/HEAD/upbitBar.xcodeproj/project.xcworkspace/xcuserdata/sung.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Sources/Utils/Notifications.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Notifications.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/09.
6 | //
7 |
8 | import Foundation
9 |
10 | extension Notification.Name {
11 | static let neededTokenSetting = Notification.Name("neededTokenSetting")
12 | static let neededRefresh = Notification.Name("neededRefresh")
13 | }
14 |
--------------------------------------------------------------------------------
/Sources/Models/Market.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Market.swift
3 | // upbitBar
4 | //
5 | // Created by SUNG on 2021/03/18.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Market: Codable {
11 | let market, koreanName, englishName: String?
12 |
13 | enum CodingKeys: String, CodingKey {
14 | case market
15 | case koreanName = "korean_name"
16 | case englishName = "english_name"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Supporting Files/upbitBar.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 | com.apple.security.network.client
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Sources/Constants/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // upbitBar
4 | //
5 | // Created by SUNG on 2021/03/18.
6 | //
7 |
8 | import Foundation
9 |
10 | enum Constants: String{
11 | case bearer = "Bearer"
12 | case authorization = "Authorization"
13 | case notionURL = "https://www.notion.so/UpbitBar-6b9cc7ab41474a9eaa5e9c69addd59e3"
14 | }
15 |
16 | enum UpbitKey: String{
17 | case accessKey
18 | case secretKey
19 | case refreshInterval
20 | }
21 |
22 |
23 | enum ServicesKey: String{
24 | case accessKey = "access_key"
25 | case nonce
26 | case hs256 = "HS256"
27 | }
28 |
--------------------------------------------------------------------------------
/Sources/Models/CryptoAsset.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CryptoAsset.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/08.
6 | //
7 |
8 | import Foundation
9 |
10 | // MARK: - CryptoAsset
11 | struct CryptoAsset: Codable {
12 | let currency: String
13 | let balance: String
14 | let locked: String
15 | let avgBuyPrice: String
16 | let avgBuyPriceModified: Bool
17 | let unitCurrency: String
18 |
19 | enum CodingKeys: String, CodingKey {
20 | case currency = "currency"
21 | case balance = "balance"
22 | case locked = "locked"
23 | case avgBuyPrice = "avg_buy_price"
24 | case avgBuyPriceModified = "avg_buy_price_modified"
25 | case unitCurrency = "unit_currency"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Supporting Files/ko.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | upbitBar
4 |
5 | Created by Fernando on 2021/03/09.
6 |
7 | */
8 | "app_refresh" = "♻️ 새로고침";
9 | "app_setting" = "⚙️ 설정";
10 | "app_quit" = "🚪 종료";
11 |
12 | "setting_title" = "🎉 upbitBar 설정하기";
13 | "setting_auto_launch" = "재시작시 자동 실행";
14 | "access_token_title" = "Access key";
15 | "secret_token_title" = "Secret key";
16 | "refresh_time_title" = "갱신주기";
17 | "setting_quit" = "닫기";
18 | "setting_help_feedback" = "도움말 보기";
19 | "setting_save" = "저장";
20 | "setting_alert_title" = "알림";
21 | "setting_alert_accesstoken_info" = "Access Token 값이 올바르지 않습니다 다시한번 확인해주세요 ";
22 | "setting_alert_refreshtoken_info" = "Refresh Token 값이 올바르지 않습니다 다시한번 확인해주세요 ";
23 | "ok" = "확인";
24 | "one_minutes" = "1분";
25 | "five_minutes" = "5분";
26 | "ten_minutes" = "10분";
27 | "fifteen_minutes" = "15분";
28 |
--------------------------------------------------------------------------------
/Supporting Files/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | upbitBar
4 |
5 | Created by Fernando on 2021/03/09.
6 |
7 | */
8 |
9 | "app_refresh" = "♻️ Refresh";
10 | "app_setting" = "⚙️ Preferences";
11 | "app_quit" = "🚪 Quit";
12 |
13 | "setting_title" = "Wellcome to upbitBar";
14 | "setting_auto_launch" = "Automatically start at Login";
15 | "access_token_title" = "Access key";
16 | "secret_token_title" = "Secret key";
17 | "refresh_time_title" = "Refresh Time";
18 | "setting_quit" = "Quit";
19 | "setting_help_feedback" = "Help & Feedback";
20 | "setting_save" = "Save";
21 | "setting_alert_title" = "Warning";
22 | "setting_alert_accesstoken_info" = "Warning";
23 | "setting_alert_refreshtoken_info" = "";
24 | "ok" = "Okay";
25 | "one_minutes" = "1 Minutes";
26 | "five_minutes" = "5 Minutes";
27 | "ten_minutes" = "10 Minutes";
28 | "fifteen_minutes" = "15 Minutes";
29 |
--------------------------------------------------------------------------------
/Sources/Utils/UserInfo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserInfo.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/09.
6 | //
7 |
8 | import Foundation
9 |
10 | @propertyWrapper
11 | struct UserInfo {
12 | private let key: String
13 | private let defaultValue: T
14 |
15 |
16 | var wrappedValue: T {
17 | get { return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue }
18 | set { UserDefaults.standard.set(newValue, forKey: key) }
19 | }
20 |
21 | init(key: String, defaultValue: T) {
22 | self.key = key
23 | self.defaultValue = defaultValue
24 | }
25 | }
26 |
27 | struct UPbitKeys {
28 | @UserInfo(key: UpbitKey.accessKey.rawValue, defaultValue: "") var accessToken: String
29 | @UserInfo(key: UpbitKey.secretKey.rawValue, defaultValue: "") var secretToken: String
30 | @UserInfo(key: UpbitKey.refreshInterval.rawValue, defaultValue: 1) var refershInterVal: Int
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/Models/RefreshInterval.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RefreshInterval.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/09.
6 | //
7 |
8 | import Foundation
9 |
10 | enum RefreshInterval: Int {
11 | case one = 0
12 | case five = 1
13 | case ten = 2
14 | case fifteen = 3
15 |
16 | var title: String {
17 | switch self {
18 | case .one: return NSLocalizedString("one_minutes", comment: "1 minutes")
19 | case .five: return NSLocalizedString("five_minutes", comment: "5 minutes")
20 | case .ten: return NSLocalizedString("ten_minutes", comment: "10 minutes")
21 | case .fifteen: return NSLocalizedString("fifteen_minutes", comment: "15 minutes")
22 | }
23 | }
24 |
25 | var minutes: Int {
26 | switch self {
27 | case .one: return 1
28 | case .five: return 5
29 | case .ten: return 10
30 | case .fifteen: return 15
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Sources/Utils/Attributes.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Attributes.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/10.
6 | //
7 |
8 | import Foundation
9 | import Cocoa
10 |
11 | enum Attributes {
12 |
13 | static var cryptoRedAttributes: [NSAttributedString.Key: Any] {
14 | return [.font : NSFont.systemFont(ofSize: 12.0, weight: .light),
15 | .foregroundColor : NSColor(red: 197/255.0, green: 39/255.0, blue: 68/255.0, alpha: 1)
16 | ]
17 | }
18 |
19 | static var cryptoBlueAttributes: [NSAttributedString.Key: Any] {
20 | return [.font : NSFont.systemFont(ofSize: 12.0, weight: .light),
21 | .foregroundColor : NSColor(red: 39/255.0, green: 139/255.0, blue: 197/255.0, alpha: 1)
22 | ]
23 | }
24 |
25 | static var cryptoNormalAttributes: [NSAttributedString.Key: Any] {
26 | return [.font : NSFont.systemFont(ofSize: 12.0, weight: .light),
27 | .foregroundColor : NSColor.white
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Sources/Networking/UPbitAPI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UPbitAPI.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/08.
6 | //
7 |
8 | import Foundation
9 |
10 | enum UpbitAPI {
11 |
12 | /// 나의 자산을 조회합니다
13 | case balances
14 |
15 | /// 현재가를 조회합니다
16 | case ticker
17 |
18 | /// 업비트에서 거래 가능한 목록을 조회합니다
19 | case market
20 | }
21 |
22 | extension UpbitAPI {
23 |
24 | /// baseURL 을 지정합니다
25 | var baseURL: String {
26 | return "https://api.upbit.com"
27 | }
28 |
29 | /// API Version
30 | var version: String {
31 | return "v1"
32 | }
33 |
34 | /// endpoint를 지정합니다
35 | var endPoint: String {
36 | switch self {
37 | case .balances:
38 | return "/\(version)/accounts/"
39 | case .ticker:
40 | return "/\(version)/ticker/"
41 | case .market:
42 | return "/\(version)/market/"
43 | }
44 | }
45 |
46 | var targetURL: String {
47 | return baseURL + endPoint
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Fernando
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Supporting Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.2
21 | CFBundleVersion
22 | 4
23 | LSApplicationCategoryType
24 | public.app-category.utilities
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | LSUIElement
28 |
29 | NSMainStoryboardFile
30 | Main
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/xcuserdata/sung.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | QuickStart (Playground) 1.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 6
13 |
14 | QuickStart (Playground) 2.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 7
20 |
21 | QuickStart (Playground).xcscheme
22 |
23 | isShown
24 |
25 | orderHint
26 | 5
27 |
28 | SnapKitPlayground (Playground) 1.xcscheme
29 |
30 | isShown
31 |
32 | orderHint
33 | 3
34 |
35 | SnapKitPlayground (Playground) 2.xcscheme
36 |
37 | isShown
38 |
39 | orderHint
40 | 4
41 |
42 | SnapKitPlayground (Playground).xcscheme
43 |
44 | isShown
45 |
46 | orderHint
47 | 2
48 |
49 | upbitBar.xcscheme_^#shared#^_
50 |
51 | orderHint
52 | 1
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "AppIcon-16.0x16.0@1x.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "AppIcon-16.0x16.0@2x.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "AppIcon-32.0x32.0@1x.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "AppIcon-32.0x32.0@2x.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "AppIcon-128.0x128.0@1x.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "AppIcon-128.0x128.0@2x.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "AppIcon-256.0x256.0@1x.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "AppIcon-256.0x256.0@2x.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "AppIcon-512.0x512.0@1x.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "AppIcon-512.0x512.0@2x.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Sources/Utils/Localized.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Localized.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/09.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Localized {
11 |
12 | static let refresh = NSLocalizedString("app_refresh", comment: "♻️ Refresh")
13 | static let setting = NSLocalizedString("app_setting", comment: "⚙️ Preferences")
14 | static let quit = NSLocalizedString("app_quit", comment: "🚪 Quit")
15 |
16 | /// SettingViewController
17 | static let settingTitle = NSLocalizedString("setting_title", comment: "Wellcome to upbitBar")
18 | static let autoLaunch = NSLocalizedString("setting_auto_launch", comment: "Automatically start at Login")
19 | static let accessToken = NSLocalizedString("access_token_title", comment: "Access Key")
20 | static let secretToken = NSLocalizedString("secret_token_title", comment: "Secret Key")
21 | static let refreshTime = NSLocalizedString("refresh_time_title", comment: "Refresh Time")
22 |
23 | static let settingQuit = NSLocalizedString("setting_quit", comment: "Quit")
24 | static let settingHelpFeedback = NSLocalizedString(("setting_help_feedback"), comment: "Help & Feedback")
25 | static let settingSave = NSLocalizedString("setting_save", comment: "Save")
26 |
27 | static let settingAlertTitle = NSLocalizedString("setting_alert_title", comment: "Warning")
28 | static let settingAlertAccessTokenInfoText = NSLocalizedString("setting_alert_accesstoken_info", comment: "")
29 | static let settingAlertRefreshTokenInfoText = NSLocalizedString("setting_alert_refreshtoken_info", comment: "")
30 | static let ok = NSLocalizedString("ok", comment: "ok")
31 |
32 | static let oneMinutes = NSLocalizedString("one_minutes", comment: "1 minutes")
33 | static let fiveMinutes = NSLocalizedString("five_minutes", comment: "5 minutes")
34 | static let tenMinutes = NSLocalizedString("ten_minutes", comment: "10 minutes")
35 | static let fifteenMinues = NSLocalizedString("fifteen_minutes", comment: "15 minutes")
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # upbitBar
2 |
3 |
4 | [](https://github.com/techinpark/jandi/blob/main/LICENSE)
5 | [](https://github.com/techinpark/jandi)
6 | [](https://developer.apple.com/swift/)
7 | 
8 |
9 |
10 | ## 소개 🔍
11 |
12 | - 업비트 지갑 매번 스마트폰으로 확인하지 마시고 상태바에서 손쉽게 확인해보세요 💰
13 | - Swift 5.0 으로 작성되었습니다.
14 |
15 | ## 미리보기 👀
16 |
17 | - 설정을 하게되면 상태바에서 업비트 지갑의 잔액을 실시간으로 보실 수 있습니다.
18 | - 미리보기로 제공된 이미지는 예시입니다
19 |
20 | 
21 |
22 |
23 | ## 요구 사항 🪄
24 |
25 | - `UpbitBar` 프로젝트는 Swift 5.0 으로 작성되었습니다.
26 | - macOS 10.15 버전 이상에서 동작합니다.
27 |
28 |
29 | ## 사용한 라이브러리 📦
30 |
31 | - [Just](https://github.com/dduan/Just)
32 | - [JWTComponents](https://github.com/couchdeveloper/JWTComponents)
33 | - [LaunchAtLogin](https://github.com/sindresorhus/LaunchAtLogin)
34 | - [SnapKit](https://github.com/SnapKit/SnapKit)
35 | - [Then](https://github.com/devxoul/Then)
36 |
37 | ## 설치하기 🎉
38 |
39 | ### AppStore
40 |
41 |
42 |
43 | ## 이 프로젝트가 유용하셨나요 ? ❤️
44 |
45 | 저의 프로젝트가 유용하셨다면 [stargazers](https://github.com/techinpark/Jandi/stargazers) 에 동참해주세요 ⭐
46 | [팔로우](https://github.com/techinpark) 해주신다면 새로운 프로젝트를 더 빠르게 만나보실 수 있습니다 🤩
47 |
48 | ## Author
49 | - [techinpark](https://twitter.com/techinpark)
50 |
51 | ## 기여하기 🌱
52 | 모든 형태의 기여를 기다리고 있습니다 오타 수정, 기능 추가, 기능제안 모두 두팔벌려 환영합니다 🥳
53 |
54 |
55 | ## License
56 | `UpbitBar` is available under the MIT license. See the LICENSE file for more info.
57 |
58 |
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "Just",
6 | "repositoryURL": "https://github.com/dduan/Just",
7 | "state": {
8 | "branch": null,
9 | "revision": "1824bf84cf52d11d69ae20cfb89f0ce5bffa5650",
10 | "version": "0.8.0"
11 | }
12 | },
13 | {
14 | "package": "JWTComponents",
15 | "repositoryURL": "https://github.com/couchdeveloper/JWTComponents",
16 | "state": {
17 | "branch": null,
18 | "revision": "ddf78f2213f74c82ad0acbe2e6b08c74908d9dc0",
19 | "version": "0.4.0"
20 | }
21 | },
22 | {
23 | "package": "LaunchAtLogin",
24 | "repositoryURL": "https://github.com/sindresorhus/LaunchAtLogin",
25 | "state": {
26 | "branch": null,
27 | "revision": "0f39982b9d6993eef253b81219d3c39ba1e680f3",
28 | "version": "4.0.0"
29 | }
30 | },
31 | {
32 | "package": "SnapKit",
33 | "repositoryURL": "https://github.com/SnapKit/SnapKit",
34 | "state": {
35 | "branch": null,
36 | "revision": "d458564516e5676af9c70b4f4b2a9178294f1bc6",
37 | "version": "5.0.1"
38 | }
39 | },
40 | {
41 | "package": "swift-crypto",
42 | "repositoryURL": "https://github.com/apple/swift-crypto.git",
43 | "state": {
44 | "branch": null,
45 | "revision": "0141f53dd525706c803b0c20aa8ad36f9ecd45e5",
46 | "version": "1.1.5"
47 | }
48 | },
49 | {
50 | "package": "swift-log",
51 | "repositoryURL": "https://github.com/apple/swift-log",
52 | "state": {
53 | "branch": null,
54 | "revision": "5d66f7ba25daf4f94100e7022febf3c75e37a6c7",
55 | "version": "1.4.2"
56 | }
57 | },
58 | {
59 | "package": "Then",
60 | "repositoryURL": "http://github.com/devxoul/then",
61 | "state": {
62 | "branch": null,
63 | "revision": "e421a7b3440a271834337694e6050133a3958bc7",
64 | "version": "2.7.0"
65 | }
66 | }
67 | ]
68 | },
69 | "version": 1
70 | }
71 |
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/xcuserdata/fernando.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | QuickStart (Playground) 1.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 2
13 |
14 | QuickStart (Playground) 2.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 3
20 |
21 | QuickStart (Playground) 3.xcscheme
22 |
23 | isShown
24 |
25 | orderHint
26 | 11
27 |
28 | QuickStart (Playground) 4.xcscheme
29 |
30 | isShown
31 |
32 | orderHint
33 | 12
34 |
35 | QuickStart (Playground) 5.xcscheme
36 |
37 | isShown
38 |
39 | orderHint
40 | 13
41 |
42 | QuickStart (Playground).xcscheme
43 |
44 | isShown
45 |
46 | orderHint
47 | 1
48 |
49 | SnapKitPlayground (Playground) 1.xcscheme
50 |
51 | isShown
52 |
53 | orderHint
54 | 5
55 |
56 | SnapKitPlayground (Playground) 2.xcscheme
57 |
58 | isShown
59 |
60 | orderHint
61 | 6
62 |
63 | SnapKitPlayground (Playground) 3.xcscheme
64 |
65 | isShown
66 |
67 | orderHint
68 | 8
69 |
70 | SnapKitPlayground (Playground) 4.xcscheme
71 |
72 | isShown
73 |
74 | orderHint
75 | 9
76 |
77 | SnapKitPlayground (Playground) 5.xcscheme
78 |
79 | isShown
80 |
81 | orderHint
82 | 10
83 |
84 | SnapKitPlayground (Playground).xcscheme
85 |
86 | isShown
87 |
88 | orderHint
89 | 4
90 |
91 | upbitBar.xcscheme_^#shared#^_
92 |
93 | orderHint
94 | 0
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/Sources/Models/Ticker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Ticker.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/08.
6 | //
7 |
8 | import Foundation
9 |
10 | // MARK: - Ticker
11 |
12 | /// Document URL
13 | /// https://docs.upbit.com/reference#ticker%ED%98%84%EC%9E%AC%EA%B0%80-%EB%82%B4%EC%97%AD
14 |
15 | struct Ticker: Codable {
16 |
17 | /// 종목구분코드
18 | let market: String
19 | /// 최근거래일자 (UTC)
20 | let tradeDate: String
21 | /// 최근 거래시각 (UTC)
22 | let tradeTime: String
23 | /// 최근 거래일자 (KST)
24 | let tradeDateKst: String
25 | /// 최근 거래시각 (KST)
26 | let tradeTimeKst: String
27 | /// 최근 거래시간 타임스탬프
28 | let tradeTimestamp: Double
29 | /// 시가
30 | let openingPrice: Double
31 | /// 고가
32 | let highPrice: Double
33 | /// 저가
34 | let lowPrice: Double
35 | /// 종가
36 | let tradePrice: Double
37 | /// 전일종가
38 | let prevClosingPrice: Double
39 | /// 변화 (EVENT: 보합, RISE: 상승, FALL: 하락)
40 | let change: String
41 | /// 변화액의 절대값
42 | let changePrice: Double
43 | /// 변화율의 절대값
44 | let changeRate: Double
45 | /// 부호가 있는 변화액
46 | let signedChangePrice: Double
47 | /// 부호가 있는 변화율
48 | let signedChangeRate: Double
49 | /// 가장최근 거래량
50 | let tradeVolume: Double
51 | /// 누적거래대금 (UTC 0시 기준)
52 | let accTradePrice: Double
53 | /// 24시간 누적 거래량
54 | let accTradePrice24H: Double
55 | /// 누적거래량 (UTC 0시 기준)
56 | let accTradeVolume: Double
57 | /// 24시간 누적 거래량
58 | let accTradeVolume24H: Double
59 | /// 52주 신고가
60 | let highest52_WeekPrice: Double
61 | /// 52주 신고가 달성일
62 | let highest52_WeekDate: String
63 | /// 52주 신저가
64 | let lowest52_WeekPrice: Double
65 | /// 52주 신저가 달성일
66 | let lowest52_WeekDate: String
67 | /// 타임스탬프
68 | let timestamp: UInt
69 |
70 | enum CodingKeys: String, CodingKey {
71 | case market = "market"
72 | case tradeDate = "trade_date"
73 | case tradeTime = "trade_time"
74 | case tradeDateKst = "trade_date_kst"
75 | case tradeTimeKst = "trade_time_kst"
76 | case tradeTimestamp = "trade_timestamp"
77 | case openingPrice = "opening_price"
78 | case highPrice = "high_price"
79 | case lowPrice = "low_price"
80 | case tradePrice = "trade_price"
81 | case prevClosingPrice = "prev_closing_price"
82 | case change = "change"
83 | case changePrice = "change_price"
84 | case changeRate = "change_rate"
85 | case signedChangePrice = "signed_change_price"
86 | case signedChangeRate = "signed_change_rate"
87 | case tradeVolume = "trade_volume"
88 | case accTradePrice = "acc_trade_price"
89 | case accTradePrice24H = "acc_trade_price_24h"
90 | case accTradeVolume = "acc_trade_volume"
91 | case accTradeVolume24H = "acc_trade_volume_24h"
92 | case highest52_WeekPrice = "highest_52_week_price"
93 | case highest52_WeekDate = "highest_52_week_date"
94 | case lowest52_WeekPrice = "lowest_52_week_price"
95 | case lowest52_WeekDate = "lowest_52_week_date"
96 | case timestamp = "timestamp"
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/swift,xcode,swiftpackagemanager
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=swift,xcode,swiftpackagemanager
4 |
5 | ### Swift ###
6 | # Xcode
7 | #
8 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
9 |
10 | ## User settings
11 | xcuserdata/
12 |
13 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
14 | *.xcscmblueprint
15 | *.xccheckout
16 |
17 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
18 | build/
19 | DerivedData/
20 | *.moved-aside
21 | *.pbxuser
22 | !default.pbxuser
23 | *.mode1v3
24 | !default.mode1v3
25 | *.mode2v3
26 | !default.mode2v3
27 | *.perspectivev3
28 | !default.perspectivev3
29 |
30 | ## Obj-C/Swift specific
31 | *.hmap
32 |
33 | ## App packaging
34 | *.ipa
35 | *.dSYM.zip
36 | *.dSYM
37 |
38 | ## Playgrounds
39 | timeline.xctimeline
40 | playground.xcworkspace
41 |
42 | # Swift Package Manager
43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
44 | # Packages/
45 | # Package.pins
46 | # Package.resolved
47 | # *.xcodeproj
48 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
49 | # hence it is not needed unless you have added a package configuration file to your project
50 | # .swiftpm
51 |
52 | .build/
53 |
54 | # CocoaPods
55 | # We recommend against adding the Pods directory to your .gitignore. However
56 | # you should judge for yourself, the pros and cons are mentioned at:
57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
58 | # Pods/
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
64 | # Carthage/Checkouts
65 |
66 | Carthage/Build/
67 |
68 | # Accio dependency management
69 | Dependencies/
70 | .accio/
71 |
72 | # fastlane
73 | # It is recommended to not store the screenshots in the git repo.
74 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
75 | # For more information about the recommended setup visit:
76 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
77 |
78 | fastlane/report.xml
79 | fastlane/Preview.html
80 | fastlane/screenshots/**/*.png
81 | fastlane/test_output
82 |
83 | # Code Injection
84 | # After new code Injection tools there's a generated folder /iOSInjectionProject
85 | # https://github.com/johnno1962/injectionforxcode
86 |
87 | iOSInjectionProject/
88 |
89 | ### SwiftPackageManager ###
90 | Packages
91 | xcuserdata
92 | *.xcodeproj
93 |
94 |
95 | ### Xcode ###
96 | # Xcode
97 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
98 |
99 |
100 |
101 |
102 | ## Gcc Patch
103 | /*.gcno
104 |
105 | ### Xcode Patch ###
106 | *.xcodeproj/*
107 | !*.xcodeproj/project.pbxproj
108 | !*.xcodeproj/xcshareddata/
109 | !*.xcworkspace/contents.xcworkspacedata
110 | **/xcshareddata/WorkspaceSettings.xcsettings
111 |
112 | # End of https://www.toptal.com/developers/gitignore/api/swift,xcode,swiftpackagemanager.DS_Store
113 | DerivedData
114 |
--------------------------------------------------------------------------------
/Sources/Networking/UpbitServices.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UpbitServices.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/08.
6 | //
7 |
8 | import Foundation
9 | import JWTComponents
10 | import Just
11 |
12 | /// MARK: UpbitServices
13 |
14 | class UpbitServices {
15 |
16 | static let shared = UpbitServices()
17 |
18 | private let keys = UPbitKeys()
19 |
20 | /// JWT 토큰을 생성합니다
21 | func generateJWTToken() -> String? {
22 |
23 | var jwtc = JWTComponents()
24 | guard let secretKey = keys.secretToken.data(using: .utf8) else { return nil }
25 | let accessToken: String = keys.accessToken
26 | let nonce: String = UUID().uuidString
27 |
28 | do {
29 | try jwtc.setValue(accessToken, forClaim: ServicesKey.accessKey.rawValue)
30 | try jwtc.setValue(nonce, forClaim: ServicesKey.nonce.rawValue)
31 | try jwtc.setValue(ServicesKey.hs256.rawValue, forHeaderParameter: .alg)
32 | try jwtc.sign(withKey: secretKey)
33 |
34 | guard let bearer = jwtc.jwt else { return nil }
35 | return "Bearer \(bearer)"
36 |
37 | } catch {
38 | return nil
39 | }
40 | }
41 |
42 | /// 나의 자산을 조회합니다
43 | func getBalances() -> [CryptoAsset]? {
44 | guard let bearerToken = generateJWTToken() else { return nil }
45 | let targetURL = UpbitAPI.balances.targetURL
46 | let headers: [String: String] = [Constants.authorization.rawValue: bearerToken]
47 | let response = Just.get(targetURL, headers: headers)
48 | guard let jsonData = response.content else { return nil }
49 |
50 | do {
51 | return try JSONDecoder().decode([CryptoAsset].self, from: jsonData)
52 | } catch {
53 | NotificationCenter.default.post(name: .neededTokenSetting, object: nil)
54 | print(error)
55 | return nil
56 | }
57 | }
58 |
59 | /// 현재가를 조회합니다
60 | func getTicker(markets: String) -> [Ticker]? {
61 | guard let bearerToken = generateJWTToken() else { return nil }
62 | let targetURL = "\(UpbitAPI.ticker.targetURL)?markets=\(markets)"
63 | print(targetURL)
64 |
65 | let headers: [String: String] = [Constants.authorization.rawValue: bearerToken]
66 | let response = Just.get(targetURL, headers: headers)
67 |
68 | guard let jsonData = response.content else { return nil }
69 | do {
70 | return try JSONDecoder().decode([Ticker].self, from: jsonData)
71 | } catch {
72 | print("error: \(error.localizedDescription)")
73 | print("response: \(String(describing: String(data: jsonData, encoding: .utf8)))")
74 | return nil
75 | }
76 | }
77 |
78 | // 업비트에서 거래 가능한 코인을 조회합니다
79 | func getAllMarket() -> [Market]?{
80 | let targetURL = "\(UpbitAPI.market.targetURL)all"
81 | let response = Just.get(targetURL)
82 |
83 | guard let jsonData = response.content else { return nil }
84 | do {
85 | return try JSONDecoder().decode([Market].self, from: jsonData)
86 | } catch {
87 | print("error: \(error.localizedDescription)")
88 | print("response: \(String(describing: String(data: jsonData, encoding: .utf8)))")
89 | return nil
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Sources/Models/Cryptocurrency.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Cryptocurrency.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/08.
6 | //
7 |
8 | import Foundation
9 |
10 | enum Cryptocurrency: String, Equatable {
11 |
12 | case BTC
13 | case ETH
14 | case XHR
15 | case XEM
16 | case EMC2
17 | case LBC
18 | case CHZ
19 | case BORA
20 | case PCI
21 | case ENJ
22 | case GRS
23 | case META
24 | case SRM
25 | case POWR
26 | case ONG
27 | case SAND
28 | case ADA
29 | case DOT
30 | case HUNT
31 | case CRO
32 | case DMT
33 | case UPP
34 | case EOS
35 | case ETC
36 | case ANKR
37 | case MANA
38 | case SXP
39 | case XLM
40 | case BCH
41 | case MLK
42 | case VET
43 | case GAS
44 | case OMG
45 | case STEEM
46 | case WAXP
47 | case BTT
48 | case DKA
49 | case NPXS
50 | case MTL
51 | case SOLVE
52 | case ICX
53 | case QTUM
54 | case BTG
55 | case MOC
56 | case CRE
57 | case TFUEL
58 | case TRX
59 | case HBAR
60 | case MFT
61 | case LTC
62 | case GLM
63 | case SSX
64 | case STRAX
65 | case XTZ
66 | case HIVE
67 | case TON
68 | case POLY
69 | case LINK
70 | case MVL
71 | case ONT
72 | case MED
73 | case BSV
74 | case SBD
75 | case QTCON
76 | case CVC
77 | case AQT
78 | case TT
79 | case IOST
80 | case PXL
81 | case CBK
82 | case DOGE
83 | case AHT
84 | case SNT
85 | case RFR
86 | case STPT
87 | case THETA
88 | case ZPX
89 | case BAT
90 | case ARK
91 | case ADX
92 | case AERGO
93 | case FCT2
94 | case NEO
95 | case MARO
96 | case STORJ
97 | case JST
98 | case SRN
99 | case ELF
100 | case MBL
101 | case HUM
102 | case LOOM
103 | case OBSR
104 | case ZIL
105 | case KAVA
106 | case ARDR
107 | case KMD
108 | case LAMB
109 | case TSHP
110 | case ATOM
111 | case STMX
112 | case LSK
113 | case BCHA
114 | case EDR
115 | case QKC
116 | case ORBS
117 | case SC
118 | case IGNIS
119 | case SPND
120 | case REP
121 | case IQ
122 | case WAVES
123 | case KNC
124 | case IOTA
125 |
126 | var name: String {
127 | switch self {
128 |
129 | case .BTC: return "비트코인"
130 | case .ETH: return "이더리움"
131 | case .XHR: return "리플"
132 | case .XEM: return "넴"
133 | case .EMC2: return "아인스타이늄"
134 | case .LBC: return "엘비와이크레딧"
135 | case .CHZ: return "칠리즈"
136 | case .BORA: return "보라"
137 | case .PCI: return "페이코인"
138 | case .ENJ: return "엔진코인"
139 | case .GRS: return "그로스톨코인"
140 | case .META: return "메타디움"
141 | case .SRM: return "세럼"
142 | case .POWR: return "파워렛저"
143 | case .ONG: return "온톨로지가스"
144 | case .SAND: return "샌드박스"
145 | case .ADA: return "에이다"
146 | case .DOT: return "폴카닷"
147 | case .HUNT: return "헌트"
148 | case .CRO: return ""
149 | case .DMT: return ""
150 | case .UPP: return ""
151 | case .EOS: return "이오스"
152 | case .ETC: return ""
153 | case .ANKR: return ""
154 | case .MANA: return ""
155 | case .SXP: return ""
156 | case .XLM: return ""
157 | case .BCH: return ""
158 | case .MLK: return ""
159 | case .VET: return ""
160 | case .GAS: return ""
161 | case .OMG: return ""
162 | case .STEEM: return ""
163 | case .WAXP: return ""
164 | case .BTT: return ""
165 | case .DKA: return ""
166 | case .NPXS: return ""
167 | case .MTL: return ""
168 | case .SOLVE: return ""
169 | case .ICX: return ""
170 | case .QTUM: return ""
171 | case .BTG: return ""
172 | case .MOC: return ""
173 | case .CRE: return ""
174 | case .TFUEL: return ""
175 | case .TRX: return ""
176 | case .HBAR: return ""
177 | case .MFT: return ""
178 | case .LTC: return ""
179 | case .GLM: return ""
180 | case .SSX: return ""
181 | case .STRAX: return ""
182 | case .XTZ: return ""
183 | case .HIVE: return ""
184 | case .TON: return ""
185 | case .POLY: return ""
186 | case .LINK: return ""
187 | case .MVL: return ""
188 | case .ONT: return ""
189 | case .MED: return ""
190 | case .BSV: return ""
191 | case .SBD: return ""
192 | case .QTCON: return ""
193 | case .CVC: return ""
194 | case .AQT: return ""
195 | case .TT: return ""
196 | case .IOST: return ""
197 | case .PXL: return ""
198 | case .CBK: return ""
199 | case .DOGE: return ""
200 | case .AHT: return ""
201 | case .SNT: return ""
202 | case .RFR: return ""
203 | case .STPT: return ""
204 | case .THETA: return ""
205 | case .ZPX: return ""
206 | case .BAT: return ""
207 | case .ARK: return ""
208 | case .ADX: return ""
209 | case .AERGO: return ""
210 | case .FCT2: return ""
211 | case .NEO: return ""
212 | case .MARO: return ""
213 | case .STORJ: return ""
214 | case .JST: return ""
215 | case .SRN: return ""
216 | case .ELF: return ""
217 | case .MBL: return ""
218 | case .HUM: return ""
219 | case .LOOM: return ""
220 | case .OBSR: return ""
221 | case .ZIL: return ""
222 | case .KAVA: return ""
223 | case .ARDR: return ""
224 | case .KMD: return ""
225 | case .LAMB: return ""
226 | case .TSHP: return ""
227 | case .ATOM: return ""
228 | case .STMX: return ""
229 | case .LSK: return ""
230 | case .BCHA: return ""
231 | case .EDR: return ""
232 | case .QKC: return ""
233 | case .ORBS: return ""
234 | case .SC: return ""
235 | case .IGNIS: return ""
236 | case .SPND: return ""
237 | case .REP: return ""
238 | case .IQ: return ""
239 | case .WAVES: return ""
240 | case .KNC: return ""
241 | case .IOTA: return ""
242 | }
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/Sources/SettingViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SettingViewController.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/08.
6 | //
7 |
8 | import Cocoa
9 | import Then
10 | import SnapKit
11 | import LaunchAtLogin
12 |
13 |
14 | class SettingViewController: NSViewController {
15 |
16 | private struct Consts {
17 |
18 | static let viewRect = NSRect(x: 0, y: 0, width: 480, height: 240)
19 | static let accessTokenFieldFrame = NSRect(x: 0, y: 0, width: 300, height: 30)
20 | static let refreshTokenFieldFrame = NSRect(x: 0, y: 40, width: 300, height: 30)
21 | }
22 |
23 | private var keys = UPbitKeys()
24 |
25 | private let accessTokenField = NSTextField().then {
26 | $0.frame = Consts.accessTokenFieldFrame
27 | }
28 |
29 | private let secretTokenField = NSTextField().then {
30 | $0.frame = Consts.refreshTokenFieldFrame
31 | }
32 |
33 | private let accessTokenLabel = NSTextField().then {
34 | $0.stringValue = Localized.accessToken
35 | $0.isBezeled = false
36 | $0.isEditable = false
37 | $0.backgroundColor = .clear
38 | $0.sizeToFit()
39 | }
40 |
41 | private let refreshTokenLabel = NSTextField().then {
42 | $0.stringValue = Localized.secretToken
43 | $0.isBezeled = false
44 | $0.isEditable = false
45 | $0.backgroundColor = .clear
46 | $0.sizeToFit()
47 | }
48 |
49 | private let refreshTimeLabel = NSTextField().then {
50 | $0.stringValue = Localized.refreshTime
51 | $0.isBezeled = false
52 | $0.isEditable = false
53 | $0.backgroundColor = .clear
54 | $0.sizeToFit()
55 | }
56 |
57 | private let refreshTimeCheckbox = NSPopUpButton().then {
58 | $0.addItem(withTitle: Localized.oneMinutes)
59 | $0.addItem(withTitle: Localized.fiveMinutes)
60 | $0.addItem(withTitle: Localized.tenMinutes)
61 | $0.addItem(withTitle: Localized.fifteenMinues)
62 | }
63 |
64 | private let quitButton = NSButton().then {
65 | $0.title = Localized.settingQuit
66 | $0.action = #selector(onQuitTap)
67 | $0.bezelStyle = .rounded
68 | }
69 |
70 | private let helpButton = NSButton().then {
71 | $0.title = Localized.settingHelpFeedback
72 | $0.action = #selector(onHelpTap)
73 | $0.bezelStyle = .rounded
74 | }
75 |
76 | private let saveButton = NSButton().then {
77 | $0.title = Localized.settingSave
78 | $0.action = #selector(onSaveTap)
79 | $0.bezelStyle = .rounded
80 | $0.keyEquivalent = "\r"
81 | $0.highlight(true)
82 | }
83 |
84 | private let startAtLoginButton = NSButton(checkboxWithTitle: Localized.autoLaunch, target: nil, action: #selector(setupLaunchToggle)).then {
85 | $0.state = LaunchAtLogin.isEnabled ? .on : .off
86 | }
87 |
88 |
89 | override func loadView() {
90 | let rect = Consts.viewRect
91 | view = NSView(frame: rect)
92 | view.wantsLayer = true
93 | view.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor
94 |
95 |
96 | view.addSubview(accessTokenLabel)
97 | view.addSubview(accessTokenField)
98 | view.addSubview(refreshTokenLabel)
99 | view.addSubview(secretTokenField)
100 | view.addSubview(refreshTimeLabel)
101 | view.addSubview(refreshTimeCheckbox)
102 | view.addSubview(startAtLoginButton)
103 | view.addSubview(quitButton)
104 | view.addSubview(helpButton)
105 | view.addSubview(saveButton)
106 |
107 |
108 |
109 | setupDefaultValues()
110 | setupConstraints()
111 | }
112 |
113 | func setupConstraints() {
114 |
115 | accessTokenLabel.snp.makeConstraints {
116 | $0.top.equalToSuperview().offset(50)
117 | $0.left.equalToSuperview().offset(10)
118 | }
119 |
120 | accessTokenField.snp.makeConstraints {
121 | $0.centerY.equalTo(accessTokenLabel.snp.centerY)
122 | $0.left.equalTo(accessTokenLabel.snp.right).offset(30)
123 | }
124 |
125 | refreshTokenLabel.snp.makeConstraints {
126 | $0.top.equalTo(accessTokenLabel.snp.bottom).offset(20)
127 | $0.left.equalToSuperview().offset(10)
128 | }
129 |
130 | secretTokenField.snp.makeConstraints {
131 | $0.centerY.equalTo(refreshTokenLabel.snp.centerY)
132 | $0.left.equalTo(refreshTokenLabel.snp.right).offset(30)
133 | }
134 |
135 |
136 | refreshTimeLabel.snp.makeConstraints {
137 | $0.top.equalTo(secretTokenField.snp.bottom).offset(20)
138 | $0.left.equalToSuperview().offset(10)
139 | }
140 |
141 | refreshTimeCheckbox.snp.makeConstraints {
142 | $0.centerY.equalTo(refreshTimeLabel.snp.centerY)
143 | $0.left.equalTo(refreshTimeLabel.snp.right).offset(30)
144 | }
145 |
146 | startAtLoginButton.snp.makeConstraints {
147 | $0.top.equalTo(refreshTimeCheckbox.snp.bottom).offset(20)
148 | $0.left.equalToSuperview().offset(10)
149 | }
150 |
151 | quitButton.snp.makeConstraints {
152 | $0.bottom.equalToSuperview().offset(-20)
153 | $0.left.equalToSuperview().offset(20)
154 | $0.size.equalTo(CGSize(width: 100, height: 20))
155 | }
156 |
157 | helpButton.snp.makeConstraints {
158 | $0.bottom.equalToSuperview().offset(-20)
159 | $0.left.equalTo(quitButton.snp.right).offset(20)
160 | $0.size.equalTo(CGSize(width: 120, height: 20))
161 | }
162 |
163 | saveButton.snp.makeConstraints {
164 | $0.bottom.equalToSuperview().offset(-20)
165 | $0.right.equalToSuperview().offset(-20)
166 | $0.size.equalTo(CGSize(width: 100, height: 20))
167 | }
168 | }
169 |
170 | // MARK: Private functions
171 |
172 | func setupDefaultValues() {
173 | accessTokenField.stringValue = keys.accessToken
174 | secretTokenField.stringValue = keys.secretToken
175 |
176 | if keys.refershInterVal == -1 {
177 | keys.refershInterVal = 1
178 | }
179 |
180 | refreshTimeCheckbox.selectItem(at: keys.refershInterVal)
181 | startAtLoginButton.state = LaunchAtLogin.isEnabled ? .off : .on
182 | }
183 |
184 | @objc func setupLaunchToggle() {
185 | LaunchAtLogin.isEnabled.toggle()
186 | }
187 |
188 | @objc func onQuitTap() {
189 | NSApp.stopModal()
190 | }
191 |
192 | @objc func onHelpTap() {
193 | let url = URL(string: Constants.notionURL.rawValue)!
194 | NSWorkspace.shared.open(url)
195 | }
196 |
197 | @objc func onSaveTap() {
198 | print("onSaveTap")
199 |
200 | let accessToken = accessTokenField.stringValue
201 | let refreshToken = secretTokenField.stringValue
202 |
203 | if accessToken.isEmpty || accessToken.count < 40{
204 |
205 | let alert = NSAlert()
206 | alert.alertStyle = .warning
207 | alert.messageText = Localized.settingAlertTitle
208 | alert.informativeText = Localized.settingAlertAccessTokenInfoText
209 | alert.addButton(withTitle: Localized.ok)
210 | if alert.runModal() == .alertFirstButtonReturn {
211 | return
212 | }
213 | } else if refreshToken.isEmpty || refreshToken.count < 40 {
214 |
215 | let alert = NSAlert()
216 | alert.messageText = Localized.settingAlertTitle
217 | alert.informativeText = Localized.settingAlertRefreshTokenInfoText
218 | alert.addButton(withTitle: Localized.ok)
219 | if alert.runModal() == .alertFirstButtonReturn {
220 | return
221 | }
222 | }
223 |
224 | keys.accessToken = accessToken
225 | keys.secretToken = refreshToken
226 | keys.refershInterVal = refreshTimeCheckbox.indexOfSelectedItem
227 |
228 | NSApp.stopModal()
229 | NotificationCenter.default.post(name: .neededRefresh, object: nil)
230 |
231 | }
232 |
233 | }
234 |
--------------------------------------------------------------------------------
/Sources/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // upbitBar
4 | //
5 | // Created by Fernando on 2021/03/07.
6 | //
7 |
8 | import Cocoa
9 | import Then
10 |
11 | @main
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 |
15 | private struct Consts {
16 | static let cryptoTags = 99
17 | }
18 |
19 | private var statusItem: NSStatusItem?
20 | private var refreshTimer: Timer?
21 | private var keys = UPbitKeys()
22 |
23 | private let menu = NSMenu().then {
24 | $0.title = ""
25 | }
26 |
27 | private let refreshMenuItem = NSMenuItem().then {
28 | $0.title = Localized.refresh
29 | $0.action = #selector(onRefreshTap)
30 | $0.tag = 1
31 | $0.keyEquivalent = "r"
32 | }
33 |
34 | private let settingMenuItem = NSMenuItem().then {
35 | $0.title = Localized.setting
36 | $0.action = #selector(onSettingTap)
37 | $0.tag = 2
38 | $0.keyEquivalent = "s"
39 | }
40 |
41 | private let quitMenuItem = NSMenuItem().then {
42 | $0.title = Localized.quit
43 | $0.action = #selector(onQuitTap)
44 | $0.tag = 3
45 | $0.keyEquivalent = "q"
46 | }
47 |
48 | private var settingWindow: NSWindow!
49 |
50 | func applicationDidFinishLaunching(_ aNotification: Notification) {
51 | // Insert code here to initialize your application
52 | NotificationCenter.default.addObserver(self, selector: #selector(onDidNeedTokenSetting(_:)), name: .neededTokenSetting, object: nil)
53 | NotificationCenter.default.addObserver(self, selector: #selector(onDidNeedRefresh(_:)), name: .neededRefresh, object: nil)
54 |
55 | setupUI()
56 | setupSettingWindow()
57 | getAllBalances()
58 | setupRefreshTimer()
59 | }
60 |
61 | func applicationWillTerminate(_ aNotification: Notification) {
62 | // Insert code here to tear down your application
63 | }
64 |
65 | func setupUI() {
66 |
67 | menu.addItem(.separator())
68 | menu.addItem(refreshMenuItem)
69 | menu.addItem(settingMenuItem)
70 | menu.addItem(quitMenuItem)
71 |
72 | statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
73 | statusItem?.menu = menu
74 |
75 | self.statusItem?.button?.title = "Loading ... "
76 |
77 | }
78 |
79 | private func setupSettingWindow() {
80 | let windowSize = NSSize(width: 480, height: 240)
81 | let screenSize = NSScreen.main?.frame.size ?? .zero
82 | let rect = NSMakeRect(screenSize.width/2 - windowSize.width/2, screenSize.height/2 - windowSize.height/2, windowSize.width, windowSize.height)
83 | settingWindow = NSWindow(contentRect: rect, styleMask: [.miniaturizable, .closable, .titled], backing: .buffered, defer: false)
84 | settingWindow.title = Localized.settingTitle
85 | settingWindow.contentViewController = SettingViewController()
86 | settingWindow.delegate = self
87 | }
88 |
89 | @objc func onDidNeedTokenSetting(_ notification: Notification) {
90 | self.showSettingAlert()
91 | }
92 |
93 | @objc func onDidNeedRefresh(_ notification: Notification) {
94 | self.refresh()
95 | }
96 |
97 | @objc func onRefreshTap() {
98 | self.refresh()
99 | }
100 |
101 | @objc func onSettingTap() {
102 | self.showSettingAlert()
103 | }
104 |
105 | @objc func onQuitTap() {
106 | NSApplication.shared.terminate(self)
107 | }
108 |
109 | @objc func onMenuItemTap() {
110 | //NSApplication.shared.terminate(self)
111 | print("menu")
112 | }
113 |
114 | // MARK: Private functions
115 |
116 | private func refresh() {
117 | invalidateRefreshTimer()
118 | removeAllItems()
119 | getAllBalances()
120 | setupRefreshTimer()
121 | }
122 |
123 | private func setupRefreshTimer() {
124 |
125 | let refreshInterval = RefreshInterval(rawValue: keys.refershInterVal)
126 | let timeInterval = refreshInterval?.minutes ?? 5
127 |
128 | refreshTimer = Timer.scheduledTimer(withTimeInterval: TimeInterval( timeInterval * 60),
129 | repeats: true,
130 | block: { [weak self] _ in
131 | guard let self = self else { return }
132 | self.refresh()
133 | })
134 | }
135 |
136 | private func invalidateRefreshTimer() {
137 | refreshTimer?.invalidate()
138 | }
139 |
140 | private func showSettingAlert() {
141 | NSApp.runModal(for: settingWindow)
142 | NSApp.activate(ignoringOtherApps: true)
143 | settingWindow.orderOut(self)
144 | }
145 |
146 | private func removeAllItems() {
147 | _ = menu.items.map {
148 | if $0.tag == Consts.cryptoTags {
149 | self.menu.removeItem($0)
150 | }
151 | }
152 | }
153 |
154 | private func getAllBalances() {
155 | guard let balances = UpbitServices.shared.getBalances(),
156 | let allMarket = UpbitServices.shared.getAllMarket() else { return }
157 |
158 | let availableMarkets = allMarket.compactMap{ $0.market }
159 | let currency: [String] = balances
160 | .map { "\($0.unitCurrency)-\($0.currency)" }
161 | .filter{ market -> Bool in availableMarkets.filter{ $0 == market }.first != nil }
162 |
163 | var myCurrency: [String: Market] {
164 | var tempDict: [String: Market] = [:]
165 | for currencyItem in currency {
166 | tempDict[currencyItem] = allMarket.filter{ $0.market == currencyItem }.first
167 | }
168 | return tempDict
169 | }
170 |
171 | let markets = currency.joined(separator: ",")
172 | guard let tickers = UpbitServices.shared.getTicker(markets: markets) else { return }
173 |
174 | var totalBalances: [Double] = []
175 | var avgTotalBalances: [Double] = []
176 |
177 | for ticker in tickers {
178 | for balance in balances {
179 | let currentMarket = "\(balance.unitCurrency)-\(balance.currency)"
180 | if ticker.market == currentMarket {
181 |
182 | let totalAsset = Double(balance.balance) ?? 0
183 | let totalPrice = Double(ticker.tradePrice) * totalAsset
184 | let buyPrice = Double(balance.avgBuyPrice)! * totalAsset
185 | let percent = (Double(ticker.tradePrice) / Double(balance.avgBuyPrice)!-1.0) * 100
186 |
187 | var emoji = "-"
188 | var attributes = Attributes.cryptoNormalAttributes
189 |
190 | if totalPrice < buyPrice {
191 | emoji = "📉"
192 | attributes = Attributes.cryptoBlueAttributes
193 | } else if buyPrice < totalPrice {
194 | emoji = "📈"
195 | attributes = Attributes.cryptoRedAttributes
196 | }
197 |
198 | avgTotalBalances.append(buyPrice)
199 | totalBalances.append(totalPrice)
200 |
201 | let totalString = self.convertCurrency(prefix:"", money: round(totalPrice))
202 |
203 | let currentCurrency = myCurrency[currentMarket]
204 | let currencyName = currentCurrency?.koreanName ?? currentCurrency?.englishName ?? ""
205 |
206 | let title: String = "\(emoji) \(currencyName)(\(balance.currency)) - \(totalString) (\(percent.rounded())%)"
207 |
208 | let menuItem = NSMenuItem().then {
209 | $0.isEnabled = true
210 | $0.tag = Consts.cryptoTags
211 | $0.action = #selector(onMenuItemTap)
212 | $0.attributedTitle = NSAttributedString(string: title, attributes: attributes)
213 | }
214 |
215 | self.menu.insertItem(menuItem, at: .zero)
216 | }
217 | }
218 | }
219 |
220 | let total = totalBalances.map { round($0) }.reduce(0, +)
221 | let avg = avgTotalBalances.map { round($0) }.reduce(0, +)
222 | var title = ""
223 | var totalAttributes = Attributes.cryptoNormalAttributes
224 |
225 | if avg < total {
226 | title = self.convertCurrency(prefix: "📈", money: total)
227 | totalAttributes = Attributes.cryptoRedAttributes
228 | } else if total < avg {
229 | title = self.convertCurrency(prefix: "📉", money: total)
230 | totalAttributes = Attributes.cryptoBlueAttributes
231 | }
232 |
233 | self.statusItem?.button?.attributedTitle = NSAttributedString(string: title, attributes: totalAttributes)
234 | }
235 |
236 | func convertCurrency(prefix: String, money: Double) -> String {
237 |
238 | let number = NSNumber(value: money)
239 | let numberFormatter = NumberFormatter()
240 | numberFormatter.numberStyle = .decimal
241 |
242 | let decimalString = numberFormatter.string(from: number)!
243 |
244 | return prefix.isEmpty ? "₩\(decimalString)" : "\(prefix) ₩\(decimalString)"
245 | }
246 |
247 | }
248 |
249 |
250 |
251 | extension AppDelegate: NSWindowDelegate {
252 | func windowWillClose(_ notification: Notification) {
253 | NSApp.stopModal()
254 | }
255 | }
256 |
--------------------------------------------------------------------------------
/Supporting Files/ko.lproj/Main.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "NSMenuItem"; title = "Customize Toolbar…"; ObjectID = "1UK-8n-QPP"; */
3 | "1UK-8n-QPP.title" = "Customize Toolbar…";
4 |
5 | /* Class = "NSMenuItem"; title = "upbitBar"; ObjectID = "1Xt-HY-uBw"; */
6 | "1Xt-HY-uBw.title" = "upbitBar";
7 |
8 | /* Class = "NSMenu"; title = "Find"; ObjectID = "1b7-l0-nxx"; */
9 | "1b7-l0-nxx.title" = "Find";
10 |
11 | /* Class = "NSMenuItem"; title = "Lower"; ObjectID = "1tx-W0-xDw"; */
12 | "1tx-W0-xDw.title" = "Lower";
13 |
14 | /* Class = "NSMenuItem"; title = "Raise"; ObjectID = "2h7-ER-AoG"; */
15 | "2h7-ER-AoG.title" = "Raise";
16 |
17 | /* Class = "NSMenuItem"; title = "Transformations"; ObjectID = "2oI-Rn-ZJC"; */
18 | "2oI-Rn-ZJC.title" = "Transformations";
19 |
20 | /* Class = "NSMenu"; title = "Spelling"; ObjectID = "3IN-sU-3Bg"; */
21 | "3IN-sU-3Bg.title" = "Spelling";
22 |
23 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "3Om-Ey-2VK"; */
24 | "3Om-Ey-2VK.title" = "Use Default";
25 |
26 | /* Class = "NSMenu"; title = "Speech"; ObjectID = "3rS-ZA-NoH"; */
27 | "3rS-ZA-NoH.title" = "Speech";
28 |
29 | /* Class = "NSMenuItem"; title = "Tighten"; ObjectID = "46P-cB-AYj"; */
30 | "46P-cB-AYj.title" = "Tighten";
31 |
32 | /* Class = "NSMenuItem"; title = "Find"; ObjectID = "4EN-yA-p0u"; */
33 | "4EN-yA-p0u.title" = "Find";
34 |
35 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */
36 | "4J7-dP-txa.title" = "Enter Full Screen";
37 |
38 | /* Class = "NSMenuItem"; title = "Quit upbitBar"; ObjectID = "4sb-4s-VLi"; */
39 | "4sb-4s-VLi.title" = "Quit upbitBar";
40 |
41 | /* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
42 | "5QF-Oa-p0T.title" = "Edit";
43 |
44 | /* Class = "NSMenuItem"; title = "Copy Style"; ObjectID = "5Vv-lz-BsD"; */
45 | "5Vv-lz-BsD.title" = "Copy Style";
46 |
47 | /* Class = "NSMenuItem"; title = "About upbitBar"; ObjectID = "5kV-Vb-QxS"; */
48 | "5kV-Vb-QxS.title" = "About upbitBar";
49 |
50 | /* Class = "NSMenuItem"; title = "Redo"; ObjectID = "6dh-zS-Vam"; */
51 | "6dh-zS-Vam.title" = "Redo";
52 |
53 | /* Class = "NSMenuItem"; title = "Correct Spelling Automatically"; ObjectID = "78Y-hA-62v"; */
54 | "78Y-hA-62v.title" = "Correct Spelling Automatically";
55 |
56 | /* Class = "NSMenu"; title = "Writing Direction"; ObjectID = "8mr-sm-Yjd"; */
57 | "8mr-sm-Yjd.title" = "Writing Direction";
58 |
59 | /* Class = "NSMenuItem"; title = "Substitutions"; ObjectID = "9ic-FL-obx"; */
60 | "9ic-FL-obx.title" = "Substitutions";
61 |
62 | /* Class = "NSMenuItem"; title = "Smart Copy/Paste"; ObjectID = "9yt-4B-nSM"; */
63 | "9yt-4B-nSM.title" = "Smart Copy/Paste";
64 |
65 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
66 | "AYu-sK-qS6.title" = "Main Menu";
67 |
68 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
69 | "BOF-NM-1cW.title" = "Preferences…";
70 |
71 | /* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "BgM-ve-c93"; */
72 | "BgM-ve-c93.title" = "\tLeft to Right";
73 |
74 | /* Class = "NSMenuItem"; title = "Save As…"; ObjectID = "Bw7-FT-i3A"; */
75 | "Bw7-FT-i3A.title" = "Save As…";
76 |
77 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */
78 | "DVo-aG-piG.title" = "Close";
79 |
80 | /* Class = "NSMenuItem"; title = "Spelling and Grammar"; ObjectID = "Dv1-io-Yv7"; */
81 | "Dv1-io-Yv7.title" = "Spelling and Grammar";
82 |
83 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */
84 | "F2S-fz-NVQ.title" = "Help";
85 |
86 | /* Class = "NSMenuItem"; title = "upbitBar Help"; ObjectID = "FKE-Sm-Kum"; */
87 | "FKE-Sm-Kum.title" = "upbitBar Help";
88 |
89 | /* Class = "NSMenuItem"; title = "Text"; ObjectID = "Fal-I4-PZk"; */
90 | "Fal-I4-PZk.title" = "Text";
91 |
92 | /* Class = "NSMenu"; title = "Substitutions"; ObjectID = "FeM-D8-WVr"; */
93 | "FeM-D8-WVr.title" = "Substitutions";
94 |
95 | /* Class = "NSMenuItem"; title = "Bold"; ObjectID = "GB9-OM-e27"; */
96 | "GB9-OM-e27.title" = "Bold";
97 |
98 | /* Class = "NSMenu"; title = "Format"; ObjectID = "GEO-Iw-cKr"; */
99 | "GEO-Iw-cKr.title" = "Format";
100 |
101 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "GUa-eO-cwY"; */
102 | "GUa-eO-cwY.title" = "Use Default";
103 |
104 | /* Class = "NSMenuItem"; title = "Font"; ObjectID = "Gi5-1S-RQB"; */
105 | "Gi5-1S-RQB.title" = "Font";
106 |
107 | /* Class = "NSMenuItem"; title = "Writing Direction"; ObjectID = "H1b-Si-o9J"; */
108 | "H1b-Si-o9J.title" = "Writing Direction";
109 |
110 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
111 | "H8h-7b-M4v.title" = "View";
112 |
113 | /* Class = "NSMenuItem"; title = "Text Replacement"; ObjectID = "HFQ-gK-NFA"; */
114 | "HFQ-gK-NFA.title" = "Text Replacement";
115 |
116 | /* Class = "NSMenuItem"; title = "Show Spelling and Grammar"; ObjectID = "HFo-cy-zxI"; */
117 | "HFo-cy-zxI.title" = "Show Spelling and Grammar";
118 |
119 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */
120 | "HyV-fh-RgO.title" = "View";
121 |
122 | /* Class = "NSMenuItem"; title = "Subscript"; ObjectID = "I0S-gh-46l"; */
123 | "I0S-gh-46l.title" = "Subscript";
124 |
125 | /* Class = "NSMenuItem"; title = "Open…"; ObjectID = "IAo-SY-fd9"; */
126 | "IAo-SY-fd9.title" = "Open…";
127 |
128 | /* Class = "NSMenuItem"; title = "Justify"; ObjectID = "J5U-5w-g23"; */
129 | "J5U-5w-g23.title" = "Justify";
130 |
131 | /* Class = "NSMenuItem"; title = "Use None"; ObjectID = "J7y-lM-qPV"; */
132 | "J7y-lM-qPV.title" = "Use None";
133 |
134 | /* Class = "NSMenuItem"; title = "Revert to Saved"; ObjectID = "KaW-ft-85H"; */
135 | "KaW-ft-85H.title" = "Revert to Saved";
136 |
137 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
138 | "Kd2-mp-pUS.title" = "Show All";
139 |
140 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */
141 | "LE2-aR-0XJ.title" = "Bring All to Front";
142 |
143 | /* Class = "NSMenuItem"; title = "Paste Ruler"; ObjectID = "LVM-kO-fVI"; */
144 | "LVM-kO-fVI.title" = "Paste Ruler";
145 |
146 | /* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "Lbh-J2-qVU"; */
147 | "Lbh-J2-qVU.title" = "\tLeft to Right";
148 |
149 | /* Class = "NSMenuItem"; title = "Copy Ruler"; ObjectID = "MkV-Pr-PK5"; */
150 | "MkV-Pr-PK5.title" = "Copy Ruler";
151 |
152 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
153 | "NMo-om-nkz.title" = "Services";
154 |
155 | /* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "Nop-cj-93Q"; */
156 | "Nop-cj-93Q.title" = "\tDefault";
157 |
158 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */
159 | "OY7-WF-poV.title" = "Minimize";
160 |
161 | /* Class = "NSMenuItem"; title = "Baseline"; ObjectID = "OaQ-X3-Vso"; */
162 | "OaQ-X3-Vso.title" = "Baseline";
163 |
164 | /* Class = "NSMenuItem"; title = "Hide upbitBar"; ObjectID = "Olw-nP-bQN"; */
165 | "Olw-nP-bQN.title" = "Hide upbitBar";
166 |
167 | /* Class = "NSMenuItem"; title = "Find Previous"; ObjectID = "OwM-mh-QMV"; */
168 | "OwM-mh-QMV.title" = "Find Previous";
169 |
170 | /* Class = "NSMenuItem"; title = "Stop Speaking"; ObjectID = "Oyz-dy-DGm"; */
171 | "Oyz-dy-DGm.title" = "Stop Speaking";
172 |
173 | /* Class = "NSMenuItem"; title = "Bigger"; ObjectID = "Ptp-SP-VEL"; */
174 | "Ptp-SP-VEL.title" = "Bigger";
175 |
176 | /* Class = "NSMenuItem"; title = "Show Fonts"; ObjectID = "Q5e-8K-NDq"; */
177 | "Q5e-8K-NDq.title" = "Show Fonts";
178 |
179 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */
180 | "R4o-n2-Eq4.title" = "Zoom";
181 |
182 | /* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "RB4-Sm-HuC"; */
183 | "RB4-Sm-HuC.title" = "\tRight to Left";
184 |
185 | /* Class = "NSMenuItem"; title = "Superscript"; ObjectID = "Rqc-34-cIF"; */
186 | "Rqc-34-cIF.title" = "Superscript";
187 |
188 | /* Class = "NSMenuItem"; title = "Select All"; ObjectID = "Ruw-6m-B2m"; */
189 | "Ruw-6m-B2m.title" = "Select All";
190 |
191 | /* Class = "NSMenuItem"; title = "Jump to Selection"; ObjectID = "S0p-oC-mLd"; */
192 | "S0p-oC-mLd.title" = "Jump to Selection";
193 |
194 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */
195 | "Td7-aD-5lo.title" = "Window";
196 |
197 | /* Class = "NSMenuItem"; title = "Capitalize"; ObjectID = "UEZ-Bs-lqG"; */
198 | "UEZ-Bs-lqG.title" = "Capitalize";
199 |
200 | /* Class = "NSMenuItem"; title = "Center"; ObjectID = "VIY-Ag-zcb"; */
201 | "VIY-Ag-zcb.title" = "Center";
202 |
203 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
204 | "Vdr-fp-XzO.title" = "Hide Others";
205 |
206 | /* Class = "NSMenuItem"; title = "Italic"; ObjectID = "Vjx-xi-njq"; */
207 | "Vjx-xi-njq.title" = "Italic";
208 |
209 | /* Class = "NSMenu"; title = "Edit"; ObjectID = "W48-6f-4Dl"; */
210 | "W48-6f-4Dl.title" = "Edit";
211 |
212 | /* Class = "NSMenuItem"; title = "Underline"; ObjectID = "WRG-CD-K1S"; */
213 | "WRG-CD-K1S.title" = "Underline";
214 |
215 | /* Class = "NSMenuItem"; title = "New"; ObjectID = "Was-JA-tGl"; */
216 | "Was-JA-tGl.title" = "New";
217 |
218 | /* Class = "NSMenuItem"; title = "Paste and Match Style"; ObjectID = "WeT-3V-zwk"; */
219 | "WeT-3V-zwk.title" = "Paste and Match Style";
220 |
221 | /* Class = "NSMenuItem"; title = "Find…"; ObjectID = "Xz5-n4-O0W"; */
222 | "Xz5-n4-O0W.title" = "Find…";
223 |
224 | /* Class = "NSMenuItem"; title = "Find and Replace…"; ObjectID = "YEy-JH-Tfz"; */
225 | "YEy-JH-Tfz.title" = "Find and Replace…";
226 |
227 | /* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "YGs-j5-SAR"; */
228 | "YGs-j5-SAR.title" = "\tDefault";
229 |
230 | /* Class = "NSMenuItem"; title = "Start Speaking"; ObjectID = "Ynk-f8-cLZ"; */
231 | "Ynk-f8-cLZ.title" = "Start Speaking";
232 |
233 | /* Class = "NSMenuItem"; title = "Align Left"; ObjectID = "ZM1-6Q-yy1"; */
234 | "ZM1-6Q-yy1.title" = "Align Left";
235 |
236 | /* Class = "NSMenuItem"; title = "Paragraph"; ObjectID = "ZvO-Gk-QUH"; */
237 | "ZvO-Gk-QUH.title" = "Paragraph";
238 |
239 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */
240 | "aTl-1u-JFS.title" = "Print…";
241 |
242 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
243 | "aUF-d1-5bR.title" = "Window";
244 |
245 | /* Class = "NSMenu"; title = "Font"; ObjectID = "aXa-aM-Jaq"; */
246 | "aXa-aM-Jaq.title" = "Font";
247 |
248 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "agt-UL-0e3"; */
249 | "agt-UL-0e3.title" = "Use Default";
250 |
251 | /* Class = "NSMenuItem"; title = "Show Colors"; ObjectID = "bgn-CT-cEk"; */
252 | "bgn-CT-cEk.title" = "Show Colors";
253 |
254 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */
255 | "bib-Uj-vzu.title" = "File";
256 |
257 | /* Class = "NSMenuItem"; title = "Use Selection for Find"; ObjectID = "buJ-ug-pKt"; */
258 | "buJ-ug-pKt.title" = "Use Selection for Find";
259 |
260 | /* Class = "NSMenu"; title = "Transformations"; ObjectID = "c8a-y6-VQd"; */
261 | "c8a-y6-VQd.title" = "Transformations";
262 |
263 | /* Class = "NSMenuItem"; title = "Use None"; ObjectID = "cDB-IK-hbR"; */
264 | "cDB-IK-hbR.title" = "Use None";
265 |
266 | /* Class = "NSMenuItem"; title = "Selection"; ObjectID = "cqv-fj-IhA"; */
267 | "cqv-fj-IhA.title" = "Selection";
268 |
269 | /* Class = "NSMenuItem"; title = "Smart Links"; ObjectID = "cwL-P1-jid"; */
270 | "cwL-P1-jid.title" = "Smart Links";
271 |
272 | /* Class = "NSMenuItem"; title = "Make Lower Case"; ObjectID = "d9M-CD-aMd"; */
273 | "d9M-CD-aMd.title" = "Make Lower Case";
274 |
275 | /* Class = "NSMenu"; title = "Text"; ObjectID = "d9c-me-L2H"; */
276 | "d9c-me-L2H.title" = "Text";
277 |
278 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
279 | "dMs-cI-mzQ.title" = "File";
280 |
281 | /* Class = "NSMenuItem"; title = "Undo"; ObjectID = "dRJ-4n-Yzg"; */
282 | "dRJ-4n-Yzg.title" = "Undo";
283 |
284 | /* Class = "NSMenuItem"; title = "Paste"; ObjectID = "gVA-U4-sdL"; */
285 | "gVA-U4-sdL.title" = "Paste";
286 |
287 | /* Class = "NSMenuItem"; title = "Smart Quotes"; ObjectID = "hQb-2v-fYv"; */
288 | "hQb-2v-fYv.title" = "Smart Quotes";
289 |
290 | /* Class = "NSMenuItem"; title = "Check Document Now"; ObjectID = "hz2-CU-CR7"; */
291 | "hz2-CU-CR7.title" = "Check Document Now";
292 |
293 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
294 | "hz9-B4-Xy5.title" = "Services";
295 |
296 | /* Class = "NSMenuItem"; title = "Smaller"; ObjectID = "i1d-Er-qST"; */
297 | "i1d-Er-qST.title" = "Smaller";
298 |
299 | /* Class = "NSMenu"; title = "Baseline"; ObjectID = "ijk-EB-dga"; */
300 | "ijk-EB-dga.title" = "Baseline";
301 |
302 | /* Class = "NSMenuItem"; title = "Kern"; ObjectID = "jBQ-r6-VK2"; */
303 | "jBQ-r6-VK2.title" = "Kern";
304 |
305 | /* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "jFq-tB-4Kx"; */
306 | "jFq-tB-4Kx.title" = "\tRight to Left";
307 |
308 | /* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
309 | "jxT-CU-nIS.title" = "Format";
310 |
311 | /* Class = "NSMenuItem"; title = "Show Sidebar"; ObjectID = "kIP-vf-haE"; */
312 | "kIP-vf-haE.title" = "Show Sidebar";
313 |
314 | /* Class = "NSMenuItem"; title = "Check Grammar With Spelling"; ObjectID = "mK6-2p-4JG"; */
315 | "mK6-2p-4JG.title" = "Check Grammar With Spelling";
316 |
317 | /* Class = "NSMenuItem"; title = "Ligatures"; ObjectID = "o6e-r0-MWq"; */
318 | "o6e-r0-MWq.title" = "Ligatures";
319 |
320 | /* Class = "NSMenu"; title = "Open Recent"; ObjectID = "oas-Oc-fiZ"; */
321 | "oas-Oc-fiZ.title" = "Open Recent";
322 |
323 | /* Class = "NSMenuItem"; title = "Loosen"; ObjectID = "ogc-rX-tC1"; */
324 | "ogc-rX-tC1.title" = "Loosen";
325 |
326 | /* Class = "NSMenuItem"; title = "Delete"; ObjectID = "pa3-QI-u2k"; */
327 | "pa3-QI-u2k.title" = "Delete";
328 |
329 | /* Class = "NSMenuItem"; title = "Save…"; ObjectID = "pxx-59-PXV"; */
330 | "pxx-59-PXV.title" = "Save…";
331 |
332 | /* Class = "NSMenuItem"; title = "Find Next"; ObjectID = "q09-fT-Sye"; */
333 | "q09-fT-Sye.title" = "Find Next";
334 |
335 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */
336 | "qIS-W8-SiK.title" = "Page Setup…";
337 |
338 | /* Class = "NSMenuItem"; title = "Check Spelling While Typing"; ObjectID = "rbD-Rh-wIN"; */
339 | "rbD-Rh-wIN.title" = "Check Spelling While Typing";
340 |
341 | /* Class = "NSMenuItem"; title = "Smart Dashes"; ObjectID = "rgM-f4-ycn"; */
342 | "rgM-f4-ycn.title" = "Smart Dashes";
343 |
344 | /* Class = "NSMenuItem"; title = "Show Toolbar"; ObjectID = "snW-S8-Cw5"; */
345 | "snW-S8-Cw5.title" = "Show Toolbar";
346 |
347 | /* Class = "NSMenuItem"; title = "Data Detectors"; ObjectID = "tRr-pd-1PS"; */
348 | "tRr-pd-1PS.title" = "Data Detectors";
349 |
350 | /* Class = "NSMenuItem"; title = "Open Recent"; ObjectID = "tXI-mr-wws"; */
351 | "tXI-mr-wws.title" = "Open Recent";
352 |
353 | /* Class = "NSMenu"; title = "Kern"; ObjectID = "tlD-Oa-oAM"; */
354 | "tlD-Oa-oAM.title" = "Kern";
355 |
356 | /* Class = "NSMenu"; title = "upbitBar"; ObjectID = "uQy-DD-JDr"; */
357 | "uQy-DD-JDr.title" = "upbitBar";
358 |
359 | /* Class = "NSMenuItem"; title = "Cut"; ObjectID = "uRl-iY-unG"; */
360 | "uRl-iY-unG.title" = "Cut";
361 |
362 | /* Class = "NSMenuItem"; title = "Paste Style"; ObjectID = "vKC-jM-MkH"; */
363 | "vKC-jM-MkH.title" = "Paste Style";
364 |
365 | /* Class = "NSMenuItem"; title = "Show Ruler"; ObjectID = "vLm-3I-IUL"; */
366 | "vLm-3I-IUL.title" = "Show Ruler";
367 |
368 | /* Class = "NSMenuItem"; title = "Clear Menu"; ObjectID = "vNY-rz-j42"; */
369 | "vNY-rz-j42.title" = "Clear Menu";
370 |
371 | /* Class = "NSMenuItem"; title = "Make Upper Case"; ObjectID = "vmV-6d-7jI"; */
372 | "vmV-6d-7jI.title" = "Make Upper Case";
373 |
374 | /* Class = "NSMenu"; title = "Ligatures"; ObjectID = "w0m-vy-SC9"; */
375 | "w0m-vy-SC9.title" = "Ligatures";
376 |
377 | /* Class = "NSMenuItem"; title = "Align Right"; ObjectID = "wb2-vD-lq4"; */
378 | "wb2-vD-lq4.title" = "Align Right";
379 |
380 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
381 | "wpr-3q-Mcd.title" = "Help";
382 |
383 | /* Class = "NSMenuItem"; title = "Copy"; ObjectID = "x3v-GG-iWU"; */
384 | "x3v-GG-iWU.title" = "Copy";
385 |
386 | /* Class = "NSMenuItem"; title = "Use All"; ObjectID = "xQD-1f-W4t"; */
387 | "xQD-1f-W4t.title" = "Use All";
388 |
389 | /* Class = "NSMenuItem"; title = "Speech"; ObjectID = "xrE-MZ-jX0"; */
390 | "xrE-MZ-jX0.title" = "Speech";
391 |
392 | /* Class = "NSMenuItem"; title = "Show Substitutions"; ObjectID = "z6F-FW-3nz"; */
393 | "z6F-FW-3nz.title" = "Show Substitutions";
394 |
--------------------------------------------------------------------------------
/upbitBar.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A7BC7B8626032E0000B2A6DB /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7BC7B8526032E0000B2A6DB /* Constants.swift */; };
11 | A7BC7B8A26032E3000B2A6DB /* Market.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7BC7B8926032E3000B2A6DB /* Market.swift */; };
12 | ED3BF34625F7C67A00F05BB5 /* Attributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED3BF34525F7C67A00F05BB5 /* Attributes.swift */; };
13 | ED6E757E25F51FE2006387CA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E757D25F51FE2006387CA /* AppDelegate.swift */; };
14 | ED6E758225F51FE3006387CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ED6E758125F51FE3006387CA /* Assets.xcassets */; };
15 | ED6E758525F51FE3006387CA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ED6E758325F51FE3006387CA /* Main.storyboard */; };
16 | ED6E759025F5204B006387CA /* Just in Frameworks */ = {isa = PBXBuildFile; productRef = ED6E758F25F5204B006387CA /* Just */; };
17 | ED6E759425F5224B006387CA /* JWTComponents in Frameworks */ = {isa = PBXBuildFile; productRef = ED6E759325F5224B006387CA /* JWTComponents */; };
18 | ED6E759925F522EC006387CA /* Then in Frameworks */ = {isa = PBXBuildFile; productRef = ED6E759825F522EC006387CA /* Then */; };
19 | ED6E759D25F52C45006387CA /* CryptoAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E759C25F52C45006387CA /* CryptoAsset.swift */; };
20 | ED6E75A225F52DE1006387CA /* UpbitServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E75A125F52DE1006387CA /* UpbitServices.swift */; };
21 | ED6E75A725F53056006387CA /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = ED6E75A625F53056006387CA /* Logging */; };
22 | ED6E75AA25F5325A006387CA /* Ticker.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E75A925F5325A006387CA /* Ticker.swift */; };
23 | ED6E75AD25F54617006387CA /* Cryptocurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E75AC25F54617006387CA /* Cryptocurrency.swift */; };
24 | ED6E75B125F54B0E006387CA /* LaunchAtLogin in Frameworks */ = {isa = PBXBuildFile; productRef = ED6E75B025F54B0E006387CA /* LaunchAtLogin */; };
25 | ED6E75B425F54B6C006387CA /* UpbitAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E75B325F54B6C006387CA /* UpbitAPI.swift */; };
26 | ED6E765625F648E8006387CA /* SettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E765525F648E8006387CA /* SettingViewController.swift */; };
27 | ED6E765A25F64BC5006387CA /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = ED6E765925F64BC5006387CA /* SnapKit */; };
28 | ED6E772125F67802006387CA /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E772025F67802006387CA /* UserInfo.swift */; };
29 | ED6E772A25F6836E006387CA /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E772925F6836E006387CA /* Notifications.swift */; };
30 | ED6E772D25F689E0006387CA /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E772C25F689E0006387CA /* RefreshInterval.swift */; };
31 | ED6E773425F68E8C006387CA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = ED6E773625F68E8C006387CA /* Localizable.strings */; };
32 | ED6E774125F68F14006387CA /* Localized.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED6E774025F68F14006387CA /* Localized.swift */; };
33 | /* End PBXBuildFile section */
34 |
35 | /* Begin PBXFileReference section */
36 | A7BC7B8526032E0000B2A6DB /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
37 | A7BC7B8926032E3000B2A6DB /* Market.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Market.swift; sourceTree = ""; };
38 | ED3BF34525F7C67A00F05BB5 /* Attributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attributes.swift; sourceTree = ""; };
39 | ED6E757A25F51FE2006387CA /* upbitBar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = upbitBar.app; sourceTree = BUILT_PRODUCTS_DIR; };
40 | ED6E757D25F51FE2006387CA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
41 | ED6E758125F51FE3006387CA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
42 | ED6E758425F51FE3006387CA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
43 | ED6E758625F51FE3006387CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | ED6E758725F51FE3006387CA /* upbitBar.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = upbitBar.entitlements; sourceTree = ""; };
45 | ED6E759C25F52C45006387CA /* CryptoAsset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoAsset.swift; sourceTree = ""; };
46 | ED6E75A125F52DE1006387CA /* UpbitServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpbitServices.swift; sourceTree = ""; };
47 | ED6E75A925F5325A006387CA /* Ticker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ticker.swift; sourceTree = ""; };
48 | ED6E75AC25F54617006387CA /* Cryptocurrency.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cryptocurrency.swift; sourceTree = ""; };
49 | ED6E75B325F54B6C006387CA /* UpbitAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpbitAPI.swift; sourceTree = ""; };
50 | ED6E765525F648E8006387CA /* SettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingViewController.swift; sourceTree = ""; };
51 | ED6E772025F67802006387CA /* UserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = ""; };
52 | ED6E772925F6836E006387CA /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; };
53 | ED6E772C25F689E0006387CA /* RefreshInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshInterval.swift; sourceTree = ""; };
54 | ED6E773525F68E8C006387CA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
55 | ED6E773825F68EAB006387CA /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Main.strings; sourceTree = ""; };
56 | ED6E773925F68EAB006387CA /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; };
57 | ED6E774025F68F14006387CA /* Localized.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Localized.swift; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | ED6E757725F51FE2006387CA /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | ED6E759425F5224B006387CA /* JWTComponents in Frameworks */,
66 | ED6E759925F522EC006387CA /* Then in Frameworks */,
67 | ED6E75A725F53056006387CA /* Logging in Frameworks */,
68 | ED6E765A25F64BC5006387CA /* SnapKit in Frameworks */,
69 | ED6E75B125F54B0E006387CA /* LaunchAtLogin in Frameworks */,
70 | ED6E759025F5204B006387CA /* Just in Frameworks */,
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | /* End PBXFrameworksBuildPhase section */
75 |
76 | /* Begin PBXGroup section */
77 | A7BC7B8426032DF800B2A6DB /* Constants */ = {
78 | isa = PBXGroup;
79 | children = (
80 | A7BC7B8526032E0000B2A6DB /* Constants.swift */,
81 | );
82 | path = Constants;
83 | sourceTree = "";
84 | };
85 | ED6E757125F51FE2006387CA = {
86 | isa = PBXGroup;
87 | children = (
88 | ED6E772F25F68E25006387CA /* Supporting Files */,
89 | ED6E757C25F51FE2006387CA /* Sources */,
90 | ED6E757B25F51FE2006387CA /* Products */,
91 | );
92 | sourceTree = "";
93 | };
94 | ED6E757B25F51FE2006387CA /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | ED6E757A25F51FE2006387CA /* upbitBar.app */,
98 | );
99 | name = Products;
100 | sourceTree = "";
101 | };
102 | ED6E757C25F51FE2006387CA /* Sources */ = {
103 | isa = PBXGroup;
104 | children = (
105 | A7BC7B8426032DF800B2A6DB /* Constants */,
106 | ED6E771A25F677D5006387CA /* Utils */,
107 | ED6E75A025F52DCF006387CA /* Networking */,
108 | ED6E759B25F52BD1006387CA /* Models */,
109 | ED6E757D25F51FE2006387CA /* AppDelegate.swift */,
110 | ED6E765525F648E8006387CA /* SettingViewController.swift */,
111 | );
112 | path = Sources;
113 | sourceTree = "";
114 | };
115 | ED6E759B25F52BD1006387CA /* Models */ = {
116 | isa = PBXGroup;
117 | children = (
118 | ED6E759C25F52C45006387CA /* CryptoAsset.swift */,
119 | ED6E75A925F5325A006387CA /* Ticker.swift */,
120 | ED6E75AC25F54617006387CA /* Cryptocurrency.swift */,
121 | ED6E772C25F689E0006387CA /* RefreshInterval.swift */,
122 | A7BC7B8926032E3000B2A6DB /* Market.swift */,
123 | );
124 | path = Models;
125 | sourceTree = "";
126 | };
127 | ED6E75A025F52DCF006387CA /* Networking */ = {
128 | isa = PBXGroup;
129 | children = (
130 | ED6E75A125F52DE1006387CA /* UpbitServices.swift */,
131 | ED6E75B325F54B6C006387CA /* UpbitAPI.swift */,
132 | );
133 | path = Networking;
134 | sourceTree = "";
135 | };
136 | ED6E771A25F677D5006387CA /* Utils */ = {
137 | isa = PBXGroup;
138 | children = (
139 | ED6E772025F67802006387CA /* UserInfo.swift */,
140 | ED6E772925F6836E006387CA /* Notifications.swift */,
141 | ED6E774025F68F14006387CA /* Localized.swift */,
142 | ED3BF34525F7C67A00F05BB5 /* Attributes.swift */,
143 | );
144 | path = Utils;
145 | sourceTree = "";
146 | };
147 | ED6E772F25F68E25006387CA /* Supporting Files */ = {
148 | isa = PBXGroup;
149 | children = (
150 | ED6E758125F51FE3006387CA /* Assets.xcassets */,
151 | ED6E758325F51FE3006387CA /* Main.storyboard */,
152 | ED6E758625F51FE3006387CA /* Info.plist */,
153 | ED6E758725F51FE3006387CA /* upbitBar.entitlements */,
154 | ED6E773625F68E8C006387CA /* Localizable.strings */,
155 | );
156 | path = "Supporting Files";
157 | sourceTree = "";
158 | };
159 | /* End PBXGroup section */
160 |
161 | /* Begin PBXNativeTarget section */
162 | ED6E757925F51FE2006387CA /* upbitBar */ = {
163 | isa = PBXNativeTarget;
164 | buildConfigurationList = ED6E758A25F51FE4006387CA /* Build configuration list for PBXNativeTarget "upbitBar" */;
165 | buildPhases = (
166 | ED6E757625F51FE2006387CA /* Sources */,
167 | ED3BF34D25F7F2F500F05BB5 /* LaunchAtLogin */,
168 | ED6E757725F51FE2006387CA /* Frameworks */,
169 | ED6E757825F51FE2006387CA /* Resources */,
170 | );
171 | buildRules = (
172 | );
173 | dependencies = (
174 | );
175 | name = upbitBar;
176 | packageProductDependencies = (
177 | ED6E758F25F5204B006387CA /* Just */,
178 | ED6E759325F5224B006387CA /* JWTComponents */,
179 | ED6E759825F522EC006387CA /* Then */,
180 | ED6E75A625F53056006387CA /* Logging */,
181 | ED6E75B025F54B0E006387CA /* LaunchAtLogin */,
182 | ED6E765925F64BC5006387CA /* SnapKit */,
183 | );
184 | productName = upbitBar;
185 | productReference = ED6E757A25F51FE2006387CA /* upbitBar.app */;
186 | productType = "com.apple.product-type.application";
187 | };
188 | /* End PBXNativeTarget section */
189 |
190 | /* Begin PBXProject section */
191 | ED6E757225F51FE2006387CA /* Project object */ = {
192 | isa = PBXProject;
193 | attributes = {
194 | LastSwiftUpdateCheck = 1240;
195 | LastUpgradeCheck = 1240;
196 | TargetAttributes = {
197 | ED6E757925F51FE2006387CA = {
198 | CreatedOnToolsVersion = 12.4;
199 | };
200 | };
201 | };
202 | buildConfigurationList = ED6E757525F51FE2006387CA /* Build configuration list for PBXProject "upbitBar" */;
203 | compatibilityVersion = "Xcode 9.3";
204 | developmentRegion = en;
205 | hasScannedForEncodings = 0;
206 | knownRegions = (
207 | en,
208 | Base,
209 | ko,
210 | );
211 | mainGroup = ED6E757125F51FE2006387CA;
212 | packageReferences = (
213 | ED6E758E25F5204B006387CA /* XCRemoteSwiftPackageReference "Just" */,
214 | ED6E759225F5224B006387CA /* XCRemoteSwiftPackageReference "JWTComponents" */,
215 | ED6E759725F522EC006387CA /* XCRemoteSwiftPackageReference "then" */,
216 | ED6E75A525F53056006387CA /* XCRemoteSwiftPackageReference "swift-log" */,
217 | ED6E75AF25F54B0E006387CA /* XCRemoteSwiftPackageReference "LaunchAtLogin" */,
218 | ED6E765825F64BC5006387CA /* XCRemoteSwiftPackageReference "SnapKit" */,
219 | );
220 | productRefGroup = ED6E757B25F51FE2006387CA /* Products */;
221 | projectDirPath = "";
222 | projectRoot = "";
223 | targets = (
224 | ED6E757925F51FE2006387CA /* upbitBar */,
225 | );
226 | };
227 | /* End PBXProject section */
228 |
229 | /* Begin PBXResourcesBuildPhase section */
230 | ED6E757825F51FE2006387CA /* Resources */ = {
231 | isa = PBXResourcesBuildPhase;
232 | buildActionMask = 2147483647;
233 | files = (
234 | ED6E758225F51FE3006387CA /* Assets.xcassets in Resources */,
235 | ED6E773425F68E8C006387CA /* Localizable.strings in Resources */,
236 | ED6E758525F51FE3006387CA /* Main.storyboard in Resources */,
237 | );
238 | runOnlyForDeploymentPostprocessing = 0;
239 | };
240 | /* End PBXResourcesBuildPhase section */
241 |
242 | /* Begin PBXShellScriptBuildPhase section */
243 | ED3BF34D25F7F2F500F05BB5 /* LaunchAtLogin */ = {
244 | isa = PBXShellScriptBuildPhase;
245 | buildActionMask = 2147483647;
246 | files = (
247 | );
248 | inputFileListPaths = (
249 | );
250 | inputPaths = (
251 | );
252 | name = LaunchAtLogin;
253 | outputFileListPaths = (
254 | );
255 | outputPaths = (
256 | );
257 | runOnlyForDeploymentPostprocessing = 0;
258 | shellPath = /bin/sh;
259 | shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${BUILT_PRODUCTS_DIR}/LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources/copy-helper-swiftpm.sh\"\n";
260 | };
261 | /* End PBXShellScriptBuildPhase section */
262 |
263 | /* Begin PBXSourcesBuildPhase section */
264 | ED6E757625F51FE2006387CA /* Sources */ = {
265 | isa = PBXSourcesBuildPhase;
266 | buildActionMask = 2147483647;
267 | files = (
268 | ED6E759D25F52C45006387CA /* CryptoAsset.swift in Sources */,
269 | ED6E75AD25F54617006387CA /* Cryptocurrency.swift in Sources */,
270 | ED6E772D25F689E0006387CA /* RefreshInterval.swift in Sources */,
271 | ED6E765625F648E8006387CA /* SettingViewController.swift in Sources */,
272 | ED6E772A25F6836E006387CA /* Notifications.swift in Sources */,
273 | ED6E75AA25F5325A006387CA /* Ticker.swift in Sources */,
274 | ED6E75B425F54B6C006387CA /* UpbitAPI.swift in Sources */,
275 | A7BC7B8626032E0000B2A6DB /* Constants.swift in Sources */,
276 | ED6E75A225F52DE1006387CA /* UpbitServices.swift in Sources */,
277 | A7BC7B8A26032E3000B2A6DB /* Market.swift in Sources */,
278 | ED6E774125F68F14006387CA /* Localized.swift in Sources */,
279 | ED6E772125F67802006387CA /* UserInfo.swift in Sources */,
280 | ED3BF34625F7C67A00F05BB5 /* Attributes.swift in Sources */,
281 | ED6E757E25F51FE2006387CA /* AppDelegate.swift in Sources */,
282 | );
283 | runOnlyForDeploymentPostprocessing = 0;
284 | };
285 | /* End PBXSourcesBuildPhase section */
286 |
287 | /* Begin PBXVariantGroup section */
288 | ED6E758325F51FE3006387CA /* Main.storyboard */ = {
289 | isa = PBXVariantGroup;
290 | children = (
291 | ED6E758425F51FE3006387CA /* Base */,
292 | ED6E773825F68EAB006387CA /* ko */,
293 | );
294 | name = Main.storyboard;
295 | sourceTree = "";
296 | };
297 | ED6E773625F68E8C006387CA /* Localizable.strings */ = {
298 | isa = PBXVariantGroup;
299 | children = (
300 | ED6E773525F68E8C006387CA /* en */,
301 | ED6E773925F68EAB006387CA /* ko */,
302 | );
303 | name = Localizable.strings;
304 | sourceTree = "";
305 | };
306 | /* End PBXVariantGroup section */
307 |
308 | /* Begin XCBuildConfiguration section */
309 | ED6E758825F51FE3006387CA /* Debug */ = {
310 | isa = XCBuildConfiguration;
311 | buildSettings = {
312 | ALWAYS_SEARCH_USER_PATHS = NO;
313 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
314 | CLANG_ANALYZER_NONNULL = YES;
315 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
317 | CLANG_CXX_LIBRARY = "libc++";
318 | CLANG_ENABLE_MODULES = YES;
319 | CLANG_ENABLE_OBJC_ARC = YES;
320 | CLANG_ENABLE_OBJC_WEAK = YES;
321 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
322 | CLANG_WARN_BOOL_CONVERSION = YES;
323 | CLANG_WARN_COMMA = YES;
324 | CLANG_WARN_CONSTANT_CONVERSION = YES;
325 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
326 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
327 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
328 | CLANG_WARN_EMPTY_BODY = YES;
329 | CLANG_WARN_ENUM_CONVERSION = YES;
330 | CLANG_WARN_INFINITE_RECURSION = YES;
331 | CLANG_WARN_INT_CONVERSION = YES;
332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
336 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
337 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
338 | CLANG_WARN_STRICT_PROTOTYPES = YES;
339 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
340 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
341 | CLANG_WARN_UNREACHABLE_CODE = YES;
342 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
343 | COPY_PHASE_STRIP = NO;
344 | DEBUG_INFORMATION_FORMAT = dwarf;
345 | ENABLE_STRICT_OBJC_MSGSEND = YES;
346 | ENABLE_TESTABILITY = YES;
347 | GCC_C_LANGUAGE_STANDARD = gnu11;
348 | GCC_DYNAMIC_NO_PIC = NO;
349 | GCC_NO_COMMON_BLOCKS = YES;
350 | GCC_OPTIMIZATION_LEVEL = 0;
351 | GCC_PREPROCESSOR_DEFINITIONS = (
352 | "DEBUG=1",
353 | "$(inherited)",
354 | );
355 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
356 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
357 | GCC_WARN_UNDECLARED_SELECTOR = YES;
358 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
359 | GCC_WARN_UNUSED_FUNCTION = YES;
360 | GCC_WARN_UNUSED_VARIABLE = YES;
361 | MACOSX_DEPLOYMENT_TARGET = 11.1;
362 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
363 | MTL_FAST_MATH = YES;
364 | ONLY_ACTIVE_ARCH = YES;
365 | SDKROOT = macosx;
366 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
367 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
368 | };
369 | name = Debug;
370 | };
371 | ED6E758925F51FE3006387CA /* Release */ = {
372 | isa = XCBuildConfiguration;
373 | buildSettings = {
374 | ALWAYS_SEARCH_USER_PATHS = NO;
375 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
376 | CLANG_ANALYZER_NONNULL = YES;
377 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
379 | CLANG_CXX_LIBRARY = "libc++";
380 | CLANG_ENABLE_MODULES = YES;
381 | CLANG_ENABLE_OBJC_ARC = YES;
382 | CLANG_ENABLE_OBJC_WEAK = YES;
383 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
384 | CLANG_WARN_BOOL_CONVERSION = YES;
385 | CLANG_WARN_COMMA = YES;
386 | CLANG_WARN_CONSTANT_CONVERSION = YES;
387 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
388 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
389 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
390 | CLANG_WARN_EMPTY_BODY = YES;
391 | CLANG_WARN_ENUM_CONVERSION = YES;
392 | CLANG_WARN_INFINITE_RECURSION = YES;
393 | CLANG_WARN_INT_CONVERSION = YES;
394 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
395 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
396 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
397 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
398 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
400 | CLANG_WARN_STRICT_PROTOTYPES = YES;
401 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
402 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
403 | CLANG_WARN_UNREACHABLE_CODE = YES;
404 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
405 | COPY_PHASE_STRIP = NO;
406 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
407 | ENABLE_NS_ASSERTIONS = NO;
408 | ENABLE_STRICT_OBJC_MSGSEND = YES;
409 | GCC_C_LANGUAGE_STANDARD = gnu11;
410 | GCC_NO_COMMON_BLOCKS = YES;
411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
413 | GCC_WARN_UNDECLARED_SELECTOR = YES;
414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
415 | GCC_WARN_UNUSED_FUNCTION = YES;
416 | GCC_WARN_UNUSED_VARIABLE = YES;
417 | MACOSX_DEPLOYMENT_TARGET = 11.1;
418 | MTL_ENABLE_DEBUG_INFO = NO;
419 | MTL_FAST_MATH = YES;
420 | SDKROOT = macosx;
421 | SWIFT_COMPILATION_MODE = wholemodule;
422 | SWIFT_OPTIMIZATION_LEVEL = "-O";
423 | };
424 | name = Release;
425 | };
426 | ED6E758B25F51FE4006387CA /* Debug */ = {
427 | isa = XCBuildConfiguration;
428 | buildSettings = {
429 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
430 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
431 | CODE_SIGN_ENTITLEMENTS = "Supporting Files/upbitBar.entitlements";
432 | CODE_SIGN_IDENTITY = "-";
433 | CODE_SIGN_STYLE = Automatic;
434 | COMBINE_HIDPI_IMAGES = YES;
435 | CURRENT_PROJECT_VERSION = 1;
436 | DEVELOPMENT_TEAM = U6GQL8JQMT;
437 | ENABLE_HARDENED_RUNTIME = YES;
438 | INFOPLIST_FILE = "Supporting Files/Info.plist";
439 | LD_RUNPATH_SEARCH_PATHS = (
440 | "$(inherited)",
441 | "@executable_path/../Frameworks",
442 | );
443 | MACOSX_DEPLOYMENT_TARGET = 10.15;
444 | MARKETING_VERSION = 1.0;
445 | PRODUCT_BUNDLE_IDENTIFIER = com.tmsae.upbitbar;
446 | PRODUCT_NAME = "$(TARGET_NAME)";
447 | SWIFT_VERSION = 5.0;
448 | };
449 | name = Debug;
450 | };
451 | ED6E758C25F51FE4006387CA /* Release */ = {
452 | isa = XCBuildConfiguration;
453 | buildSettings = {
454 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
455 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
456 | CODE_SIGN_ENTITLEMENTS = "Supporting Files/upbitBar.entitlements";
457 | CODE_SIGN_IDENTITY = "-";
458 | CODE_SIGN_STYLE = Automatic;
459 | COMBINE_HIDPI_IMAGES = YES;
460 | CURRENT_PROJECT_VERSION = 1;
461 | DEVELOPMENT_TEAM = U6GQL8JQMT;
462 | ENABLE_HARDENED_RUNTIME = YES;
463 | INFOPLIST_FILE = "Supporting Files/Info.plist";
464 | LD_RUNPATH_SEARCH_PATHS = (
465 | "$(inherited)",
466 | "@executable_path/../Frameworks",
467 | );
468 | MACOSX_DEPLOYMENT_TARGET = 10.15;
469 | MARKETING_VERSION = 1.0;
470 | PRODUCT_BUNDLE_IDENTIFIER = com.tmsae.upbitbar;
471 | PRODUCT_NAME = "$(TARGET_NAME)";
472 | SWIFT_VERSION = 5.0;
473 | };
474 | name = Release;
475 | };
476 | /* End XCBuildConfiguration section */
477 |
478 | /* Begin XCConfigurationList section */
479 | ED6E757525F51FE2006387CA /* Build configuration list for PBXProject "upbitBar" */ = {
480 | isa = XCConfigurationList;
481 | buildConfigurations = (
482 | ED6E758825F51FE3006387CA /* Debug */,
483 | ED6E758925F51FE3006387CA /* Release */,
484 | );
485 | defaultConfigurationIsVisible = 0;
486 | defaultConfigurationName = Release;
487 | };
488 | ED6E758A25F51FE4006387CA /* Build configuration list for PBXNativeTarget "upbitBar" */ = {
489 | isa = XCConfigurationList;
490 | buildConfigurations = (
491 | ED6E758B25F51FE4006387CA /* Debug */,
492 | ED6E758C25F51FE4006387CA /* Release */,
493 | );
494 | defaultConfigurationIsVisible = 0;
495 | defaultConfigurationName = Release;
496 | };
497 | /* End XCConfigurationList section */
498 |
499 | /* Begin XCRemoteSwiftPackageReference section */
500 | ED6E758E25F5204B006387CA /* XCRemoteSwiftPackageReference "Just" */ = {
501 | isa = XCRemoteSwiftPackageReference;
502 | repositoryURL = "https://github.com/dduan/Just";
503 | requirement = {
504 | kind = upToNextMajorVersion;
505 | minimumVersion = 0.8.0;
506 | };
507 | };
508 | ED6E759225F5224B006387CA /* XCRemoteSwiftPackageReference "JWTComponents" */ = {
509 | isa = XCRemoteSwiftPackageReference;
510 | repositoryURL = "https://github.com/couchdeveloper/JWTComponents";
511 | requirement = {
512 | kind = upToNextMajorVersion;
513 | minimumVersion = 0.4.0;
514 | };
515 | };
516 | ED6E759725F522EC006387CA /* XCRemoteSwiftPackageReference "then" */ = {
517 | isa = XCRemoteSwiftPackageReference;
518 | repositoryURL = "http://github.com/devxoul/then";
519 | requirement = {
520 | kind = upToNextMajorVersion;
521 | minimumVersion = 2.7.0;
522 | };
523 | };
524 | ED6E75A525F53056006387CA /* XCRemoteSwiftPackageReference "swift-log" */ = {
525 | isa = XCRemoteSwiftPackageReference;
526 | repositoryURL = "https://github.com/apple/swift-log";
527 | requirement = {
528 | kind = upToNextMajorVersion;
529 | minimumVersion = 1.4.2;
530 | };
531 | };
532 | ED6E75AF25F54B0E006387CA /* XCRemoteSwiftPackageReference "LaunchAtLogin" */ = {
533 | isa = XCRemoteSwiftPackageReference;
534 | repositoryURL = "https://github.com/sindresorhus/LaunchAtLogin";
535 | requirement = {
536 | kind = upToNextMajorVersion;
537 | minimumVersion = 4.0.0;
538 | };
539 | };
540 | ED6E765825F64BC5006387CA /* XCRemoteSwiftPackageReference "SnapKit" */ = {
541 | isa = XCRemoteSwiftPackageReference;
542 | repositoryURL = "https://github.com/SnapKit/SnapKit";
543 | requirement = {
544 | kind = upToNextMajorVersion;
545 | minimumVersion = 5.0.1;
546 | };
547 | };
548 | /* End XCRemoteSwiftPackageReference section */
549 |
550 | /* Begin XCSwiftPackageProductDependency section */
551 | ED6E758F25F5204B006387CA /* Just */ = {
552 | isa = XCSwiftPackageProductDependency;
553 | package = ED6E758E25F5204B006387CA /* XCRemoteSwiftPackageReference "Just" */;
554 | productName = Just;
555 | };
556 | ED6E759325F5224B006387CA /* JWTComponents */ = {
557 | isa = XCSwiftPackageProductDependency;
558 | package = ED6E759225F5224B006387CA /* XCRemoteSwiftPackageReference "JWTComponents" */;
559 | productName = JWTComponents;
560 | };
561 | ED6E759825F522EC006387CA /* Then */ = {
562 | isa = XCSwiftPackageProductDependency;
563 | package = ED6E759725F522EC006387CA /* XCRemoteSwiftPackageReference "then" */;
564 | productName = Then;
565 | };
566 | ED6E75A625F53056006387CA /* Logging */ = {
567 | isa = XCSwiftPackageProductDependency;
568 | package = ED6E75A525F53056006387CA /* XCRemoteSwiftPackageReference "swift-log" */;
569 | productName = Logging;
570 | };
571 | ED6E75B025F54B0E006387CA /* LaunchAtLogin */ = {
572 | isa = XCSwiftPackageProductDependency;
573 | package = ED6E75AF25F54B0E006387CA /* XCRemoteSwiftPackageReference "LaunchAtLogin" */;
574 | productName = LaunchAtLogin;
575 | };
576 | ED6E765925F64BC5006387CA /* SnapKit */ = {
577 | isa = XCSwiftPackageProductDependency;
578 | package = ED6E765825F64BC5006387CA /* XCRemoteSwiftPackageReference "SnapKit" */;
579 | productName = SnapKit;
580 | };
581 | /* End XCSwiftPackageProductDependency section */
582 | };
583 | rootObject = ED6E757225F51FE2006387CA /* Project object */;
584 | }
585 |
--------------------------------------------------------------------------------
/Supporting Files/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
--------------------------------------------------------------------------------