├── .github └── 1.png ├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── CHANGELOG.md ├── DOCS.md ├── Info.plist ├── LICENSE.md ├── Package.swift ├── README.md ├── Sources ├── StockCharts │ ├── CapsuleChart │ │ ├── CapsuleChartStyle.swift │ │ └── CapsuleChartView.swift │ ├── LineChart │ │ ├── Helpers │ │ │ ├── ChartLabel.swift │ │ │ ├── IndicatorPoint.swift │ │ │ ├── LinePath.swift │ │ │ └── LineView.swift │ │ ├── LineChartController.swift │ │ └── LineChartView.swift │ └── StockCharts.h ├── StockChartsTests │ ├── Info.plist │ └── StockChartsTests.swift ├── StockChartsWatchOS │ ├── Info.plist │ └── StockChartsWatchOS.h └── StockChartsWatchOSTests │ ├── Info.plist │ └── StockChartsWatchOSTests.swift └── StockCharts.xcodeproj ├── project.pbxproj └── xcshareddata └── xcschemes └── StockCharts.xcscheme /.github/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/denniscmcom/stock-charts/9bfefc3b3e86b7c937fabbafe2a77b78ab37701a/.github/1.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/xcode,macos,swift 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=xcode,macos,swift 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | ### Swift ### 35 | # Xcode 36 | # 37 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 38 | 39 | ## User settings 40 | xcuserdata/ 41 | 42 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 43 | *.xcscmblueprint 44 | *.xccheckout 45 | 46 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 47 | build/ 48 | DerivedData/ 49 | *.moved-aside 50 | *.pbxuser 51 | !default.pbxuser 52 | *.mode1v3 53 | !default.mode1v3 54 | *.mode2v3 55 | !default.mode2v3 56 | *.perspectivev3 57 | !default.perspectivev3 58 | 59 | ## Obj-C/Swift specific 60 | *.hmap 61 | 62 | ## App packaging 63 | *.ipa 64 | *.dSYM.zip 65 | *.dSYM 66 | 67 | ## Playgrounds 68 | timeline.xctimeline 69 | playground.xcworkspace 70 | 71 | # Swift Package Manager 72 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 73 | # Packages/ 74 | # Package.pins 75 | # Package.resolved 76 | # *.xcodeproj 77 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 78 | # hence it is not needed unless you have added a package configuration file to your project 79 | # .swiftpm 80 | 81 | .build/ 82 | 83 | # CocoaPods 84 | # We recommend against adding the Pods directory to your .gitignore. However 85 | # you should judge for yourself, the pros and cons are mentioned at: 86 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 87 | # Pods/ 88 | # Add this line if you want to avoid checking in source code from the Xcode workspace 89 | # *.xcworkspace 90 | 91 | # Carthage 92 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 93 | # Carthage/Checkouts 94 | 95 | Carthage/Build/ 96 | 97 | # Accio dependency management 98 | Dependencies/ 99 | .accio/ 100 | 101 | # fastlane 102 | # It is recommended to not store the screenshots in the git repo. 103 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 104 | # For more information about the recommended setup visit: 105 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 106 | 107 | fastlane/report.xml 108 | fastlane/Preview.html 109 | fastlane/screenshots/**/*.png 110 | fastlane/test_output 111 | 112 | # Code Injection 113 | # After new code Injection tools there's a generated folder /iOSInjectionProject 114 | # https://github.com/johnno1962/injectionforxcode 115 | 116 | iOSInjectionProject/ 117 | 118 | ### Xcode ### 119 | # Xcode 120 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 121 | 122 | 123 | 124 | 125 | ## Gcc Patch 126 | /*.gcno 127 | 128 | ### Xcode Patch ### 129 | *.xcodeproj/* 130 | !*.xcodeproj/project.pbxproj 131 | !*.xcodeproj/xcshareddata/ 132 | !*.xcworkspace/contents.xcworkspacedata 133 | **/xcshareddata/WorkspaceSettings.xcsettings 134 | 135 | # End of https://www.toptal.com/developers/gitignore/api/xcode,macos,swift 136 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Table of Contents 3 | 4 | 1. [2021-08-09 -> Version 1.2.0](#orgdbd1c4f) 5 | 2. [2021-07-17 -> Minor UI improvements](#org17d583f) 6 | 3. [2021-06-28 -> Change colors to SwiftUI native](#orge71a9c9) 7 | 4. [2021-06-27 -> WatchOS compatibility](#orgbc1f4da) 8 | 5. [2021-06-22 -> UI Chart label changer](#org68756eb) 9 | 6. [2021-06-16 -> Fix unwrap crash](#org460d505) 10 | 7. [2021-06-06 -> Fix bug color LineChartView on dragGesture](#org17e1907) 11 | 8. [2021-06-06 -> Fix `Index out of range` when data is empty](#org5ae752f) 12 | 9. [2021-06-05 -> Add CapsuleChart](#org14a9a79) 13 | 10. [2021-05-19 -> Fix builder issues](#org4f37163) 14 | 11. [2021-05-08 -> Fix warning `Modifying state during view update`](#orgb3b26d6) 15 | 12. [2021-05-08 -> Fix folder structure bug](#orgc348d6d) 16 | 13. [2021-05-07 -> Delete demo project](#org1c3026a) 17 | 14. [2021-05-07 -> v1.1](#org079f167) 18 | 15. [2021-04-30 -> v1.0](#org1235ab7) 19 | 16. [2021-05-28 -> v0.2-alpha](#org9285a3b) 20 | 17. [2021-05-28 -> v0.1-alpha](#org6f2747e) 21 | 22 | 23 | 24 | 25 | # 2021-08-09 -> Version 1.2.0 26 | 27 | Remove on push triggers 28 | 29 | 30 | 31 | 32 | # 2021-07-17 -> Minor UI improvements 33 | 34 | 35 | 36 | 37 | # 2021-06-28 -> Change colors to SwiftUI native 38 | 39 | 40 | 41 | 42 | # 2021-06-27 -> WatchOS compatibility 43 | 44 | 45 | 46 | 47 | # 2021-06-22 -> UI Chart label changer 48 | 49 | 50 | 51 | 52 | # 2021-06-16 -> Fix unwrap crash 53 | 54 | Fix crash when `path.currentPoint` was `nil` in `LinePath.swift` 55 | 56 | 57 | 58 | 59 | # 2021-06-06 -> Fix bug color LineChartView on dragGesture 60 | 61 | 62 | 63 | 64 | # 2021-06-06 -> Fix `Index out of range` when data is empty 65 | 66 | 67 | 68 | 69 | # 2021-06-05 -> Add CapsuleChart 70 | 71 | 72 | 73 | 74 | # 2021-05-19 -> Fix builder issues 75 | 76 | 77 | 78 | 79 | # 2021-05-08 -> Fix warning `Modifying state during view update` 80 | 81 | 82 | 83 | 84 | # 2021-05-08 -> Fix folder structure bug 85 | 86 | 87 | 88 | 89 | # 2021-05-07 -> Delete demo project 90 | 91 | 92 | 93 | 94 | # 2021-05-07 -> v1.1 95 | 96 | Add `dragGesture` argument 97 | 98 | 99 | 100 | 101 | # 2021-04-30 -> v1.0 102 | 103 | 104 | 105 | 106 | # 2021-05-28 -> v0.2-alpha 107 | 108 | 109 | 110 | 111 | # 2021-05-28 -> v0.1-alpha 112 | 113 | -------------------------------------------------------------------------------- /DOCS.md: -------------------------------------------------------------------------------- 1 | 2 | # Table of Contents 3 | 4 | 1. [Installation](#orgd9f2fd7) 5 | 2. [Demo app](#orgbd9420c) 6 | 3. [Usage](#org57f1418) 7 | 1. [Line chart](#org19fa053) 8 | 2. [Capsule chart](#orgc225fff) 9 | 1. [Example](#org71304cd) 10 | 11 | 12 | 13 | 14 | # Installation 15 | 16 | - In Xcode go to `File` -> `Swift packages` -> `Add package dependency` 17 | - Copy and paste `https://github.com/denniscmartin/stock-charts.git` 18 | 19 | 20 | 21 | 22 | # Demo app 23 | 24 | I've created an example app to show real use cases of this framework, check -> [Trades app](https://github.com/denniscmartin/trades-demo) 25 | 26 | 27 | 28 | 29 | # Usage 30 | 31 | import StockCharts 32 | 33 | 34 | 35 | 36 | ## Line chart 37 | 38 | let lineChartController = LineChartController(prices: [Double]) 39 | LineChartView(lineChartController: lineChartController) 40 | 41 | You can customise the line chart with `LineChartController` 42 | 43 | LineChartController( 44 | prices: [Double], 45 | dates: [String]?, // format: yy-MM-dd 46 | hours: [String]?, // has to correspond to dates 47 | labelColor: Color, 48 | indicatorPointColor: Color, 49 | showingIndicatorLineColor: Color, 50 | flatTrendLineColor: Color, 51 | uptrendLineColor: Color, 52 | downtrendLineColor: Color, 53 | dragGesture: Bool 54 | ) 55 | 56 | To enable the drag gesture set `dragGesture` to `true` in the `LineChartController` 57 | 58 | LineChartView( 59 | lineChartController: 60 | LineChartController( 61 | prices: [Double], 62 | dragGesture: true 63 | ) 64 | ) 65 | 66 | 67 | 68 | 69 | ## Capsule chart 70 | 71 | CapsuleChartView(percentageOfWidth: CGFloat) 72 | // percentageOfWidth: must be 0 <= x <= 1 73 | 74 | 75 | 76 | 77 | ### Example 78 | 79 | import SwiftUI 80 | import StockCharts 81 | 82 | struct ContentView: View { 83 | var body: some View { 84 | RoundedRectangle(cornerRadius: 25) 85 | .frame(width: 400, height: 120) 86 | .foregroundColor(.white) 87 | .shadow(color: Color(.gray).opacity(0.15), radius: 10) 88 | .overlay( 89 | VStack(alignment: .leading) { 90 | Text("Dennis Concepcion") 91 | .font(.title3) 92 | .fontWeight(.semibold) 93 | 94 | Text("Random guy") 95 | 96 | CapsuleChartView(percentageOfWidth: 0.6, style: CapsuleChartStyle(capsuleColor: Color.blue)) 97 | .padding(.top) 98 | } 99 | .padding() 100 | ) 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Dennis Concepción Martín 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 | 23 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | import PackageDescription 4 | 5 | /* 6 | https://swift.org/package-manager/ 7 | */ 8 | 9 | let package = Package( 10 | name: "StockCharts", 11 | platforms: [ 12 | .iOS(.v14), .watchOS(.v7) 13 | ], 14 | products: [ 15 | .library( 16 | name: "StockCharts", 17 | targets: ["StockCharts"]), 18 | ], 19 | dependencies: [ 20 | 21 | ], 22 | targets: [ 23 | .target( 24 | name: "StockCharts", 25 | dependencies: []), 26 | .testTarget( 27 | name: "StockChartsTests", 28 | dependencies: ["StockCharts"]), 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # stock-charts 3 | 4 | StockCharts for SwiftUI - Display interactive stock charts easily 🎉 | Product Hunt 5 | 6 | This project is now deprecated in favor of the [Apple’s native framework](https://developer.apple.com/documentation/charts). At the time of archiving this project, it has accumulated 98 stars and 11 forks on Github. 7 | 8 | StockCharts is a library to create intertactive charts in SwiftUI. 9 | 10 | ## Installation 11 | In Xcode go to File -> Swift packages -> Add package dependency 12 | Copy and paste https://github.com/denniscmartin/stock-charts.git 13 | I’ve created a demo app using StockCharts called Trades. Check out the code in my Github 14 | 15 | ## Usage 16 | 17 | ```swift 18 | import StockCharts 19 | ``` 20 | 21 | ### Line chart 22 | 23 | ```swift 24 | let lineChartController = LineChartController(prices: [Double]) 25 | LineChartView(lineChartController: lineChartController) 26 | ``` 27 | 28 | You can customise the line chart with LineChartController 29 | 30 | ```swift 31 | LineChartController( 32 | prices: [Double], 33 | dates: [String]?, // format: yy-MM-dd 34 | hours: [String]?, // has to correspond to dates 35 | labelColor: Color, 36 | indicatorPointColor: Color, 37 | showingIndicatorLineColor: Color, 38 | flatTrendLineColor: Color, 39 | uptrendLineColor: Color, 40 | downtrendLineColor: Color, 41 | dragGesture: Bool 42 | ) 43 | ``` 44 | 45 | To enable the drag gesture set dragGesture to true in the LineChartController 46 | 47 | ```swift 48 | LineChartView( 49 | lineChartController: 50 | LineChartController( 51 | prices: [Double], 52 | dragGesture: true 53 | ) 54 | ) 55 | ``` 56 | 57 | ### Capsule chart 58 | 59 | ```swift 60 | CapsuleChartView(percentageOfWidth: CGFloat) 61 | // percentageOfWidth: must be 0 <= x <= 1 62 | import SwiftUI 63 | import StockCharts 64 | 65 | struct ContentView: View { 66 | var body: some View { 67 | RoundedRectangle(cornerRadius: 25) 68 | .frame(width: 400, height: 120) 69 | .foregroundColor(.white) 70 | .shadow(color: Color(.gray).opacity(0.15), radius: 10) 71 | .overlay( 72 | VStack(alignment: .leading) { 73 | Text("Dennis Concepcion") 74 | .font(.title3) 75 | .fontWeight(.semibold) 76 | 77 | Text("Random guy") 78 | 79 | CapsuleChartView(percentageOfWidth: 0.6, style: CapsuleChartStyle(capsuleColor: Color.blue)) 80 | .padding(.top) 81 | } 82 | .padding() 83 | ) 84 | } 85 | } 86 | ``` -------------------------------------------------------------------------------- /Sources/StockCharts/CapsuleChart/CapsuleChartStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CapsuleChartStyle.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 04/07/2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public class CapsuleChartStyle { 11 | public var capsuleColor: Color 12 | 13 | public init(capsuleColor: Color) { 14 | self.capsuleColor = capsuleColor 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Sources/StockCharts/CapsuleChart/CapsuleChartView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CapsuleChartView.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 5/6/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct CapsuleChartView: View { 11 | public var percentageOfWidth: CGFloat 12 | public var capsuleChartStyle: CapsuleChartStyle 13 | 14 | public init(percentageOfWidth: CGFloat, style: CapsuleChartStyle) { 15 | self.percentageOfWidth = percentageOfWidth 16 | self.capsuleChartStyle = style 17 | } 18 | 19 | public var body: some View { 20 | GeometryReader { proxy in 21 | ZStack(alignment: .leading) { 22 | Group { 23 | Capsule() 24 | .foregroundColor(Color.gray) 25 | .opacity(0.2) 26 | 27 | Capsule() 28 | .foregroundColor(capsuleChartStyle.capsuleColor) 29 | .frame(width: proxy.size.width * percentageOfWidth) 30 | } 31 | .frame(height: 10) 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/StockCharts/LineChart/Helpers/ChartLabel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartLabel.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct ChartLabel: View { 11 | public var lineChartController: LineChartController 12 | 13 | @Binding var indexPosition: Int // Data point position 14 | 15 | public var body: some View { 16 | HStack { 17 | if let dates = lineChartController.dates { 18 | let date = formatStringDate(dates[indexPosition]) 19 | Text(date) 20 | .opacity(0.5) 21 | } 22 | 23 | if let hours = lineChartController.hours { 24 | let hour = hours[indexPosition] 25 | Text(hour) 26 | .opacity(0.5) 27 | } 28 | 29 | Text("\(lineChartController.prices[indexPosition], specifier: "%.2f")") 30 | .foregroundColor(lineChartController.labelColor) 31 | } 32 | } 33 | 34 | /* 35 | Take string in format yy-MM-dd (2021-01-01) and transform it 36 | to long default string format 37 | */ 38 | public func formatStringDate(_ stringDate: String) -> String { 39 | let dateFormatter = DateFormatter() 40 | dateFormatter.dateFormat = "yy-MM-dd" 41 | let date = dateFormatter.date(from: stringDate) 42 | 43 | // Format date to the final format 44 | dateFormatter.dateStyle = .long 45 | let finalDate = dateFormatter.string(from: date!) 46 | 47 | return finalDate 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/StockCharts/LineChart/Helpers/IndicatorPoint.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndicatorPoint.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct IndicatorPoint: View { 11 | public var lineChartController: LineChartController 12 | 13 | public var body: some View { 14 | Circle() 15 | .frame(width: 20, height: 20) 16 | .foregroundColor(lineChartController.indicatorPointColor) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/StockCharts/LineChart/Helpers/LinePath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LinePath.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct LinePath: Shape { 11 | public var data: [Double] 12 | public var (width, height): (CGFloat, CGFloat) 13 | 14 | @Binding var pathPoints: [CGPoint] 15 | 16 | public func path(in rect: CGRect) -> Path { 17 | var path = Path() 18 | var pathPoints = [CGPoint]() 19 | 20 | let normalizedData = normalize(data) 21 | let widthBetweenDataPoints = Double(width) / Double(normalizedData.count - 1) // Remove first point 22 | let initialPoint = normalizedData[0] * Double(height) 23 | var x: Double = 0 24 | 25 | path.move(to: CGPoint(x: x, y: initialPoint)) 26 | for y in normalizedData { 27 | if normalizedData.firstIndex(of: y) != 0 { // Skip first point 28 | x += widthBetweenDataPoints 29 | let y = y * Double(height) 30 | path.addLine(to: CGPoint(x: x, y: y)) 31 | } 32 | 33 | // Append current point to an array. Later will be used for Drag Gesture 34 | pathPoints.append(path.currentPoint ?? CGPoint(x: 0, y: 0)) 35 | } 36 | 37 | DispatchQueue.main.async { 38 | self.pathPoints = pathPoints 39 | } 40 | 41 | return path 42 | } 43 | 44 | /* 45 | Get data -> normalize it -> 0 <= output <= 1 46 | */ 47 | public func normalize(_ data: [Double]) -> [Double] { 48 | var normalData = [Double]() 49 | let min = data.min()! 50 | let max = data.max()! 51 | 52 | for value in data { 53 | let normal = (value - min) / (max - min) 54 | normalData.append(normal) 55 | } 56 | 57 | return normalData 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /Sources/StockCharts/LineChart/Helpers/LineView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LineView.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct LineView: View { 11 | public var lineChartController: LineChartController 12 | 13 | @Binding var showingIndicators: Bool 14 | @Binding var indexPosition: Int 15 | @State var IndicatorPointPosition: CGPoint = .zero 16 | @State var pathPoints = [CGPoint]() 17 | 18 | public var body: some View { 19 | ZStack { 20 | GeometryReader { proxy in 21 | LinePath(data: lineChartController.prices, width: proxy.size.width, height: proxy.size.height, pathPoints: $pathPoints) 22 | .stroke(colorLine(), lineWidth: 2) 23 | } 24 | 25 | if showingIndicators { 26 | IndicatorPoint(lineChartController: lineChartController) 27 | .position(x: IndicatorPointPosition.x, y: IndicatorPointPosition.y) 28 | } 29 | } 30 | .rotationEffect(.degrees(180), anchor: .center) 31 | .rotation3DEffect(.degrees(180), axis: (x: 0.0, y: 1.0, z: 0.0)) 32 | .contentShape(Rectangle()) // Control tappable area 33 | .gesture(lineChartController.dragGesture ? 34 | LongPressGesture(minimumDuration: 0.2) 35 | .sequenced(before: DragGesture(minimumDistance: 0, coordinateSpace: .local)) 36 | .onChanged({ value in // Get value of the gesture 37 | switch value { 38 | case .second(true, let drag): 39 | if let longPressLocation = drag?.location { 40 | dragGesture(longPressLocation) 41 | } 42 | default: 43 | break 44 | } 45 | }) 46 | // Hide indicator when finish 47 | .onEnded({ value in 48 | self.showingIndicators = false 49 | }) 50 | : nil // On dragGesture = false 51 | ) 52 | } 53 | 54 | /* 55 | Color path depending on data. 56 | */ 57 | public func colorLine() -> Color { 58 | var color = lineChartController.uptrendLineColor 59 | 60 | if showingIndicators { 61 | color = lineChartController.showingIndicatorLineColor 62 | } else if lineChartController.prices.first! > lineChartController.prices.last! { 63 | color = lineChartController.downtrendLineColor 64 | } else if lineChartController.prices.first! == lineChartController.prices.last! { 65 | color = lineChartController.flatTrendLineColor 66 | } 67 | 68 | return color 69 | } 70 | 71 | /* 72 | When the user drag on Path -> Modifiy indicator point to move it on the path accordingly 73 | */ 74 | public func dragGesture(_ longPressLocation: CGPoint) { 75 | let (closestXPoint, closestYPoint, yPointIndex) = getClosestValueFrom(longPressLocation, inData: pathPoints) 76 | self.IndicatorPointPosition.x = closestXPoint 77 | self.IndicatorPointPosition.y = closestYPoint 78 | self.showingIndicators = true 79 | self.indexPosition = yPointIndex 80 | } 81 | 82 | /* 83 | First, search the closest X point in Path from the tapped location. 84 | Then, find the correspondent Y point in Path. 85 | */ 86 | public func getClosestValueFrom(_ value: CGPoint, inData: [CGPoint]) -> (CGFloat, CGFloat, Int) { 87 | let touchPoint: (CGFloat, CGFloat) = (value.x, value.y) 88 | let xPathPoints = inData.map { $0.x } 89 | let yPathPoints = inData.map { $0.y } 90 | 91 | // Closest X value 92 | let closestXPoint = xPathPoints.enumerated().min( by: { abs($0.1 - touchPoint.0) < abs($1.1 - touchPoint.0) } )! 93 | let closestYPointIndex = xPathPoints.firstIndex(of: closestXPoint.element)! 94 | let closestYPoint = yPathPoints[closestYPointIndex] 95 | 96 | // Index of the closest points in the array 97 | let yPointIndex = yPathPoints.firstIndex(of: closestYPoint)! 98 | 99 | return (closestXPoint.element, closestYPoint, yPointIndex) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Sources/StockCharts/LineChart/LineChartController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LineChartController.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 5/8/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public class LineChartController { 11 | 12 | // MARK: - Data 13 | public var prices: [Double] 14 | public var dates: [String]? 15 | public var hours: [String]? 16 | 17 | // MARK: - Style 18 | public var labelColor: Color 19 | public var indicatorPointColor: Color 20 | public var showingIndicatorLineColor: Color 21 | public var flatTrendLineColor: Color 22 | public var uptrendLineColor: Color 23 | public var downtrendLineColor: Color 24 | 25 | // MARK: - Interactions 26 | public var dragGesture: Bool = false 27 | 28 | public init( 29 | prices: [Double], 30 | dates: [String]? = nil, 31 | hours: [String]? = nil, 32 | 33 | labelColor: Color = .blue, 34 | indicatorPointColor: Color = .blue, 35 | showingIndicatorLineColor: Color = .blue, 36 | flatTrendLineColor: Color = .purple, 37 | uptrendLineColor: Color = .green, 38 | downtrendLineColor: Color = .red, 39 | 40 | dragGesture: Bool = false 41 | ) { 42 | self.prices = prices 43 | self.dates = dates 44 | self.hours = hours 45 | 46 | self.labelColor = labelColor 47 | self.indicatorPointColor = indicatorPointColor 48 | self.showingIndicatorLineColor = showingIndicatorLineColor 49 | self.flatTrendLineColor = flatTrendLineColor 50 | self.uptrendLineColor = uptrendLineColor 51 | self.downtrendLineColor = downtrendLineColor 52 | 53 | self.dragGesture = dragGesture 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/StockCharts/LineChart/LineChartView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LineChartView.swift 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct LineChartView: View { 11 | public var lineChartController: LineChartController 12 | 13 | @State var showingIndicators = false 14 | @State var indexPosition = Int() 15 | 16 | public init(lineChartController: LineChartController) { 17 | self.lineChartController = lineChartController 18 | } 19 | 20 | public var body: some View { 21 | if lineChartController.prices.isEmpty { 22 | 23 | } else { 24 | VStack { 25 | if lineChartController.dragGesture { 26 | ChartLabel(lineChartController: lineChartController, indexPosition: $indexPosition) 27 | .opacity(showingIndicators ? 1: 0) 28 | } 29 | 30 | LineView( 31 | lineChartController: lineChartController, 32 | showingIndicators: $showingIndicators, 33 | indexPosition: $indexPosition 34 | ) 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/StockCharts/StockCharts.h: -------------------------------------------------------------------------------- 1 | // 2 | // StockCharts.h 3 | // StockCharts 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for StockCharts. 11 | FOUNDATION_EXPORT double StockChartsVersionNumber; 12 | 13 | //! Project version string for StockCharts. 14 | FOUNDATION_EXPORT const unsigned char StockChartsVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sources/StockChartsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sources/StockChartsTests/StockChartsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StockChartsTests.swift 3 | // StockChartsTests 4 | // 5 | // Created by Dennis Concepción Martín on 30/4/21. 6 | // 7 | 8 | import XCTest 9 | @testable import StockCharts 10 | 11 | class StockChartsTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Sources/StockChartsWatchOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sources/StockChartsWatchOS/StockChartsWatchOS.h: -------------------------------------------------------------------------------- 1 | // 2 | // StockChartsWatchOS.h 3 | // StockChartsWatchOS 4 | // 5 | // Created by Dennis Concepción Martín on 5/8/21. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for StockChartsWatchOS. 11 | FOUNDATION_EXPORT double StockChartsWatchOSVersionNumber; 12 | 13 | //! Project version string for StockChartsWatchOS. 14 | FOUNDATION_EXPORT const unsigned char StockChartsWatchOSVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sources/StockChartsWatchOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sources/StockChartsWatchOSTests/StockChartsWatchOSTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StockChartsWatchOSTests.swift 3 | // StockChartsWatchOSTests 4 | // 5 | // Created by Dennis Concepción Martín on 5/8/21. 6 | // 7 | 8 | import XCTest 9 | @testable import StockChartsWatchOS 10 | 11 | class StockChartsWatchOSTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /StockCharts.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 950857AE266BDF62005357BA /* CapsuleChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950857AD266BDF62005357BA /* CapsuleChartView.swift */; }; 11 | 954AA3A026920D060006FD14 /* CapsuleChartStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954AA39F26920D060006FD14 /* CapsuleChartStyle.swift */; }; 12 | 954CEBEB26BBEEEB00B6E989 /* StockChartsWatchOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 954CEBE226BBEEEB00B6E989 /* StockChartsWatchOS.framework */; }; 13 | 954CEBF026BBEEEB00B6E989 /* StockChartsWatchOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954CEBEF26BBEEEB00B6E989 /* StockChartsWatchOSTests.swift */; }; 14 | 954CEBF226BBEEEB00B6E989 /* StockChartsWatchOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 954CEBE426BBEEEB00B6E989 /* StockChartsWatchOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 954CEBF926BBEF3100B6E989 /* LineChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770B9F263C590C003FA924 /* LineChartView.swift */; }; 16 | 954CEBFB26BBEF3800B6E989 /* ChartLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA2263C5934003FA924 /* ChartLabel.swift */; }; 17 | 954CEBFC26BBEF3B00B6E989 /* IndicatorPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA4263C594C003FA924 /* IndicatorPoint.swift */; }; 18 | 954CEBFD26BBEF3E00B6E989 /* LinePath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA6263C596E003FA924 /* LinePath.swift */; }; 19 | 954CEBFE26BBEF4200B6E989 /* LineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA8263C5988003FA924 /* LineView.swift */; }; 20 | 954CEBFF26BBEF4700B6E989 /* CapsuleChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950857AD266BDF62005357BA /* CapsuleChartView.swift */; }; 21 | 954CEC0026BBEF4A00B6E989 /* CapsuleChartStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954AA39F26920D060006FD14 /* CapsuleChartStyle.swift */; }; 22 | 95770B8B263C57B5003FA924 /* StockCharts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95770B81263C57B5003FA924 /* StockCharts.framework */; }; 23 | 95770B90263C57B5003FA924 /* StockChartsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770B8F263C57B5003FA924 /* StockChartsTests.swift */; }; 24 | 95770B92263C57B5003FA924 /* StockCharts.h in Headers */ = {isa = PBXBuildFile; fileRef = 95770B84263C57B5003FA924 /* StockCharts.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | 95770BA0263C590C003FA924 /* LineChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770B9F263C590C003FA924 /* LineChartView.swift */; }; 26 | 95770BA3263C5934003FA924 /* ChartLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA2263C5934003FA924 /* ChartLabel.swift */; }; 27 | 95770BA5263C594C003FA924 /* IndicatorPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA4263C594C003FA924 /* IndicatorPoint.swift */; }; 28 | 95770BA7263C596E003FA924 /* LinePath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA6263C596E003FA924 /* LinePath.swift */; }; 29 | 95770BA9263C5988003FA924 /* LineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95770BA8263C5988003FA924 /* LineView.swift */; }; 30 | 958E4D3226BC3776003177DD /* LineChartController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958E4D3126BC3776003177DD /* LineChartController.swift */; }; 31 | 958E4D3326BC3776003177DD /* LineChartController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958E4D3126BC3776003177DD /* LineChartController.swift */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | 954CEBEC26BBEEEB00B6E989 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = 95770B78263C57B5003FA924 /* Project object */; 38 | proxyType = 1; 39 | remoteGlobalIDString = 954CEBE126BBEEEB00B6E989; 40 | remoteInfo = StockChartsWatchOS; 41 | }; 42 | 95770B8C263C57B5003FA924 /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = 95770B78263C57B5003FA924 /* Project object */; 45 | proxyType = 1; 46 | remoteGlobalIDString = 95770B80263C57B5003FA924; 47 | remoteInfo = StockCharts; 48 | }; 49 | /* End PBXContainerItemProxy section */ 50 | 51 | /* Begin PBXFileReference section */ 52 | 950857AD266BDF62005357BA /* CapsuleChartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleChartView.swift; sourceTree = ""; }; 53 | 954AA39F26920D060006FD14 /* CapsuleChartStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleChartStyle.swift; sourceTree = ""; }; 54 | 954CEBE226BBEEEB00B6E989 /* StockChartsWatchOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StockChartsWatchOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 954CEBE426BBEEEB00B6E989 /* StockChartsWatchOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StockChartsWatchOS.h; sourceTree = ""; }; 56 | 954CEBE526BBEEEB00B6E989 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 954CEBEA26BBEEEB00B6E989 /* StockChartsWatchOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StockChartsWatchOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 954CEBEF26BBEEEB00B6E989 /* StockChartsWatchOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockChartsWatchOSTests.swift; sourceTree = ""; }; 59 | 954CEBF126BBEEEB00B6E989 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 95770B81263C57B5003FA924 /* StockCharts.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StockCharts.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 95770B84263C57B5003FA924 /* StockCharts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StockCharts.h; sourceTree = ""; }; 62 | 95770B85263C57B5003FA924 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | 95770B8A263C57B5003FA924 /* StockChartsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StockChartsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 95770B8F263C57B5003FA924 /* StockChartsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockChartsTests.swift; sourceTree = ""; }; 65 | 95770B91263C57B5003FA924 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 95770B9F263C590C003FA924 /* LineChartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartView.swift; sourceTree = ""; }; 67 | 95770BA2263C5934003FA924 /* ChartLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartLabel.swift; sourceTree = ""; }; 68 | 95770BA4263C594C003FA924 /* IndicatorPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndicatorPoint.swift; sourceTree = ""; }; 69 | 95770BA6263C596E003FA924 /* LinePath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinePath.swift; sourceTree = ""; }; 70 | 95770BA8263C5988003FA924 /* LineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineView.swift; sourceTree = ""; }; 71 | 95770BAA263C59A9003FA924 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 72 | 958E4D3126BC3776003177DD /* LineChartController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartController.swift; sourceTree = ""; }; 73 | /* End PBXFileReference section */ 74 | 75 | /* Begin PBXFrameworksBuildPhase section */ 76 | 954CEBDF26BBEEEB00B6E989 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | 954CEBE726BBEEEB00B6E989 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | 954CEBEB26BBEEEB00B6E989 /* StockChartsWatchOS.framework in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 95770B7E263C57B5003FA924 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | 95770B87263C57B5003FA924 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 95770B8B263C57B5003FA924 /* StockCharts.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXFrameworksBuildPhase section */ 107 | 108 | /* Begin PBXGroup section */ 109 | 950857AC266BDF48005357BA /* CapsuleChart */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 950857AD266BDF62005357BA /* CapsuleChartView.swift */, 113 | 954AA39F26920D060006FD14 /* CapsuleChartStyle.swift */, 114 | ); 115 | path = CapsuleChart; 116 | sourceTree = ""; 117 | }; 118 | 954CEBE326BBEEEB00B6E989 /* StockChartsWatchOS */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 954CEBE426BBEEEB00B6E989 /* StockChartsWatchOS.h */, 122 | 954CEBE526BBEEEB00B6E989 /* Info.plist */, 123 | ); 124 | path = StockChartsWatchOS; 125 | sourceTree = ""; 126 | }; 127 | 954CEBEE26BBEEEB00B6E989 /* StockChartsWatchOSTests */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 954CEBEF26BBEEEB00B6E989 /* StockChartsWatchOSTests.swift */, 131 | 954CEBF126BBEEEB00B6E989 /* Info.plist */, 132 | ); 133 | path = StockChartsWatchOSTests; 134 | sourceTree = ""; 135 | }; 136 | 95770B77263C57B5003FA924 = { 137 | isa = PBXGroup; 138 | children = ( 139 | 95770BAA263C59A9003FA924 /* Package.swift */, 140 | 95770B85263C57B5003FA924 /* Info.plist */, 141 | 95770B9B263C57CA003FA924 /* Sources */, 142 | 95770B82263C57B5003FA924 /* Products */, 143 | ); 144 | sourceTree = ""; 145 | }; 146 | 95770B82263C57B5003FA924 /* Products */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 95770B81263C57B5003FA924 /* StockCharts.framework */, 150 | 95770B8A263C57B5003FA924 /* StockChartsTests.xctest */, 151 | 954CEBE226BBEEEB00B6E989 /* StockChartsWatchOS.framework */, 152 | 954CEBEA26BBEEEB00B6E989 /* StockChartsWatchOSTests.xctest */, 153 | ); 154 | name = Products; 155 | sourceTree = ""; 156 | }; 157 | 95770B83263C57B5003FA924 /* StockCharts */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 95770B84263C57B5003FA924 /* StockCharts.h */, 161 | 95770B9E263C58F4003FA924 /* LineChart */, 162 | 950857AC266BDF48005357BA /* CapsuleChart */, 163 | ); 164 | path = StockCharts; 165 | sourceTree = ""; 166 | }; 167 | 95770B8E263C57B5003FA924 /* StockChartsTests */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 95770B8F263C57B5003FA924 /* StockChartsTests.swift */, 171 | 95770B91263C57B5003FA924 /* Info.plist */, 172 | ); 173 | path = StockChartsTests; 174 | sourceTree = ""; 175 | }; 176 | 95770B9B263C57CA003FA924 /* Sources */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 95770B83263C57B5003FA924 /* StockCharts */, 180 | 95770B8E263C57B5003FA924 /* StockChartsTests */, 181 | 954CEBE326BBEEEB00B6E989 /* StockChartsWatchOS */, 182 | 954CEBEE26BBEEEB00B6E989 /* StockChartsWatchOSTests */, 183 | ); 184 | path = Sources; 185 | sourceTree = ""; 186 | }; 187 | 95770B9E263C58F4003FA924 /* LineChart */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 95770B9F263C590C003FA924 /* LineChartView.swift */, 191 | 958E4D3126BC3776003177DD /* LineChartController.swift */, 192 | 95770BA1263C5927003FA924 /* Helpers */, 193 | ); 194 | path = LineChart; 195 | sourceTree = ""; 196 | }; 197 | 95770BA1263C5927003FA924 /* Helpers */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 95770BA2263C5934003FA924 /* ChartLabel.swift */, 201 | 95770BA4263C594C003FA924 /* IndicatorPoint.swift */, 202 | 95770BA6263C596E003FA924 /* LinePath.swift */, 203 | 95770BA8263C5988003FA924 /* LineView.swift */, 204 | ); 205 | path = Helpers; 206 | sourceTree = ""; 207 | }; 208 | /* End PBXGroup section */ 209 | 210 | /* Begin PBXHeadersBuildPhase section */ 211 | 954CEBDD26BBEEEB00B6E989 /* Headers */ = { 212 | isa = PBXHeadersBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | 954CEBF226BBEEEB00B6E989 /* StockChartsWatchOS.h in Headers */, 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | }; 219 | 95770B7C263C57B5003FA924 /* Headers */ = { 220 | isa = PBXHeadersBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | 95770B92263C57B5003FA924 /* StockCharts.h in Headers */, 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | /* End PBXHeadersBuildPhase section */ 228 | 229 | /* Begin PBXNativeTarget section */ 230 | 954CEBE126BBEEEB00B6E989 /* StockChartsWatchOS */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = 954CEBF726BBEEEB00B6E989 /* Build configuration list for PBXNativeTarget "StockChartsWatchOS" */; 233 | buildPhases = ( 234 | 954CEBDD26BBEEEB00B6E989 /* Headers */, 235 | 954CEBDE26BBEEEB00B6E989 /* Sources */, 236 | 954CEBDF26BBEEEB00B6E989 /* Frameworks */, 237 | 954CEBE026BBEEEB00B6E989 /* Resources */, 238 | ); 239 | buildRules = ( 240 | ); 241 | dependencies = ( 242 | ); 243 | name = StockChartsWatchOS; 244 | productName = StockChartsWatchOS; 245 | productReference = 954CEBE226BBEEEB00B6E989 /* StockChartsWatchOS.framework */; 246 | productType = "com.apple.product-type.framework"; 247 | }; 248 | 954CEBE926BBEEEB00B6E989 /* StockChartsWatchOSTests */ = { 249 | isa = PBXNativeTarget; 250 | buildConfigurationList = 954CEBF826BBEEEB00B6E989 /* Build configuration list for PBXNativeTarget "StockChartsWatchOSTests" */; 251 | buildPhases = ( 252 | 954CEBE626BBEEEB00B6E989 /* Sources */, 253 | 954CEBE726BBEEEB00B6E989 /* Frameworks */, 254 | 954CEBE826BBEEEB00B6E989 /* Resources */, 255 | ); 256 | buildRules = ( 257 | ); 258 | dependencies = ( 259 | 954CEBED26BBEEEB00B6E989 /* PBXTargetDependency */, 260 | ); 261 | name = StockChartsWatchOSTests; 262 | productName = StockChartsWatchOSTests; 263 | productReference = 954CEBEA26BBEEEB00B6E989 /* StockChartsWatchOSTests.xctest */; 264 | productType = "com.apple.product-type.bundle.unit-test"; 265 | }; 266 | 95770B80263C57B5003FA924 /* StockCharts */ = { 267 | isa = PBXNativeTarget; 268 | buildConfigurationList = 95770B95263C57B5003FA924 /* Build configuration list for PBXNativeTarget "StockCharts" */; 269 | buildPhases = ( 270 | 95770B7C263C57B5003FA924 /* Headers */, 271 | 95770B7D263C57B5003FA924 /* Sources */, 272 | 95770B7E263C57B5003FA924 /* Frameworks */, 273 | 95770B7F263C57B5003FA924 /* Resources */, 274 | ); 275 | buildRules = ( 276 | ); 277 | dependencies = ( 278 | ); 279 | name = StockCharts; 280 | productName = StockCharts; 281 | productReference = 95770B81263C57B5003FA924 /* StockCharts.framework */; 282 | productType = "com.apple.product-type.framework"; 283 | }; 284 | 95770B89263C57B5003FA924 /* StockChartsTests */ = { 285 | isa = PBXNativeTarget; 286 | buildConfigurationList = 95770B98263C57B5003FA924 /* Build configuration list for PBXNativeTarget "StockChartsTests" */; 287 | buildPhases = ( 288 | 95770B86263C57B5003FA924 /* Sources */, 289 | 95770B87263C57B5003FA924 /* Frameworks */, 290 | 95770B88263C57B5003FA924 /* Resources */, 291 | ); 292 | buildRules = ( 293 | ); 294 | dependencies = ( 295 | 95770B8D263C57B5003FA924 /* PBXTargetDependency */, 296 | ); 297 | name = StockChartsTests; 298 | productName = StockChartsTests; 299 | productReference = 95770B8A263C57B5003FA924 /* StockChartsTests.xctest */; 300 | productType = "com.apple.product-type.bundle.unit-test"; 301 | }; 302 | /* End PBXNativeTarget section */ 303 | 304 | /* Begin PBXProject section */ 305 | 95770B78263C57B5003FA924 /* Project object */ = { 306 | isa = PBXProject; 307 | attributes = { 308 | LastSwiftUpdateCheck = 1250; 309 | LastUpgradeCheck = 1250; 310 | TargetAttributes = { 311 | 954CEBE126BBEEEB00B6E989 = { 312 | CreatedOnToolsVersion = 12.5.1; 313 | }; 314 | 954CEBE926BBEEEB00B6E989 = { 315 | CreatedOnToolsVersion = 12.5.1; 316 | }; 317 | 95770B80263C57B5003FA924 = { 318 | CreatedOnToolsVersion = 12.5; 319 | LastSwiftMigration = 1250; 320 | }; 321 | 95770B89263C57B5003FA924 = { 322 | CreatedOnToolsVersion = 12.5; 323 | }; 324 | }; 325 | }; 326 | buildConfigurationList = 95770B7B263C57B5003FA924 /* Build configuration list for PBXProject "StockCharts" */; 327 | compatibilityVersion = "Xcode 9.3"; 328 | developmentRegion = en; 329 | hasScannedForEncodings = 0; 330 | knownRegions = ( 331 | en, 332 | Base, 333 | ); 334 | mainGroup = 95770B77263C57B5003FA924; 335 | productRefGroup = 95770B82263C57B5003FA924 /* Products */; 336 | projectDirPath = ""; 337 | projectRoot = ""; 338 | targets = ( 339 | 95770B80263C57B5003FA924 /* StockCharts */, 340 | 95770B89263C57B5003FA924 /* StockChartsTests */, 341 | 954CEBE126BBEEEB00B6E989 /* StockChartsWatchOS */, 342 | 954CEBE926BBEEEB00B6E989 /* StockChartsWatchOSTests */, 343 | ); 344 | }; 345 | /* End PBXProject section */ 346 | 347 | /* Begin PBXResourcesBuildPhase section */ 348 | 954CEBE026BBEEEB00B6E989 /* Resources */ = { 349 | isa = PBXResourcesBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | 954CEBE826BBEEEB00B6E989 /* Resources */ = { 356 | isa = PBXResourcesBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | }; 362 | 95770B7F263C57B5003FA924 /* Resources */ = { 363 | isa = PBXResourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | 95770B88263C57B5003FA924 /* Resources */ = { 370 | isa = PBXResourcesBuildPhase; 371 | buildActionMask = 2147483647; 372 | files = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | /* End PBXResourcesBuildPhase section */ 377 | 378 | /* Begin PBXSourcesBuildPhase section */ 379 | 954CEBDE26BBEEEB00B6E989 /* Sources */ = { 380 | isa = PBXSourcesBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | 954CEBFD26BBEF3E00B6E989 /* LinePath.swift in Sources */, 384 | 954CEC0026BBEF4A00B6E989 /* CapsuleChartStyle.swift in Sources */, 385 | 954CEBFE26BBEF4200B6E989 /* LineView.swift in Sources */, 386 | 958E4D3326BC3776003177DD /* LineChartController.swift in Sources */, 387 | 954CEBF926BBEF3100B6E989 /* LineChartView.swift in Sources */, 388 | 954CEBFC26BBEF3B00B6E989 /* IndicatorPoint.swift in Sources */, 389 | 954CEBFB26BBEF3800B6E989 /* ChartLabel.swift in Sources */, 390 | 954CEBFF26BBEF4700B6E989 /* CapsuleChartView.swift in Sources */, 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | 954CEBE626BBEEEB00B6E989 /* Sources */ = { 395 | isa = PBXSourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | 954CEBF026BBEEEB00B6E989 /* StockChartsWatchOSTests.swift in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | 95770B7D263C57B5003FA924 /* Sources */ = { 403 | isa = PBXSourcesBuildPhase; 404 | buildActionMask = 2147483647; 405 | files = ( 406 | 95770BA0263C590C003FA924 /* LineChartView.swift in Sources */, 407 | 95770BA3263C5934003FA924 /* ChartLabel.swift in Sources */, 408 | 954AA3A026920D060006FD14 /* CapsuleChartStyle.swift in Sources */, 409 | 95770BA7263C596E003FA924 /* LinePath.swift in Sources */, 410 | 958E4D3226BC3776003177DD /* LineChartController.swift in Sources */, 411 | 950857AE266BDF62005357BA /* CapsuleChartView.swift in Sources */, 412 | 95770BA9263C5988003FA924 /* LineView.swift in Sources */, 413 | 95770BA5263C594C003FA924 /* IndicatorPoint.swift in Sources */, 414 | ); 415 | runOnlyForDeploymentPostprocessing = 0; 416 | }; 417 | 95770B86263C57B5003FA924 /* Sources */ = { 418 | isa = PBXSourcesBuildPhase; 419 | buildActionMask = 2147483647; 420 | files = ( 421 | 95770B90263C57B5003FA924 /* StockChartsTests.swift in Sources */, 422 | ); 423 | runOnlyForDeploymentPostprocessing = 0; 424 | }; 425 | /* End PBXSourcesBuildPhase section */ 426 | 427 | /* Begin PBXTargetDependency section */ 428 | 954CEBED26BBEEEB00B6E989 /* PBXTargetDependency */ = { 429 | isa = PBXTargetDependency; 430 | target = 954CEBE126BBEEEB00B6E989 /* StockChartsWatchOS */; 431 | targetProxy = 954CEBEC26BBEEEB00B6E989 /* PBXContainerItemProxy */; 432 | }; 433 | 95770B8D263C57B5003FA924 /* PBXTargetDependency */ = { 434 | isa = PBXTargetDependency; 435 | target = 95770B80263C57B5003FA924 /* StockCharts */; 436 | targetProxy = 95770B8C263C57B5003FA924 /* PBXContainerItemProxy */; 437 | }; 438 | /* End PBXTargetDependency section */ 439 | 440 | /* Begin XCBuildConfiguration section */ 441 | 954CEBF326BBEEEB00B6E989 /* Debug */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | APPLICATION_EXTENSION_API_ONLY = YES; 445 | CODE_SIGN_STYLE = Automatic; 446 | DEFINES_MODULE = YES; 447 | DEVELOPMENT_TEAM = MTX83R5H8X; 448 | DYLIB_COMPATIBILITY_VERSION = 1; 449 | DYLIB_CURRENT_VERSION = 1; 450 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 451 | INFOPLIST_FILE = Sources/StockChartsWatchOS/Info.plist; 452 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 453 | LD_RUNPATH_SEARCH_PATHS = ( 454 | "$(inherited)", 455 | "@executable_path/Frameworks", 456 | "@loader_path/Frameworks", 457 | ); 458 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockChartsWatchOS; 459 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 460 | SDKROOT = watchos; 461 | SKIP_INSTALL = YES; 462 | SWIFT_VERSION = 5.0; 463 | TARGETED_DEVICE_FAMILY = 4; 464 | WATCHOS_DEPLOYMENT_TARGET = 7.4; 465 | }; 466 | name = Debug; 467 | }; 468 | 954CEBF426BBEEEB00B6E989 /* Release */ = { 469 | isa = XCBuildConfiguration; 470 | buildSettings = { 471 | APPLICATION_EXTENSION_API_ONLY = YES; 472 | CODE_SIGN_STYLE = Automatic; 473 | DEFINES_MODULE = YES; 474 | DEVELOPMENT_TEAM = MTX83R5H8X; 475 | DYLIB_COMPATIBILITY_VERSION = 1; 476 | DYLIB_CURRENT_VERSION = 1; 477 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 478 | INFOPLIST_FILE = Sources/StockChartsWatchOS/Info.plist; 479 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 480 | LD_RUNPATH_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "@executable_path/Frameworks", 483 | "@loader_path/Frameworks", 484 | ); 485 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockChartsWatchOS; 486 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 487 | SDKROOT = watchos; 488 | SKIP_INSTALL = YES; 489 | SWIFT_VERSION = 5.0; 490 | TARGETED_DEVICE_FAMILY = 4; 491 | WATCHOS_DEPLOYMENT_TARGET = 7.4; 492 | }; 493 | name = Release; 494 | }; 495 | 954CEBF526BBEEEB00B6E989 /* Debug */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 499 | CODE_SIGN_STYLE = Automatic; 500 | DEVELOPMENT_TEAM = MTX83R5H8X; 501 | INFOPLIST_FILE = Sources/StockChartsWatchOSTests/Info.plist; 502 | LD_RUNPATH_SEARCH_PATHS = ( 503 | "$(inherited)", 504 | "@executable_path/Frameworks", 505 | "@loader_path/Frameworks", 506 | ); 507 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockChartsWatchOSTests; 508 | PRODUCT_NAME = "$(TARGET_NAME)"; 509 | SDKROOT = watchos; 510 | SWIFT_VERSION = 5.0; 511 | TARGETED_DEVICE_FAMILY = 4; 512 | WATCHOS_DEPLOYMENT_TARGET = 7.4; 513 | }; 514 | name = Debug; 515 | }; 516 | 954CEBF626BBEEEB00B6E989 /* Release */ = { 517 | isa = XCBuildConfiguration; 518 | buildSettings = { 519 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 520 | CODE_SIGN_STYLE = Automatic; 521 | DEVELOPMENT_TEAM = MTX83R5H8X; 522 | INFOPLIST_FILE = Sources/StockChartsWatchOSTests/Info.plist; 523 | LD_RUNPATH_SEARCH_PATHS = ( 524 | "$(inherited)", 525 | "@executable_path/Frameworks", 526 | "@loader_path/Frameworks", 527 | ); 528 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockChartsWatchOSTests; 529 | PRODUCT_NAME = "$(TARGET_NAME)"; 530 | SDKROOT = watchos; 531 | SWIFT_VERSION = 5.0; 532 | TARGETED_DEVICE_FAMILY = 4; 533 | WATCHOS_DEPLOYMENT_TARGET = 7.4; 534 | }; 535 | name = Release; 536 | }; 537 | 95770B93263C57B5003FA924 /* Debug */ = { 538 | isa = XCBuildConfiguration; 539 | buildSettings = { 540 | ALWAYS_SEARCH_USER_PATHS = NO; 541 | CLANG_ANALYZER_NONNULL = YES; 542 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 543 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 544 | CLANG_CXX_LIBRARY = "libc++"; 545 | CLANG_ENABLE_MODULES = YES; 546 | CLANG_ENABLE_OBJC_ARC = YES; 547 | CLANG_ENABLE_OBJC_WEAK = YES; 548 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 549 | CLANG_WARN_BOOL_CONVERSION = YES; 550 | CLANG_WARN_COMMA = YES; 551 | CLANG_WARN_CONSTANT_CONVERSION = YES; 552 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 553 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 554 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 555 | CLANG_WARN_EMPTY_BODY = YES; 556 | CLANG_WARN_ENUM_CONVERSION = YES; 557 | CLANG_WARN_INFINITE_RECURSION = YES; 558 | CLANG_WARN_INT_CONVERSION = YES; 559 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 560 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 561 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 562 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 563 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 564 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 565 | CLANG_WARN_STRICT_PROTOTYPES = YES; 566 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 567 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 568 | CLANG_WARN_UNREACHABLE_CODE = YES; 569 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 570 | CODE_SIGN_IDENTITY = ""; 571 | COPY_PHASE_STRIP = NO; 572 | CURRENT_PROJECT_VERSION = 1; 573 | DEBUG_INFORMATION_FORMAT = dwarf; 574 | DEVELOPMENT_TEAM = MTX83R5H8X; 575 | ENABLE_STRICT_OBJC_MSGSEND = YES; 576 | ENABLE_TESTABILITY = YES; 577 | GCC_C_LANGUAGE_STANDARD = gnu11; 578 | GCC_DYNAMIC_NO_PIC = NO; 579 | GCC_NO_COMMON_BLOCKS = YES; 580 | GCC_OPTIMIZATION_LEVEL = 0; 581 | GCC_PREPROCESSOR_DEFINITIONS = ( 582 | "DEBUG=1", 583 | "$(inherited)", 584 | ); 585 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 586 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 587 | GCC_WARN_UNDECLARED_SELECTOR = YES; 588 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 589 | GCC_WARN_UNUSED_FUNCTION = YES; 590 | GCC_WARN_UNUSED_VARIABLE = YES; 591 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 592 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 593 | MTL_FAST_MATH = YES; 594 | ONLY_ACTIVE_ARCH = YES; 595 | SDKROOT = iphoneos; 596 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 597 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 598 | VERSIONING_SYSTEM = "apple-generic"; 599 | VERSION_INFO_PREFIX = ""; 600 | }; 601 | name = Debug; 602 | }; 603 | 95770B94263C57B5003FA924 /* Release */ = { 604 | isa = XCBuildConfiguration; 605 | buildSettings = { 606 | ALWAYS_SEARCH_USER_PATHS = NO; 607 | CLANG_ANALYZER_NONNULL = YES; 608 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 609 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 610 | CLANG_CXX_LIBRARY = "libc++"; 611 | CLANG_ENABLE_MODULES = YES; 612 | CLANG_ENABLE_OBJC_ARC = YES; 613 | CLANG_ENABLE_OBJC_WEAK = YES; 614 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 615 | CLANG_WARN_BOOL_CONVERSION = YES; 616 | CLANG_WARN_COMMA = YES; 617 | CLANG_WARN_CONSTANT_CONVERSION = YES; 618 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 619 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 620 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 621 | CLANG_WARN_EMPTY_BODY = YES; 622 | CLANG_WARN_ENUM_CONVERSION = YES; 623 | CLANG_WARN_INFINITE_RECURSION = YES; 624 | CLANG_WARN_INT_CONVERSION = YES; 625 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 626 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 627 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 628 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 629 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 630 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 631 | CLANG_WARN_STRICT_PROTOTYPES = YES; 632 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 633 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 634 | CLANG_WARN_UNREACHABLE_CODE = YES; 635 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 636 | CODE_SIGN_IDENTITY = ""; 637 | COPY_PHASE_STRIP = NO; 638 | CURRENT_PROJECT_VERSION = 1; 639 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 640 | DEVELOPMENT_TEAM = MTX83R5H8X; 641 | ENABLE_NS_ASSERTIONS = NO; 642 | ENABLE_STRICT_OBJC_MSGSEND = YES; 643 | GCC_C_LANGUAGE_STANDARD = gnu11; 644 | GCC_NO_COMMON_BLOCKS = YES; 645 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 646 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 647 | GCC_WARN_UNDECLARED_SELECTOR = YES; 648 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 649 | GCC_WARN_UNUSED_FUNCTION = YES; 650 | GCC_WARN_UNUSED_VARIABLE = YES; 651 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 652 | MTL_ENABLE_DEBUG_INFO = NO; 653 | MTL_FAST_MATH = YES; 654 | SDKROOT = iphoneos; 655 | SWIFT_COMPILATION_MODE = wholemodule; 656 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 657 | VALIDATE_PRODUCT = YES; 658 | VERSIONING_SYSTEM = "apple-generic"; 659 | VERSION_INFO_PREFIX = ""; 660 | }; 661 | name = Release; 662 | }; 663 | 95770B96263C57B5003FA924 /* Debug */ = { 664 | isa = XCBuildConfiguration; 665 | buildSettings = { 666 | CLANG_ENABLE_MODULES = YES; 667 | CODE_SIGN_IDENTITY = ""; 668 | CODE_SIGN_STYLE = Manual; 669 | DEFINES_MODULE = YES; 670 | DEVELOPMENT_TEAM = ""; 671 | DYLIB_COMPATIBILITY_VERSION = 1; 672 | DYLIB_CURRENT_VERSION = 1; 673 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 674 | INFOPLIST_FILE = Info.plist; 675 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 676 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 677 | LD_RUNPATH_SEARCH_PATHS = ( 678 | "$(inherited)", 679 | "@executable_path/Frameworks", 680 | "@loader_path/Frameworks", 681 | ); 682 | MARKETING_VERSION = 1.0; 683 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockCharts; 684 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 685 | PROVISIONING_PROFILE_SPECIFIER = ""; 686 | SKIP_INSTALL = YES; 687 | SUPPORTS_MACCATALYST = NO; 688 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 689 | SWIFT_VERSION = 5.0; 690 | TARGETED_DEVICE_FAMILY = "1,2"; 691 | }; 692 | name = Debug; 693 | }; 694 | 95770B97263C57B5003FA924 /* Release */ = { 695 | isa = XCBuildConfiguration; 696 | buildSettings = { 697 | CLANG_ENABLE_MODULES = YES; 698 | CODE_SIGN_IDENTITY = ""; 699 | CODE_SIGN_STYLE = Manual; 700 | DEFINES_MODULE = YES; 701 | DEVELOPMENT_TEAM = ""; 702 | DYLIB_COMPATIBILITY_VERSION = 1; 703 | DYLIB_CURRENT_VERSION = 1; 704 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 705 | INFOPLIST_FILE = Info.plist; 706 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 707 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 708 | LD_RUNPATH_SEARCH_PATHS = ( 709 | "$(inherited)", 710 | "@executable_path/Frameworks", 711 | "@loader_path/Frameworks", 712 | ); 713 | MARKETING_VERSION = 1.0; 714 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockCharts; 715 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 716 | PROVISIONING_PROFILE_SPECIFIER = ""; 717 | SKIP_INSTALL = YES; 718 | SUPPORTS_MACCATALYST = NO; 719 | SWIFT_VERSION = 5.0; 720 | TARGETED_DEVICE_FAMILY = "1,2"; 721 | }; 722 | name = Release; 723 | }; 724 | 95770B99263C57B5003FA924 /* Debug */ = { 725 | isa = XCBuildConfiguration; 726 | buildSettings = { 727 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 728 | CODE_SIGN_IDENTITY = "iPhone Developer"; 729 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; 730 | CODE_SIGN_STYLE = Manual; 731 | DEVELOPMENT_TEAM = ""; 732 | INFOPLIST_FILE = Tests/StockChartsTests/Info.plist; 733 | LD_RUNPATH_SEARCH_PATHS = ( 734 | "$(inherited)", 735 | "@executable_path/Frameworks", 736 | "@loader_path/Frameworks", 737 | ); 738 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockChartsTests; 739 | PRODUCT_NAME = "$(TARGET_NAME)"; 740 | PROVISIONING_PROFILE_SPECIFIER = ""; 741 | "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; 742 | SWIFT_VERSION = 5.0; 743 | TARGETED_DEVICE_FAMILY = "1,2"; 744 | }; 745 | name = Debug; 746 | }; 747 | 95770B9A263C57B5003FA924 /* Release */ = { 748 | isa = XCBuildConfiguration; 749 | buildSettings = { 750 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 751 | CODE_SIGN_IDENTITY = "iPhone Developer"; 752 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; 753 | CODE_SIGN_STYLE = Manual; 754 | DEVELOPMENT_TEAM = ""; 755 | INFOPLIST_FILE = Tests/StockChartsTests/Info.plist; 756 | LD_RUNPATH_SEARCH_PATHS = ( 757 | "$(inherited)", 758 | "@executable_path/Frameworks", 759 | "@loader_path/Frameworks", 760 | ); 761 | PRODUCT_BUNDLE_IDENTIFIER = io.dennistech.StockChartsTests; 762 | PRODUCT_NAME = "$(TARGET_NAME)"; 763 | PROVISIONING_PROFILE_SPECIFIER = ""; 764 | "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; 765 | SWIFT_VERSION = 5.0; 766 | TARGETED_DEVICE_FAMILY = "1,2"; 767 | }; 768 | name = Release; 769 | }; 770 | /* End XCBuildConfiguration section */ 771 | 772 | /* Begin XCConfigurationList section */ 773 | 954CEBF726BBEEEB00B6E989 /* Build configuration list for PBXNativeTarget "StockChartsWatchOS" */ = { 774 | isa = XCConfigurationList; 775 | buildConfigurations = ( 776 | 954CEBF326BBEEEB00B6E989 /* Debug */, 777 | 954CEBF426BBEEEB00B6E989 /* Release */, 778 | ); 779 | defaultConfigurationIsVisible = 0; 780 | defaultConfigurationName = Release; 781 | }; 782 | 954CEBF826BBEEEB00B6E989 /* Build configuration list for PBXNativeTarget "StockChartsWatchOSTests" */ = { 783 | isa = XCConfigurationList; 784 | buildConfigurations = ( 785 | 954CEBF526BBEEEB00B6E989 /* Debug */, 786 | 954CEBF626BBEEEB00B6E989 /* Release */, 787 | ); 788 | defaultConfigurationIsVisible = 0; 789 | defaultConfigurationName = Release; 790 | }; 791 | 95770B7B263C57B5003FA924 /* Build configuration list for PBXProject "StockCharts" */ = { 792 | isa = XCConfigurationList; 793 | buildConfigurations = ( 794 | 95770B93263C57B5003FA924 /* Debug */, 795 | 95770B94263C57B5003FA924 /* Release */, 796 | ); 797 | defaultConfigurationIsVisible = 0; 798 | defaultConfigurationName = Release; 799 | }; 800 | 95770B95263C57B5003FA924 /* Build configuration list for PBXNativeTarget "StockCharts" */ = { 801 | isa = XCConfigurationList; 802 | buildConfigurations = ( 803 | 95770B96263C57B5003FA924 /* Debug */, 804 | 95770B97263C57B5003FA924 /* Release */, 805 | ); 806 | defaultConfigurationIsVisible = 0; 807 | defaultConfigurationName = Release; 808 | }; 809 | 95770B98263C57B5003FA924 /* Build configuration list for PBXNativeTarget "StockChartsTests" */ = { 810 | isa = XCConfigurationList; 811 | buildConfigurations = ( 812 | 95770B99263C57B5003FA924 /* Debug */, 813 | 95770B9A263C57B5003FA924 /* Release */, 814 | ); 815 | defaultConfigurationIsVisible = 0; 816 | defaultConfigurationName = Release; 817 | }; 818 | /* End XCConfigurationList section */ 819 | }; 820 | rootObject = 95770B78263C57B5003FA924 /* Project object */; 821 | } 822 | -------------------------------------------------------------------------------- /StockCharts.xcodeproj/xcshareddata/xcschemes/StockCharts.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | --------------------------------------------------------------------------------