├── .gitignore ├── images ├── demo.gif ├── icon.png └── preference.png ├── Scre ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ ├── Icon-128.png │ │ ├── Icon-16.png │ │ ├── Icon-256.png │ │ ├── Icon-257.png │ │ ├── Icon-32.png │ │ ├── Icon-33.png │ │ ├── Icon-512.png │ │ ├── Icon-513.png │ │ ├── Icon-64.png │ │ ├── Icon-1024.png │ │ └── Contents.json ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── Scre.entitlements ├── Application.swift ├── Model │ ├── FrameRate.swift │ ├── TimerHolder.swift │ ├── PixelSize.swift │ ├── GIFConveter.swift │ └── ScreenRecorder.swift ├── Util │ ├── Utils.swift │ ├── Config.swift │ ├── NSWindow+Extensions.swift │ └── WindowServer.swift ├── Info.plist ├── View │ ├── SettingsView.swift │ └── MainView.swift └── AppDelegate.swift ├── Podfile ├── Scre.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── shintaro.katafuchi.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── shintaro.katafuchi.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── xcshareddata │ └── xcschemes │ │ └── Scre.xcscheme └── project.pbxproj ├── Scre.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Podfile.lock ├── CHANGELOG.md ├── ScreTests ├── Info.plist └── ScreTests.swift ├── ScreUITests ├── Info.plist └── ScreUITests.swift ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Pods/ 2 | Scre.xcworkspace/xcuserdata/ 3 | .DS_Store -------------------------------------------------------------------------------- /images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/images/demo.gif -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/images/icon.png -------------------------------------------------------------------------------- /images/preference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/images/preference.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Scre/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-128.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-16.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-256.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-257.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-257.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-32.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-33.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-512.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-513.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-513.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-64.png -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre/Assets.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | target 'Scre' do 2 | use_frameworks! 3 | pod "Regift" 4 | 5 | target 'ScreTests' do 6 | inherit! :search_paths 7 | end 8 | 9 | target 'ScreUITests' do 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Scre.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Scre.xcodeproj/xcuserdata/shintaro.katafuchi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Scre.xcodeproj/project.xcworkspace/xcuserdata/shintaro.katafuchi.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hotchemi/Scre/HEAD/Scre.xcodeproj/project.xcworkspace/xcuserdata/shintaro.katafuchi.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Scre.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Regift (1.6.0) 3 | 4 | DEPENDENCIES: 5 | - Regift 6 | 7 | SPEC REPOS: 8 | trunk: 9 | - Regift 10 | 11 | SPEC CHECKSUMS: 12 | Regift: a7c1a7e377c60bfc34301d6f532e099e5ae109a8 13 | 14 | PODFILE CHECKSUM: 399285fd0af35a126e4a9881ad289a493b33cc90 15 | 16 | COCOAPODS: 1.10.0 17 | -------------------------------------------------------------------------------- /Scre.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Scre.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ChangeLog 2 | 3 | - 0.2 2021/03/13 4 | - Update: [FPS support](https://github.com/hotchemi/Scre/commit/5a535e91b20b401b746026315e5ced10e0afb1da) 5 | - Fix: [disable record button during start and stop](https://github.com/hotchemi/Scre/pull/5) 6 | - Fix: [initial frame could be zero](https://github.com/hotchemi/Scre/pull/4) 7 | - 0.1 2021/03/11 8 | - Initial release! -------------------------------------------------------------------------------- /Scre/Scre.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.assets.movies.read-write 8 | 9 | com.apple.security.files.user-selected.read-write 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Scre/Application.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct Application: App { 5 | @NSApplicationDelegateAdaptor(AppDelegate.self) private var delegate 6 | 7 | var body: some Scene { 8 | WindowGroup { 9 | MainView() 10 | } 11 | Settings { 12 | SettingsView() 13 | } 14 | .commands { 15 | // disable creating new window 16 | CommandGroup(replacing: CommandGroupPlacement.newItem) { 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Scre/Model/FrameRate.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum FrameRate: Int, CaseIterable { 4 | case high 5 | case medium 6 | case low 7 | 8 | var frameRate: Int { 9 | switch self { 10 | case .high: 11 | return 30 12 | case .medium: 13 | return 15 14 | case .low: 15 | return 8 16 | } 17 | } 18 | 19 | var label: String { 20 | switch self { 21 | case .high: 22 | return "High(\(frameRate))" 23 | case .medium: 24 | return "Middle(\(frameRate))" 25 | case .low: 26 | return "Low(\(frameRate))" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ScreTests/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 | -------------------------------------------------------------------------------- /ScreUITests/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 | -------------------------------------------------------------------------------- /Scre/Util/Utils.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | struct Utils { 4 | static let formatter: DateFormatter = { 5 | let formatter = DateFormatter() 6 | formatter.dateFormat = "yyyy-MM-dd HH.mm.ss" 7 | return formatter 8 | }() 9 | 10 | static func recordFrame(window: NSWindow?) -> CGRect { 11 | guard let window = window else { 12 | return CGRect.zero 13 | } 14 | let lineWidth: CGFloat = 2 15 | let titleHeight: CGFloat = 12 16 | let someValue: CGFloat = 20 17 | return CGRect(x: window.frame.origin.x + lineWidth, 18 | y: window.frame.origin.y + titleHeight + someValue + lineWidth, 19 | width: window.frame.size.width - lineWidth * 2, 20 | height: window.frame.size.height - 40 - someValue - lineWidth) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Scre/Model/TimerHolder.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import Combine 3 | 4 | class TimerHolder : ObservableObject { 5 | @Published var navigationTitle = "" 6 | private var timer : Timer? 7 | private var count = 0 8 | private var startDate: Date? 9 | 10 | func start() { 11 | timer?.invalidate() 12 | count = 0 13 | timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [self] _ in 14 | self.count += 1 15 | self.navigationTitle = self.createTimeString(count) 16 | } 17 | } 18 | 19 | private func createTimeString(_ seconds: Int) -> String { 20 | let m = (seconds / 60) % 60 21 | let s = seconds % 60 22 | return String(format: "%02u:%02u", m, s) 23 | } 24 | 25 | func stop() { 26 | timer?.invalidate() 27 | count = 0 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Scre/Model/PixelSize.swift: -------------------------------------------------------------------------------- 1 | import AVFoundation 2 | 3 | enum PixelSize: Int, CaseIterable { 4 | case original 5 | case high 6 | case medium 7 | case low 8 | 9 | var preset: AVCaptureSession.Preset? { 10 | switch self { 11 | case .original: 12 | return nil 13 | case .high: 14 | return AVCaptureSession.Preset.high 15 | case .medium: 16 | return AVCaptureSession.Preset.medium 17 | case .low: 18 | return AVCaptureSession.Preset.low 19 | } 20 | } 21 | 22 | var label: String { 23 | switch self { 24 | case .original: 25 | return "Original" 26 | case .high: 27 | return "High" 28 | case .medium: 29 | return "Middle" 30 | case .low: 31 | return "Low" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Scre.xcodeproj/xcuserdata/shintaro.katafuchi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Scre.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 4 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9F3B5F6825E28DB80084A6B9 16 | 17 | primary 18 | 19 | 20 | 9F3B5F7A25E28DB90084A6B9 21 | 22 | primary 23 | 24 | 25 | 9F3B5F8525E28DB90084A6B9 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Scre/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 | 0.1 19 | CFBundleVersion 20 | 1 21 | LSMinimumSystemVersion 22 | $(MACOSX_DEPLOYMENT_TARGET) 23 | 24 | 25 | -------------------------------------------------------------------------------- /ScreTests/ScreTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScreTests.swift 3 | // ScreTests 4 | // 5 | // Created by Shintaro Katafuchi on 2021/02/21. 6 | // 7 | 8 | import XCTest 9 | @testable import Scre 10 | 11 | class ScreTests: 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Shintaro Katafuchi 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scre 2 | 3 |

4 | 5 |

6 | 7 | A lightweight screen recorder macOS application written in SwiftUI. 8 | 9 | ## Demo 10 | 11 |

12 | 13 |

14 | 15 | ## Install 16 | 17 | You can use [homebrew-cask](https://github.com/Homebrew/homebrew-cask) or download from [release](https://github.com/hotchemi/Scre/releases) page. 18 | 19 | ```sh 20 | brew tap hotchemi/tap 21 | brew install scre 22 | ``` 23 | 24 | ## Keyboard Shortcuts 25 | 26 | - `Command + s`: record/stop button 27 | - `Command + l`: Show other windows 28 | - `Command + ,`: Settings 29 | 30 | ## Settings 31 | 32 | - Always ask file path 33 | - if the option is false, we automatically save GIF file under `Movies` folder. 34 | - Mouse button press 35 | - You can capture your mouse and its press event. 36 | - Repeat 37 | - You can choose whether the GIF file supports repeat or not 38 | - Pixel Size 39 | - Original, High, Middle, Low 40 | - Frame Rate 41 | - High, Middle, Low 42 | 43 |

44 | 46 | 47 | ## Build 48 | 49 | You need CocoaPods to resolve dependencies. 50 | 51 | ```sh 52 | pod install 53 | ``` 54 | 55 | And open `Scre.xcworkspace` on XCode and here you go! -------------------------------------------------------------------------------- /Scre/Util/Config.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import AVFoundation 3 | 4 | struct Config { 5 | enum Key: String { 6 | case alwaysAskFilePath 7 | case mouseButtonPress 8 | case repeatAllowed 9 | case pixelSize 10 | case frameRate 11 | case location 12 | case windowFrame 13 | } 14 | 15 | static let shared = Config() 16 | let userDefaults: UserDefaults 17 | 18 | init(userDefaults: UserDefaults = UserDefaults.standard) { 19 | self.userDefaults = userDefaults 20 | } 21 | 22 | var location: String { 23 | userDefaults.string(forKey: Key.location.rawValue) ?? NSSearchPathForDirectoriesInDomains(.moviesDirectory, .userDomainMask, true).first ?? "" 24 | } 25 | 26 | var alwaysAskFilePath: Bool { 27 | userDefaults.bool(forKey: Key.alwaysAskFilePath.rawValue) 28 | } 29 | 30 | var mouseButtonPress: Bool { 31 | userDefaults.bool(forKey: Key.mouseButtonPress.rawValue) 32 | } 33 | 34 | var repeatAllowed: Int { 35 | userDefaults.bool(forKey: Key.repeatAllowed.rawValue) ? 0 : 1 36 | } 37 | 38 | var sessionPreset: AVCaptureSession.Preset? { 39 | PixelSize(rawValue: userDefaults.integer(forKey: Key.pixelSize.rawValue))?.preset 40 | } 41 | 42 | var frameRate: Int { 43 | FrameRate(rawValue: userDefaults.integer(forKey: Key.frameRate.rawValue))?.frameRate ?? FrameRate.medium.frameRate 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Scre/Model/GIFConveter.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Regift 3 | 4 | final class GIFConverter { 5 | typealias Completion = (URL?) -> Void 6 | private let config = Config.shared 7 | 8 | private var gifUrl: URL { 9 | if config.alwaysAskFilePath { 10 | return URL(fileURLWithPath: Config.shared.location) 11 | } else { 12 | let url = NSSearchPathForDirectoriesInDomains(.moviesDirectory, .userDomainMask, true).first ?? "" 13 | return URL(fileURLWithPath: url).appendingPathComponent(Utils.formatter.string(from: Date())).appendingPathExtension("gif") 14 | } 15 | } 16 | 17 | func save(videoUrl: URL, duration: Float, completion: @escaping Completion) { 18 | Regift.createGIFFromSource(videoUrl, startTime: 0, duration: duration, frameRate: config.frameRate, loopCount: config.repeatAllowed) { url in 19 | self.copy(url: url, completion: completion) 20 | } 21 | } 22 | 23 | private func copy(url: URL?, completion: @escaping Completion) { 24 | guard let url = url else { 25 | completion(nil) 26 | return 27 | } 28 | defer { 29 | try? FileManager.default.removeItem(at: url) 30 | } 31 | do { 32 | let gifUrl = self.gifUrl 33 | try FileManager.default.copyItem(at: url, to: gifUrl) 34 | completion(gifUrl) 35 | } catch { 36 | completion(nil) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Scre/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon-16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "Icon-33.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "Icon-32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "Icon-64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "Icon-128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "Icon-257.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "Icon-256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "Icon-513.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "Icon-512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "Icon-1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ScreUITests/ScreUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScreUITests.swift 3 | // ScreUITests 4 | // 5 | // Created by Shintaro Katafuchi on 2021/02/21. 6 | // 7 | 8 | import XCTest 9 | 10 | class ScreUITests: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | func testLaunchPerformance() throws { 35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { 36 | // This measures how long it takes to launch your application. 37 | measure(metrics: [XCTApplicationLaunchMetric()]) { 38 | XCUIApplication().launch() 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Scre/Util/NSWindow+Extensions.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import SwiftUI 3 | 4 | extension NSWindow { 5 | func toggleMoving(enabled: Bool) { 6 | if enabled { 7 | styleMask.update(with: .resizable) 8 | isMovable = true 9 | isMovableByWindowBackground = true 10 | level = NSWindow.Level(Int(CGWindowLevelForKey(.normalWindow))) 11 | } else { 12 | styleMask.remove(.resizable) 13 | isMovable = false 14 | isMovableByWindowBackground = false 15 | level = NSWindow.Level(Int(CGWindowLevelForKey(.floatingWindow))) 16 | } 17 | } 18 | 19 | func setSizeAsTitle() { 20 | title = sizeAsTitle() 21 | } 22 | 23 | func sizeAsTitle() -> String { 24 | return "Size: \(frame.size.width.description) × \(frame.size.height.description)" 25 | } 26 | 27 | func setInitialFrame(prevRect: CGRect) { 28 | if prevRect == .zero, let screenSize = screen?.visibleFrame.size { 29 | let width: CGFloat = 400 30 | let height: CGFloat = 600 31 | let x = (screenSize.width - prevRect.size.width) / 2 - (width / 2) 32 | let y = (screenSize.height - prevRect.size.height) / 2 - (height / 2) 33 | setFrame(CGRect(x: x, y: y, width: width, height: height), display: true) 34 | } else { 35 | setFrame(frame, display: true) 36 | } 37 | } 38 | } 39 | 40 | extension View { 41 | @ViewBuilder func isHidden(_ hidden: Bool) -> some View { 42 | if hidden { 43 | self.hidden() 44 | } else { 45 | self 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Scre/Util/WindowServer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct WindowServer { 4 | struct Window { 5 | let pid: Int 6 | let x: Int 7 | let y: Int 8 | let width: Int 9 | let height: Int 10 | } 11 | 12 | static func getWindows() -> [Window] { 13 | var windows: [Window] = [] 14 | let options = CGWindowListOption(arrayLiteral: .excludeDesktopElements, .optionOnScreenOnly) 15 | guard let windowList: NSArray = CGWindowListCopyWindowInfo(options, kCGNullWindowID) else { 16 | return windows 17 | } 18 | for window in windowList { 19 | let dict = window as! NSDictionary 20 | if ((dict.value(forKey: "kCGWindowAlpha") as! Double) == 0) { 21 | continue 22 | } 23 | var ownerName = "" 24 | if (dict.value(forKey: "kCGWindowOwnerName") != nil) { 25 | ownerName = dict.value(forKey: "kCGWindowOwnerName") as! String 26 | } 27 | let bundleName = Bundle.main.infoDictionary![kCFBundleNameKey as String] as! String 28 | if (bundleName == ownerName) { 29 | continue 30 | } 31 | let bounds = dict.value(forKey: "kCGWindowBounds") as! NSDictionary 32 | let x = bounds.value(forKey: "X")! as! Int 33 | let y = bounds.value(forKey: "Y")! as! Int 34 | let width = bounds.value(forKey: "Width")! as! Int 35 | let height = bounds.value(forKey: "Height")! as! Int 36 | let pid = dict.value(forKey: "kCGWindowOwnerPID") as! Int 37 | windows.append(Window(pid: pid, x: x, y: y, width: width, height: height)) 38 | } 39 | return windows 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Scre/View/SettingsView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct SettingsView: View { 4 | var body: some View { 5 | GeneralSettingsView() 6 | } 7 | } 8 | 9 | struct GeneralSettingsView: View { 10 | // TODO: move to ViewModel 11 | @AppStorage(Config.Key.alwaysAskFilePath.rawValue) private var alwaysAskFilePath = false 12 | @AppStorage(Config.Key.mouseButtonPress.rawValue) private var mouseButtonPress = true 13 | @AppStorage(Config.Key.repeatAllowed.rawValue) private var repeatAllowed = true 14 | @AppStorage(Config.Key.pixelSize.rawValue) private var pixelSize = PixelSize.original.rawValue 15 | @AppStorage(Config.Key.frameRate.rawValue) private var frameRate = FrameRate.medium.rawValue 16 | @AppStorage(Config.Key.location.rawValue) private var location = "" 17 | 18 | var body: some View { 19 | Form { 20 | Toggle("Always ask file path", isOn: $alwaysAskFilePath) 21 | .toggleStyle(SwitchToggleStyle()) 22 | Toggle("Mouse button press", isOn: $mouseButtonPress) 23 | .toggleStyle(SwitchToggleStyle()) 24 | Toggle("Repeat", isOn: $repeatAllowed) 25 | .toggleStyle(SwitchToggleStyle()) 26 | Picker(selection: $pixelSize, label: Text("Pixel Size")) { 27 | ForEach(PixelSize.allCases, id: \.self) { size in 28 | Text(size.label).tag(size.rawValue) 29 | } 30 | } 31 | .frame(width: 160) 32 | Picker(selection: $frameRate, label: Text("Frame Rate")) { 33 | ForEach(FrameRate.allCases, id: \.self) {rate in 34 | Text(rate.label).tag(rate.rawValue) 35 | } 36 | } 37 | .frame(width: 170) 38 | } 39 | .navigationTitle("Preferences") 40 | .frame(width: 350) 41 | .padding() 42 | } 43 | } 44 | 45 | struct SettingsView_Previews: PreviewProvider { 46 | static var previews: some View { 47 | SettingsView() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Scre/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | final class AppDelegate: NSObject, NSApplicationDelegate { 4 | @AppStorage(Config.Key.windowFrame.rawValue) private var windowFrame = "" 5 | 6 | var window: NSWindow? { 7 | NSApplication.shared.windows.first 8 | } 9 | 10 | func applicationDidFinishLaunching(_ notification: Notification) { 11 | guard let window = window else { 12 | return 13 | } 14 | window.setInitialFrame(prevRect: NSRectFromString(windowFrame)) 15 | window.setSizeAsTitle() 16 | window.tabbingMode = .disallowed 17 | window.isOpaque = false 18 | window.backgroundColor = NSColor.clear 19 | window.contentView?.wantsLayer = true 20 | window.contentView?.layer?.borderColor = NSColor.windowBackgroundColor.cgColor 21 | window.contentView?.layer?.borderWidth = 2 22 | window.contentView?.layer?.allowsEdgeAntialiasing = true 23 | window.delegate = self 24 | window.makeKeyAndOrderFront(nil) 25 | window.toggleMoving(enabled: true) 26 | 27 | NotificationCenter.default.addObserver(self, selector: #selector(didResizeNotification(notification:)), name: NSWindow.didResizeNotification, object: nil) 28 | } 29 | 30 | func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 31 | true 32 | } 33 | } 34 | 35 | // MARK: - Command Menu 36 | extension AppDelegate { 37 | @IBAction func showHelp(_ sender: Any) { 38 | guard let url = URL(string: "https://github.com/hotchemi/Scre") else { 39 | return 40 | } 41 | NSWorkspace.shared.open(url) 42 | } 43 | } 44 | 45 | // MARK: - NSWindow.didResizeNotification 46 | extension AppDelegate { 47 | @objc func didResizeNotification(notification: Notification) { 48 | window?.setSizeAsTitle() 49 | } 50 | } 51 | 52 | // MARK: - NSWindowDelegate 53 | extension AppDelegate : NSWindowDelegate { 54 | func windowWillClose(_ notification: Notification) { 55 | NotificationCenter.default.removeObserver(self) 56 | if let frame = window?.frame { 57 | windowFrame = NSStringFromRect(frame) 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Scre/Model/ScreenRecorder.swift: -------------------------------------------------------------------------------- 1 | import AVFoundation 2 | import Cocoa 3 | 4 | protocol ScreenRecorderDelegate { 5 | func screenRecorder(recorder: ScreenRecorder, didStateChange state: MainView.ViewState) 6 | } 7 | 8 | final class ScreenRecorder: NSObject { 9 | private let input = AVCaptureScreenInput(displayID: CGMainDisplayID()) 10 | private let output = AVCaptureMovieFileOutput() 11 | private let session = AVCaptureSession() 12 | private let gifConveter = GIFConverter() 13 | private let config = Config.shared 14 | 15 | var delegate: ScreenRecorderDelegate? 16 | 17 | override init() {} 18 | 19 | func record(rect: CGRect) { 20 | guard let input = input else { 21 | debugPrint("failed to initialize AVCaptureScreenInput") 22 | return 23 | } 24 | if let preset = config.sessionPreset { 25 | input.scaleFactor = 1.0 26 | session.sessionPreset = preset 27 | } else { 28 | input.scaleFactor = 0.505 29 | } 30 | input.cropRect = rect 31 | input.capturesCursor = config.mouseButtonPress 32 | input.capturesMouseClicks = config.mouseButtonPress 33 | if session.canAddInput(input) { 34 | session.addInput(input) 35 | } 36 | if session.canAddOutput(output) { 37 | session.addOutput(output) 38 | } 39 | let tempVideoUrl = URL(fileURLWithPath: NSTemporaryDirectory()) 40 | .appendingPathComponent(UUID().uuidString) 41 | .appendingPathExtension("mov") 42 | session.startRunning() 43 | output.startRecording(to: tempVideoUrl, recordingDelegate: self) 44 | } 45 | 46 | func stop() { 47 | output.stopRecording() 48 | session.stopRunning() 49 | session.removeOutput(output) 50 | if let input = input { 51 | session.removeInput(input) 52 | } 53 | } 54 | } 55 | 56 | // MARK: - AVCaptureFileOutputRecordingDelegate 57 | extension ScreenRecorder: AVCaptureFileOutputRecordingDelegate { 58 | func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) { 59 | delegate?.screenRecorder(recorder: self, didStateChange: .recording) 60 | } 61 | 62 | func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { 63 | delegate?.screenRecorder(recorder: self, didStateChange: .stop) 64 | let duration = CMTimeGetSeconds(output.recordedDuration) 65 | gifConveter.save(videoUrl: outputFileURL, duration: Float(duration)) { [weak self] url in 66 | guard let self = self else { 67 | return 68 | } 69 | let state: MainView.ViewState = url == nil ? .error : .finish 70 | self.delegate?.screenRecorder(recorder: self, didStateChange: state) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Scre.xcodeproj/xcshareddata/xcschemes/Scre.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Scre/View/MainView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct MainView: View { 4 | enum ViewState { 5 | case idle 6 | case start 7 | case recording 8 | case stop 9 | case finish 10 | case error 11 | } 12 | // TODO: move to ViewModel 13 | private let screenRecorder = ScreenRecorder() 14 | @AppStorage(Config.Key.location.rawValue) private var location = "" 15 | @AppStorage(Config.Key.alwaysAskFilePath.rawValue) private var alwaysAskFilePath = false 16 | 17 | @NSApplicationDelegateAdaptor(AppDelegate.self) private var delegate 18 | @ObservedObject private var timerHolder = TimerHolder() 19 | @State private var recordButtonText = "play.fill" 20 | @State private var isActionButtonDisabled = false 21 | @State private var isProgressHidden = true 22 | @State private var showPopover = false 23 | @State private var showAlert = false 24 | @State var state: ViewState = .idle { 25 | didSet { 26 | DispatchQueue.main.async { 27 | self.handleStateChanged() 28 | } 29 | } 30 | } 31 | 32 | var body: some View { 33 | ZStack { 34 | VStack { 35 | Spacer() 36 | HStack { 37 | Button(action: { 38 | NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil) 39 | }, label: { 40 | Image(systemName: "gear") 41 | }) 42 | Spacer() 43 | Button(action: { 44 | switch state { 45 | case .idle: 46 | state = .start 47 | case .start, .recording: 48 | state = .stop 49 | default: 50 | break 51 | } 52 | }, label: { 53 | Image(systemName: recordButtonText) 54 | }) 55 | .keyboardShortcut("s", modifiers: [.command]) 56 | .disabled(isActionButtonDisabled) 57 | Spacer() 58 | Button(action: { 59 | showPopover.toggle() 60 | }, label: { 61 | Image(systemName: "macwindow") 62 | }) 63 | .keyboardShortcut("l", modifiers: [.command]) 64 | .popover( 65 | isPresented: self.$showPopover, 66 | arrowEdge: .bottom 67 | ) { 68 | // TODO: separate view 69 | let windows = WindowServer.getWindows() 70 | let apps = windows.map { NSRunningApplication(processIdentifier: pid_t($0.pid)) } 71 | List { 72 | ForEach(0 ..< windows.count, id: \.self) { index in 73 | Button(action: { 74 | showPopover.toggle() 75 | guard let screen = NSScreen.main?.frame else { 76 | return 77 | } 78 | let width = windows[index].width 79 | let height = windows[index].height 80 | let x = windows[index].x 81 | let y = Int(screen.size.height) - windows[index].y - height 82 | let rect = CGRect(x: x, y: y, width: width, height: height) 83 | delegate.window?.setFrame(rect, display: true, animate: true) 84 | }) { 85 | Image(nsImage: (apps[index]?.icon)!) 86 | Text(apps[index]?.localizedName ?? "") 87 | } 88 | .buttonStyle(PlainButtonStyle()) 89 | } 90 | } 91 | } 92 | } 93 | .padding(8) 94 | .background(Color(NSColor.windowBackgroundColor)) 95 | .alert(isPresented: $showAlert) { 96 | Alert(title: Text("Error"), 97 | message: Text("Sorry, something wrong has happenned.") 98 | ) 99 | } 100 | } 101 | ProgressView().isHidden(isProgressHidden) 102 | }.navigationTitle(timerHolder.navigationTitle) 103 | } 104 | 105 | private func openSavePanel(successHandler: @escaping () -> Void, errorHandler: @escaping () -> Void) { 106 | let panel = NSSavePanel() 107 | panel.nameFieldStringValue = "\(Utils.formatter.string(from: Date())).gif" 108 | panel.showsTagField = true 109 | panel.canCreateDirectories = true 110 | panel.allowedFileTypes = ["gif"] 111 | panel.begin { response in 112 | if response == .OK, let url = panel.url { 113 | location = url.path 114 | successHandler() 115 | } else { 116 | errorHandler() 117 | } 118 | } 119 | } 120 | 121 | private func handleStateChanged() { 122 | switch state { 123 | case .idle: 124 | recordButtonText = "play.fill" 125 | delegate.window?.toggleMoving(enabled: true) 126 | isProgressHidden = true 127 | timerHolder.navigationTitle = delegate.window?.sizeAsTitle() ?? "" 128 | isActionButtonDisabled = false 129 | case .start: 130 | let closure = { 131 | screenRecorder.delegate = self 132 | screenRecorder.record(rect: Utils.recordFrame(window: delegate.window)) 133 | recordButtonText = "stop.fill" 134 | isProgressHidden = true 135 | delegate.window?.toggleMoving(enabled: false) 136 | timerHolder.navigationTitle = "Record will start..." 137 | isActionButtonDisabled = true 138 | } 139 | if alwaysAskFilePath { 140 | openSavePanel(successHandler: closure) { 141 | state = .idle 142 | } 143 | } else { 144 | closure() 145 | } 146 | case .recording: 147 | recordButtonText = "stop.fill" 148 | isProgressHidden = true 149 | timerHolder.start() 150 | isActionButtonDisabled = false 151 | case .stop: 152 | screenRecorder.stop() 153 | isProgressHidden = false 154 | timerHolder.navigationTitle = "Converting to GIF..." 155 | timerHolder.stop() 156 | isActionButtonDisabled = true 157 | case .finish: 158 | state = .idle 159 | isProgressHidden = false 160 | isActionButtonDisabled = false 161 | case .error: 162 | state = .idle 163 | showAlert = true 164 | } 165 | } 166 | } 167 | 168 | extension MainView: ScreenRecorderDelegate { 169 | func screenRecorder(recorder: ScreenRecorder, didStateChange state: ViewState) { 170 | self.state = state 171 | } 172 | } 173 | 174 | struct MainView_Previews: PreviewProvider { 175 | static var previews: some View { 176 | MainView() 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /Scre.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7414E07E22D8A9092307001C /* Pods_ScreTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E01C68ECF755905402BBC828 /* Pods_ScreTests.framework */; }; 11 | 9F26FE3425E3AE710081BE31 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F26FE3325E3AE710081BE31 /* AppDelegate.swift */; }; 12 | 9F3B5F6D25E28DB80084A6B9 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F6C25E28DB80084A6B9 /* Application.swift */; }; 13 | 9F3B5F6F25E28DB80084A6B9 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F6E25E28DB80084A6B9 /* MainView.swift */; }; 14 | 9F3B5F7125E28DB90084A6B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F3B5F7025E28DB90084A6B9 /* Assets.xcassets */; }; 15 | 9F3B5F7425E28DB90084A6B9 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F3B5F7325E28DB90084A6B9 /* Preview Assets.xcassets */; }; 16 | 9F3B5F8025E28DB90084A6B9 /* ScreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F7F25E28DB90084A6B9 /* ScreTests.swift */; }; 17 | 9F3B5F8B25E28DB90084A6B9 /* ScreUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3B5F8A25E28DB90084A6B9 /* ScreUITests.swift */; }; 18 | 9F6037E025E4A7FB00CFA708 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6037DF25E4A7FB00CFA708 /* Config.swift */; }; 19 | 9F6037E825E4A81A00CFA708 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6037E725E4A81A00CFA708 /* Utils.swift */; }; 20 | 9F85967E25EBA86200A51B43 /* NSWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F85967D25EBA86200A51B43 /* NSWindow+Extensions.swift */; }; 21 | 9F93E6C425F2AE8D00B26C7E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F93E6C325F2AE8D00B26C7E /* SettingsView.swift */; }; 22 | 9F9AD9C325F4CD6200F48B58 /* PixelSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9AD9C225F4CD6200F48B58 /* PixelSize.swift */; }; 23 | 9F9AD9C825F4D33700F48B58 /* FrameRate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9AD9C725F4D33700F48B58 /* FrameRate.swift */; }; 24 | 9F9AD9DA25F50EC600F48B58 /* WindowServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9AD9D925F50EC600F48B58 /* WindowServer.swift */; }; 25 | 9F9EDC2725F737C400EAFB35 /* TimerHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9EDC2625F737C400EAFB35 /* TimerHolder.swift */; }; 26 | 9FB3EF9425E4023500E88335 /* ScreenRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB3EF9325E4023500E88335 /* ScreenRecorder.swift */; }; 27 | 9FB3EF9E25E4033700E88335 /* GIFConveter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB3EF9D25E4033700E88335 /* GIFConveter.swift */; }; 28 | BD1FDFFDB68D3C03475CDF49 /* Pods_Scre_ScreUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA2220A2A757812E276A7305 /* Pods_Scre_ScreUITests.framework */; }; 29 | CEECA6E9DB548459019290C4 /* Pods_Scre.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03E9D5724D7131A8543D5C2C /* Pods_Scre.framework */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 9F3B5F7C25E28DB90084A6B9 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 9F3B5F6125E28DB80084A6B9 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 9F3B5F6825E28DB80084A6B9; 38 | remoteInfo = Scre; 39 | }; 40 | 9F3B5F8725E28DB90084A6B9 /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 9F3B5F6125E28DB80084A6B9 /* Project object */; 43 | proxyType = 1; 44 | remoteGlobalIDString = 9F3B5F6825E28DB80084A6B9; 45 | remoteInfo = Scre; 46 | }; 47 | /* End PBXContainerItemProxy section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 03E9D5724D7131A8543D5C2C /* Pods_Scre.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Scre.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 0F8B03146FD21BF6DCD03EB2 /* Pods-Scre.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre.debug.xcconfig"; path = "Target Support Files/Pods-Scre/Pods-Scre.debug.xcconfig"; sourceTree = ""; }; 52 | 1195994B4F14D667AD726394 /* Pods-Scre-ScreUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre-ScreUITests.debug.xcconfig"; path = "Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests.debug.xcconfig"; sourceTree = ""; }; 53 | 4667D51D990932C8CEF4AD43 /* Pods-Scre-ScreUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre-ScreUITests.release.xcconfig"; path = "Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests.release.xcconfig"; sourceTree = ""; }; 54 | 877258A9C45840F1682F8875 /* Pods-ScreTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreTests.release.xcconfig"; path = "Target Support Files/Pods-ScreTests/Pods-ScreTests.release.xcconfig"; sourceTree = ""; }; 55 | 9F26FE3325E3AE710081BE31 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 56 | 9F3B5F6925E28DB80084A6B9 /* Scre.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Scre.app; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | 9F3B5F6C25E28DB80084A6B9 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; }; 58 | 9F3B5F6E25E28DB80084A6B9 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; 59 | 9F3B5F7025E28DB90084A6B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 60 | 9F3B5F7325E28DB90084A6B9 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 61 | 9F3B5F7525E28DB90084A6B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | 9F3B5F7625E28DB90084A6B9 /* Scre.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Scre.entitlements; sourceTree = ""; }; 63 | 9F3B5F7B25E28DB90084A6B9 /* ScreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 9F3B5F7F25E28DB90084A6B9 /* ScreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreTests.swift; sourceTree = ""; }; 65 | 9F3B5F8125E28DB90084A6B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 9F3B5F8625E28DB90084A6B9 /* ScreUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 9F3B5F8A25E28DB90084A6B9 /* ScreUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreUITests.swift; sourceTree = ""; }; 68 | 9F3B5F8C25E28DB90084A6B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | 9F6037DF25E4A7FB00CFA708 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; 70 | 9F6037E725E4A81A00CFA708 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 71 | 9F85967D25EBA86200A51B43 /* NSWindow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSWindow+Extensions.swift"; sourceTree = ""; }; 72 | 9F93E6C325F2AE8D00B26C7E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 73 | 9F9AD9C225F4CD6200F48B58 /* PixelSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelSize.swift; sourceTree = ""; }; 74 | 9F9AD9C725F4D33700F48B58 /* FrameRate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameRate.swift; sourceTree = ""; }; 75 | 9F9AD9D925F50EC600F48B58 /* WindowServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowServer.swift; sourceTree = ""; }; 76 | 9F9EDC2625F737C400EAFB35 /* TimerHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerHolder.swift; sourceTree = ""; }; 77 | 9FB3EF9325E4023500E88335 /* ScreenRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenRecorder.swift; sourceTree = ""; }; 78 | 9FB3EF9D25E4033700E88335 /* GIFConveter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GIFConveter.swift; sourceTree = ""; }; 79 | AA2220A2A757812E276A7305 /* Pods_Scre_ScreUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Scre_ScreUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | C1083585DB6297624A614B7F /* Pods-ScreTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreTests.debug.xcconfig"; path = "Target Support Files/Pods-ScreTests/Pods-ScreTests.debug.xcconfig"; sourceTree = ""; }; 81 | E01C68ECF755905402BBC828 /* Pods_ScreTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ScreTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 82 | EA0E19E1E1906A0A9A5764EF /* Pods-Scre.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Scre.release.xcconfig"; path = "Target Support Files/Pods-Scre/Pods-Scre.release.xcconfig"; sourceTree = ""; }; 83 | /* End PBXFileReference section */ 84 | 85 | /* Begin PBXFrameworksBuildPhase section */ 86 | 9F3B5F6625E28DB80084A6B9 /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | CEECA6E9DB548459019290C4 /* Pods_Scre.framework in Frameworks */, 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | 9F3B5F7825E28DB90084A6B9 /* Frameworks */ = { 95 | isa = PBXFrameworksBuildPhase; 96 | buildActionMask = 2147483647; 97 | files = ( 98 | 7414E07E22D8A9092307001C /* Pods_ScreTests.framework in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | 9F3B5F8325E28DB90084A6B9 /* Frameworks */ = { 103 | isa = PBXFrameworksBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | BD1FDFFDB68D3C03475CDF49 /* Pods_Scre_ScreUITests.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | /* End PBXFrameworksBuildPhase section */ 111 | 112 | /* Begin PBXGroup section */ 113 | 9F26FE2C25E3ADEB0081BE31 /* View */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 9F3B5F6E25E28DB80084A6B9 /* MainView.swift */, 117 | 9F93E6C325F2AE8D00B26C7E /* SettingsView.swift */, 118 | ); 119 | path = View; 120 | sourceTree = ""; 121 | }; 122 | 9F3B5F6025E28DB80084A6B9 = { 123 | isa = PBXGroup; 124 | children = ( 125 | 9F3B5F6B25E28DB80084A6B9 /* Scre */, 126 | 9F3B5F7E25E28DB90084A6B9 /* ScreTests */, 127 | 9F3B5F8925E28DB90084A6B9 /* ScreUITests */, 128 | 9F3B5F6A25E28DB80084A6B9 /* Products */, 129 | B488C141B5517547C2CFF575 /* Pods */, 130 | E1A5780A4E70365F7356EC1B /* Frameworks */, 131 | ); 132 | sourceTree = ""; 133 | }; 134 | 9F3B5F6A25E28DB80084A6B9 /* Products */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 9F3B5F6925E28DB80084A6B9 /* Scre.app */, 138 | 9F3B5F7B25E28DB90084A6B9 /* ScreTests.xctest */, 139 | 9F3B5F8625E28DB90084A6B9 /* ScreUITests.xctest */, 140 | ); 141 | name = Products; 142 | sourceTree = ""; 143 | }; 144 | 9F3B5F6B25E28DB80084A6B9 /* Scre */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 9F6037DE25E4A7ED00CFA708 /* Util */, 148 | 9FB3EF9125E4021B00E88335 /* Model */, 149 | 9F26FE2C25E3ADEB0081BE31 /* View */, 150 | 9F26FE3325E3AE710081BE31 /* AppDelegate.swift */, 151 | 9F3B5F6C25E28DB80084A6B9 /* Application.swift */, 152 | 9F3B5F7025E28DB90084A6B9 /* Assets.xcassets */, 153 | 9F3B5F7525E28DB90084A6B9 /* Info.plist */, 154 | 9F3B5F7625E28DB90084A6B9 /* Scre.entitlements */, 155 | 9F3B5F7225E28DB90084A6B9 /* Preview Content */, 156 | ); 157 | path = Scre; 158 | sourceTree = ""; 159 | }; 160 | 9F3B5F7225E28DB90084A6B9 /* Preview Content */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 9F3B5F7325E28DB90084A6B9 /* Preview Assets.xcassets */, 164 | ); 165 | path = "Preview Content"; 166 | sourceTree = ""; 167 | }; 168 | 9F3B5F7E25E28DB90084A6B9 /* ScreTests */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 9F3B5F7F25E28DB90084A6B9 /* ScreTests.swift */, 172 | 9F3B5F8125E28DB90084A6B9 /* Info.plist */, 173 | ); 174 | path = ScreTests; 175 | sourceTree = ""; 176 | }; 177 | 9F3B5F8925E28DB90084A6B9 /* ScreUITests */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 9F3B5F8A25E28DB90084A6B9 /* ScreUITests.swift */, 181 | 9F3B5F8C25E28DB90084A6B9 /* Info.plist */, 182 | ); 183 | path = ScreUITests; 184 | sourceTree = ""; 185 | }; 186 | 9F6037DE25E4A7ED00CFA708 /* Util */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 9F6037DF25E4A7FB00CFA708 /* Config.swift */, 190 | 9F6037E725E4A81A00CFA708 /* Utils.swift */, 191 | 9F85967D25EBA86200A51B43 /* NSWindow+Extensions.swift */, 192 | 9F9AD9D925F50EC600F48B58 /* WindowServer.swift */, 193 | ); 194 | path = Util; 195 | sourceTree = ""; 196 | }; 197 | 9FB3EF9125E4021B00E88335 /* Model */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 9FB3EF9325E4023500E88335 /* ScreenRecorder.swift */, 201 | 9FB3EF9D25E4033700E88335 /* GIFConveter.swift */, 202 | 9F9AD9C225F4CD6200F48B58 /* PixelSize.swift */, 203 | 9F9AD9C725F4D33700F48B58 /* FrameRate.swift */, 204 | 9F9EDC2625F737C400EAFB35 /* TimerHolder.swift */, 205 | ); 206 | path = Model; 207 | sourceTree = ""; 208 | }; 209 | B488C141B5517547C2CFF575 /* Pods */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | 0F8B03146FD21BF6DCD03EB2 /* Pods-Scre.debug.xcconfig */, 213 | EA0E19E1E1906A0A9A5764EF /* Pods-Scre.release.xcconfig */, 214 | 1195994B4F14D667AD726394 /* Pods-Scre-ScreUITests.debug.xcconfig */, 215 | 4667D51D990932C8CEF4AD43 /* Pods-Scre-ScreUITests.release.xcconfig */, 216 | C1083585DB6297624A614B7F /* Pods-ScreTests.debug.xcconfig */, 217 | 877258A9C45840F1682F8875 /* Pods-ScreTests.release.xcconfig */, 218 | ); 219 | path = Pods; 220 | sourceTree = ""; 221 | }; 222 | E1A5780A4E70365F7356EC1B /* Frameworks */ = { 223 | isa = PBXGroup; 224 | children = ( 225 | 03E9D5724D7131A8543D5C2C /* Pods_Scre.framework */, 226 | AA2220A2A757812E276A7305 /* Pods_Scre_ScreUITests.framework */, 227 | E01C68ECF755905402BBC828 /* Pods_ScreTests.framework */, 228 | ); 229 | name = Frameworks; 230 | sourceTree = ""; 231 | }; 232 | /* End PBXGroup section */ 233 | 234 | /* Begin PBXNativeTarget section */ 235 | 9F3B5F6825E28DB80084A6B9 /* Scre */ = { 236 | isa = PBXNativeTarget; 237 | buildConfigurationList = 9F3B5F8F25E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "Scre" */; 238 | buildPhases = ( 239 | D07BDB164334E5B2CA9A3246 /* [CP] Check Pods Manifest.lock */, 240 | 9F3B5F6525E28DB80084A6B9 /* Sources */, 241 | 9F3B5F6625E28DB80084A6B9 /* Frameworks */, 242 | 9F3B5F6725E28DB80084A6B9 /* Resources */, 243 | 2BF3D8796D13DB59DF1CB22D /* [CP] Embed Pods Frameworks */, 244 | ); 245 | buildRules = ( 246 | ); 247 | dependencies = ( 248 | ); 249 | name = Scre; 250 | productName = Scre; 251 | productReference = 9F3B5F6925E28DB80084A6B9 /* Scre.app */; 252 | productType = "com.apple.product-type.application"; 253 | }; 254 | 9F3B5F7A25E28DB90084A6B9 /* ScreTests */ = { 255 | isa = PBXNativeTarget; 256 | buildConfigurationList = 9F3B5F9225E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreTests" */; 257 | buildPhases = ( 258 | FD0D607E3A67EA76E1A96E08 /* [CP] Check Pods Manifest.lock */, 259 | 9F3B5F7725E28DB90084A6B9 /* Sources */, 260 | 9F3B5F7825E28DB90084A6B9 /* Frameworks */, 261 | 9F3B5F7925E28DB90084A6B9 /* Resources */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | 9F3B5F7D25E28DB90084A6B9 /* PBXTargetDependency */, 267 | ); 268 | name = ScreTests; 269 | productName = ScreTests; 270 | productReference = 9F3B5F7B25E28DB90084A6B9 /* ScreTests.xctest */; 271 | productType = "com.apple.product-type.bundle.unit-test"; 272 | }; 273 | 9F3B5F8525E28DB90084A6B9 /* ScreUITests */ = { 274 | isa = PBXNativeTarget; 275 | buildConfigurationList = 9F3B5F9525E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreUITests" */; 276 | buildPhases = ( 277 | B908A311D8D6EE087CBEAA35 /* [CP] Check Pods Manifest.lock */, 278 | 9F3B5F8225E28DB90084A6B9 /* Sources */, 279 | 9F3B5F8325E28DB90084A6B9 /* Frameworks */, 280 | 9F3B5F8425E28DB90084A6B9 /* Resources */, 281 | 14E6693ADE3ADE729BD6A3AA /* [CP] Embed Pods Frameworks */, 282 | ); 283 | buildRules = ( 284 | ); 285 | dependencies = ( 286 | 9F3B5F8825E28DB90084A6B9 /* PBXTargetDependency */, 287 | ); 288 | name = ScreUITests; 289 | productName = ScreUITests; 290 | productReference = 9F3B5F8625E28DB90084A6B9 /* ScreUITests.xctest */; 291 | productType = "com.apple.product-type.bundle.ui-testing"; 292 | }; 293 | /* End PBXNativeTarget section */ 294 | 295 | /* Begin PBXProject section */ 296 | 9F3B5F6125E28DB80084A6B9 /* Project object */ = { 297 | isa = PBXProject; 298 | attributes = { 299 | LastSwiftUpdateCheck = 1240; 300 | LastUpgradeCheck = 1240; 301 | TargetAttributes = { 302 | 9F3B5F6825E28DB80084A6B9 = { 303 | CreatedOnToolsVersion = 12.4; 304 | }; 305 | 9F3B5F7A25E28DB90084A6B9 = { 306 | CreatedOnToolsVersion = 12.4; 307 | TestTargetID = 9F3B5F6825E28DB80084A6B9; 308 | }; 309 | 9F3B5F8525E28DB90084A6B9 = { 310 | CreatedOnToolsVersion = 12.4; 311 | TestTargetID = 9F3B5F6825E28DB80084A6B9; 312 | }; 313 | }; 314 | }; 315 | buildConfigurationList = 9F3B5F6425E28DB80084A6B9 /* Build configuration list for PBXProject "Scre" */; 316 | compatibilityVersion = "Xcode 9.3"; 317 | developmentRegion = en; 318 | hasScannedForEncodings = 0; 319 | knownRegions = ( 320 | en, 321 | Base, 322 | ); 323 | mainGroup = 9F3B5F6025E28DB80084A6B9; 324 | productRefGroup = 9F3B5F6A25E28DB80084A6B9 /* Products */; 325 | projectDirPath = ""; 326 | projectRoot = ""; 327 | targets = ( 328 | 9F3B5F6825E28DB80084A6B9 /* Scre */, 329 | 9F3B5F7A25E28DB90084A6B9 /* ScreTests */, 330 | 9F3B5F8525E28DB90084A6B9 /* ScreUITests */, 331 | ); 332 | }; 333 | /* End PBXProject section */ 334 | 335 | /* Begin PBXResourcesBuildPhase section */ 336 | 9F3B5F6725E28DB80084A6B9 /* Resources */ = { 337 | isa = PBXResourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | 9F3B5F7425E28DB90084A6B9 /* Preview Assets.xcassets in Resources */, 341 | 9F3B5F7125E28DB90084A6B9 /* Assets.xcassets in Resources */, 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | 9F3B5F7925E28DB90084A6B9 /* Resources */ = { 346 | isa = PBXResourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | ); 350 | runOnlyForDeploymentPostprocessing = 0; 351 | }; 352 | 9F3B5F8425E28DB90084A6B9 /* Resources */ = { 353 | isa = PBXResourcesBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | ); 357 | runOnlyForDeploymentPostprocessing = 0; 358 | }; 359 | /* End PBXResourcesBuildPhase section */ 360 | 361 | /* Begin PBXShellScriptBuildPhase section */ 362 | 14E6693ADE3ADE729BD6A3AA /* [CP] Embed Pods Frameworks */ = { 363 | isa = PBXShellScriptBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | ); 367 | inputFileListPaths = ( 368 | "${PODS_ROOT}/Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", 369 | ); 370 | name = "[CP] Embed Pods Frameworks"; 371 | outputFileListPaths = ( 372 | "${PODS_ROOT}/Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | shellPath = /bin/sh; 376 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Scre-ScreUITests/Pods-Scre-ScreUITests-frameworks.sh\"\n"; 377 | showEnvVarsInLog = 0; 378 | }; 379 | 2BF3D8796D13DB59DF1CB22D /* [CP] Embed Pods Frameworks */ = { 380 | isa = PBXShellScriptBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | ); 384 | inputFileListPaths = ( 385 | "${PODS_ROOT}/Target Support Files/Pods-Scre/Pods-Scre-frameworks-${CONFIGURATION}-input-files.xcfilelist", 386 | ); 387 | name = "[CP] Embed Pods Frameworks"; 388 | outputFileListPaths = ( 389 | "${PODS_ROOT}/Target Support Files/Pods-Scre/Pods-Scre-frameworks-${CONFIGURATION}-output-files.xcfilelist", 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | shellPath = /bin/sh; 393 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Scre/Pods-Scre-frameworks.sh\"\n"; 394 | showEnvVarsInLog = 0; 395 | }; 396 | B908A311D8D6EE087CBEAA35 /* [CP] Check Pods Manifest.lock */ = { 397 | isa = PBXShellScriptBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | ); 401 | inputFileListPaths = ( 402 | ); 403 | inputPaths = ( 404 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 405 | "${PODS_ROOT}/Manifest.lock", 406 | ); 407 | name = "[CP] Check Pods Manifest.lock"; 408 | outputFileListPaths = ( 409 | ); 410 | outputPaths = ( 411 | "$(DERIVED_FILE_DIR)/Pods-Scre-ScreUITests-checkManifestLockResult.txt", 412 | ); 413 | runOnlyForDeploymentPostprocessing = 0; 414 | shellPath = /bin/sh; 415 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 416 | showEnvVarsInLog = 0; 417 | }; 418 | D07BDB164334E5B2CA9A3246 /* [CP] Check Pods Manifest.lock */ = { 419 | isa = PBXShellScriptBuildPhase; 420 | buildActionMask = 2147483647; 421 | files = ( 422 | ); 423 | inputFileListPaths = ( 424 | ); 425 | inputPaths = ( 426 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 427 | "${PODS_ROOT}/Manifest.lock", 428 | ); 429 | name = "[CP] Check Pods Manifest.lock"; 430 | outputFileListPaths = ( 431 | ); 432 | outputPaths = ( 433 | "$(DERIVED_FILE_DIR)/Pods-Scre-checkManifestLockResult.txt", 434 | ); 435 | runOnlyForDeploymentPostprocessing = 0; 436 | shellPath = /bin/sh; 437 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 438 | showEnvVarsInLog = 0; 439 | }; 440 | FD0D607E3A67EA76E1A96E08 /* [CP] Check Pods Manifest.lock */ = { 441 | isa = PBXShellScriptBuildPhase; 442 | buildActionMask = 2147483647; 443 | files = ( 444 | ); 445 | inputFileListPaths = ( 446 | ); 447 | inputPaths = ( 448 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 449 | "${PODS_ROOT}/Manifest.lock", 450 | ); 451 | name = "[CP] Check Pods Manifest.lock"; 452 | outputFileListPaths = ( 453 | ); 454 | outputPaths = ( 455 | "$(DERIVED_FILE_DIR)/Pods-ScreTests-checkManifestLockResult.txt", 456 | ); 457 | runOnlyForDeploymentPostprocessing = 0; 458 | shellPath = /bin/sh; 459 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 460 | showEnvVarsInLog = 0; 461 | }; 462 | /* End PBXShellScriptBuildPhase section */ 463 | 464 | /* Begin PBXSourcesBuildPhase section */ 465 | 9F3B5F6525E28DB80084A6B9 /* Sources */ = { 466 | isa = PBXSourcesBuildPhase; 467 | buildActionMask = 2147483647; 468 | files = ( 469 | 9F9AD9C825F4D33700F48B58 /* FrameRate.swift in Sources */, 470 | 9F26FE3425E3AE710081BE31 /* AppDelegate.swift in Sources */, 471 | 9F9AD9DA25F50EC600F48B58 /* WindowServer.swift in Sources */, 472 | 9F3B5F6F25E28DB80084A6B9 /* MainView.swift in Sources */, 473 | 9F85967E25EBA86200A51B43 /* NSWindow+Extensions.swift in Sources */, 474 | 9F93E6C425F2AE8D00B26C7E /* SettingsView.swift in Sources */, 475 | 9F9EDC2725F737C400EAFB35 /* TimerHolder.swift in Sources */, 476 | 9F3B5F6D25E28DB80084A6B9 /* Application.swift in Sources */, 477 | 9F9AD9C325F4CD6200F48B58 /* PixelSize.swift in Sources */, 478 | 9F6037E025E4A7FB00CFA708 /* Config.swift in Sources */, 479 | 9FB3EF9425E4023500E88335 /* ScreenRecorder.swift in Sources */, 480 | 9FB3EF9E25E4033700E88335 /* GIFConveter.swift in Sources */, 481 | 9F6037E825E4A81A00CFA708 /* Utils.swift in Sources */, 482 | ); 483 | runOnlyForDeploymentPostprocessing = 0; 484 | }; 485 | 9F3B5F7725E28DB90084A6B9 /* Sources */ = { 486 | isa = PBXSourcesBuildPhase; 487 | buildActionMask = 2147483647; 488 | files = ( 489 | 9F3B5F8025E28DB90084A6B9 /* ScreTests.swift in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | 9F3B5F8225E28DB90084A6B9 /* Sources */ = { 494 | isa = PBXSourcesBuildPhase; 495 | buildActionMask = 2147483647; 496 | files = ( 497 | 9F3B5F8B25E28DB90084A6B9 /* ScreUITests.swift in Sources */, 498 | ); 499 | runOnlyForDeploymentPostprocessing = 0; 500 | }; 501 | /* End PBXSourcesBuildPhase section */ 502 | 503 | /* Begin PBXTargetDependency section */ 504 | 9F3B5F7D25E28DB90084A6B9 /* PBXTargetDependency */ = { 505 | isa = PBXTargetDependency; 506 | target = 9F3B5F6825E28DB80084A6B9 /* Scre */; 507 | targetProxy = 9F3B5F7C25E28DB90084A6B9 /* PBXContainerItemProxy */; 508 | }; 509 | 9F3B5F8825E28DB90084A6B9 /* PBXTargetDependency */ = { 510 | isa = PBXTargetDependency; 511 | target = 9F3B5F6825E28DB80084A6B9 /* Scre */; 512 | targetProxy = 9F3B5F8725E28DB90084A6B9 /* PBXContainerItemProxy */; 513 | }; 514 | /* End PBXTargetDependency section */ 515 | 516 | /* Begin XCBuildConfiguration section */ 517 | 9F3B5F8D25E28DB90084A6B9 /* Debug */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | ALWAYS_SEARCH_USER_PATHS = NO; 521 | CLANG_ANALYZER_NONNULL = YES; 522 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 523 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 524 | CLANG_CXX_LIBRARY = "libc++"; 525 | CLANG_ENABLE_MODULES = YES; 526 | CLANG_ENABLE_OBJC_ARC = YES; 527 | CLANG_ENABLE_OBJC_WEAK = YES; 528 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 529 | CLANG_WARN_BOOL_CONVERSION = YES; 530 | CLANG_WARN_COMMA = YES; 531 | CLANG_WARN_CONSTANT_CONVERSION = YES; 532 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 533 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 534 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 535 | CLANG_WARN_EMPTY_BODY = YES; 536 | CLANG_WARN_ENUM_CONVERSION = YES; 537 | CLANG_WARN_INFINITE_RECURSION = YES; 538 | CLANG_WARN_INT_CONVERSION = YES; 539 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 540 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 541 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 542 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 543 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 544 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 545 | CLANG_WARN_STRICT_PROTOTYPES = YES; 546 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 547 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 548 | CLANG_WARN_UNREACHABLE_CODE = YES; 549 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 550 | COPY_PHASE_STRIP = NO; 551 | DEBUG_INFORMATION_FORMAT = dwarf; 552 | ENABLE_STRICT_OBJC_MSGSEND = YES; 553 | ENABLE_TESTABILITY = YES; 554 | GCC_C_LANGUAGE_STANDARD = gnu11; 555 | GCC_DYNAMIC_NO_PIC = NO; 556 | GCC_NO_COMMON_BLOCKS = YES; 557 | GCC_OPTIMIZATION_LEVEL = 0; 558 | GCC_PREPROCESSOR_DEFINITIONS = ( 559 | "DEBUG=1", 560 | "$(inherited)", 561 | ); 562 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 563 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 564 | GCC_WARN_UNDECLARED_SELECTOR = YES; 565 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 566 | GCC_WARN_UNUSED_FUNCTION = YES; 567 | GCC_WARN_UNUSED_VARIABLE = YES; 568 | MACOSX_DEPLOYMENT_TARGET = 11.1; 569 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 570 | MTL_FAST_MATH = YES; 571 | ONLY_ACTIVE_ARCH = YES; 572 | SDKROOT = macosx; 573 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 574 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 575 | }; 576 | name = Debug; 577 | }; 578 | 9F3B5F8E25E28DB90084A6B9 /* Release */ = { 579 | isa = XCBuildConfiguration; 580 | buildSettings = { 581 | ALWAYS_SEARCH_USER_PATHS = NO; 582 | CLANG_ANALYZER_NONNULL = YES; 583 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 584 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 585 | CLANG_CXX_LIBRARY = "libc++"; 586 | CLANG_ENABLE_MODULES = YES; 587 | CLANG_ENABLE_OBJC_ARC = YES; 588 | CLANG_ENABLE_OBJC_WEAK = YES; 589 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 590 | CLANG_WARN_BOOL_CONVERSION = YES; 591 | CLANG_WARN_COMMA = YES; 592 | CLANG_WARN_CONSTANT_CONVERSION = YES; 593 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 594 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 595 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 596 | CLANG_WARN_EMPTY_BODY = YES; 597 | CLANG_WARN_ENUM_CONVERSION = YES; 598 | CLANG_WARN_INFINITE_RECURSION = YES; 599 | CLANG_WARN_INT_CONVERSION = YES; 600 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 601 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 602 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 603 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 604 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 605 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 606 | CLANG_WARN_STRICT_PROTOTYPES = YES; 607 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 608 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 609 | CLANG_WARN_UNREACHABLE_CODE = YES; 610 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 611 | COPY_PHASE_STRIP = NO; 612 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 613 | ENABLE_NS_ASSERTIONS = NO; 614 | ENABLE_STRICT_OBJC_MSGSEND = YES; 615 | GCC_C_LANGUAGE_STANDARD = gnu11; 616 | GCC_NO_COMMON_BLOCKS = YES; 617 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 618 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 619 | GCC_WARN_UNDECLARED_SELECTOR = YES; 620 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 621 | GCC_WARN_UNUSED_FUNCTION = YES; 622 | GCC_WARN_UNUSED_VARIABLE = YES; 623 | MACOSX_DEPLOYMENT_TARGET = 11.1; 624 | MTL_ENABLE_DEBUG_INFO = NO; 625 | MTL_FAST_MATH = YES; 626 | SDKROOT = macosx; 627 | SWIFT_COMPILATION_MODE = wholemodule; 628 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 629 | }; 630 | name = Release; 631 | }; 632 | 9F3B5F9025E28DB90084A6B9 /* Debug */ = { 633 | isa = XCBuildConfiguration; 634 | baseConfigurationReference = 0F8B03146FD21BF6DCD03EB2 /* Pods-Scre.debug.xcconfig */; 635 | buildSettings = { 636 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 637 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 638 | CODE_SIGN_ENTITLEMENTS = Scre/Scre.entitlements; 639 | CODE_SIGN_STYLE = Automatic; 640 | COMBINE_HIDPI_IMAGES = YES; 641 | DEVELOPMENT_ASSET_PATHS = "\"Scre/Preview Content\""; 642 | ENABLE_PREVIEWS = YES; 643 | INFOPLIST_FILE = Scre/Info.plist; 644 | LD_RUNPATH_SEARCH_PATHS = ( 645 | "$(inherited)", 646 | "@executable_path/../Frameworks", 647 | ); 648 | MACOSX_DEPLOYMENT_TARGET = 11.0; 649 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.Scre; 650 | PRODUCT_NAME = "$(TARGET_NAME)"; 651 | SWIFT_VERSION = 5.0; 652 | }; 653 | name = Debug; 654 | }; 655 | 9F3B5F9125E28DB90084A6B9 /* Release */ = { 656 | isa = XCBuildConfiguration; 657 | baseConfigurationReference = EA0E19E1E1906A0A9A5764EF /* Pods-Scre.release.xcconfig */; 658 | buildSettings = { 659 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 660 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 661 | CODE_SIGN_ENTITLEMENTS = Scre/Scre.entitlements; 662 | CODE_SIGN_STYLE = Automatic; 663 | COMBINE_HIDPI_IMAGES = YES; 664 | DEVELOPMENT_ASSET_PATHS = "\"Scre/Preview Content\""; 665 | ENABLE_PREVIEWS = YES; 666 | INFOPLIST_FILE = Scre/Info.plist; 667 | LD_RUNPATH_SEARCH_PATHS = ( 668 | "$(inherited)", 669 | "@executable_path/../Frameworks", 670 | ); 671 | MACOSX_DEPLOYMENT_TARGET = 11.0; 672 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.Scre; 673 | PRODUCT_NAME = "$(TARGET_NAME)"; 674 | SWIFT_VERSION = 5.0; 675 | }; 676 | name = Release; 677 | }; 678 | 9F3B5F9325E28DB90084A6B9 /* Debug */ = { 679 | isa = XCBuildConfiguration; 680 | baseConfigurationReference = C1083585DB6297624A614B7F /* Pods-ScreTests.debug.xcconfig */; 681 | buildSettings = { 682 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 683 | BUNDLE_LOADER = "$(TEST_HOST)"; 684 | CODE_SIGN_STYLE = Automatic; 685 | COMBINE_HIDPI_IMAGES = YES; 686 | INFOPLIST_FILE = ScreTests/Info.plist; 687 | LD_RUNPATH_SEARCH_PATHS = ( 688 | "$(inherited)", 689 | "@executable_path/../Frameworks", 690 | "@loader_path/../Frameworks", 691 | ); 692 | MACOSX_DEPLOYMENT_TARGET = 11.0; 693 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreTests; 694 | PRODUCT_NAME = "$(TARGET_NAME)"; 695 | SWIFT_VERSION = 5.0; 696 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Scre.app/Contents/MacOS/Scre"; 697 | }; 698 | name = Debug; 699 | }; 700 | 9F3B5F9425E28DB90084A6B9 /* Release */ = { 701 | isa = XCBuildConfiguration; 702 | baseConfigurationReference = 877258A9C45840F1682F8875 /* Pods-ScreTests.release.xcconfig */; 703 | buildSettings = { 704 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 705 | BUNDLE_LOADER = "$(TEST_HOST)"; 706 | CODE_SIGN_STYLE = Automatic; 707 | COMBINE_HIDPI_IMAGES = YES; 708 | INFOPLIST_FILE = ScreTests/Info.plist; 709 | LD_RUNPATH_SEARCH_PATHS = ( 710 | "$(inherited)", 711 | "@executable_path/../Frameworks", 712 | "@loader_path/../Frameworks", 713 | ); 714 | MACOSX_DEPLOYMENT_TARGET = 11.0; 715 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreTests; 716 | PRODUCT_NAME = "$(TARGET_NAME)"; 717 | SWIFT_VERSION = 5.0; 718 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Scre.app/Contents/MacOS/Scre"; 719 | }; 720 | name = Release; 721 | }; 722 | 9F3B5F9625E28DB90084A6B9 /* Debug */ = { 723 | isa = XCBuildConfiguration; 724 | baseConfigurationReference = 1195994B4F14D667AD726394 /* Pods-Scre-ScreUITests.debug.xcconfig */; 725 | buildSettings = { 726 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 727 | CODE_SIGN_STYLE = Automatic; 728 | COMBINE_HIDPI_IMAGES = YES; 729 | INFOPLIST_FILE = ScreUITests/Info.plist; 730 | LD_RUNPATH_SEARCH_PATHS = ( 731 | "$(inherited)", 732 | "@executable_path/../Frameworks", 733 | "@loader_path/../Frameworks", 734 | ); 735 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreUITests; 736 | PRODUCT_NAME = "$(TARGET_NAME)"; 737 | SWIFT_VERSION = 5.0; 738 | TEST_TARGET_NAME = Scre; 739 | }; 740 | name = Debug; 741 | }; 742 | 9F3B5F9725E28DB90084A6B9 /* Release */ = { 743 | isa = XCBuildConfiguration; 744 | baseConfigurationReference = 4667D51D990932C8CEF4AD43 /* Pods-Scre-ScreUITests.release.xcconfig */; 745 | buildSettings = { 746 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 747 | CODE_SIGN_STYLE = Automatic; 748 | COMBINE_HIDPI_IMAGES = YES; 749 | INFOPLIST_FILE = ScreUITests/Info.plist; 750 | LD_RUNPATH_SEARCH_PATHS = ( 751 | "$(inherited)", 752 | "@executable_path/../Frameworks", 753 | "@loader_path/../Frameworks", 754 | ); 755 | PRODUCT_BUNDLE_IDENTIFIER = com.github.hotchemi.ScreUITests; 756 | PRODUCT_NAME = "$(TARGET_NAME)"; 757 | SWIFT_VERSION = 5.0; 758 | TEST_TARGET_NAME = Scre; 759 | }; 760 | name = Release; 761 | }; 762 | /* End XCBuildConfiguration section */ 763 | 764 | /* Begin XCConfigurationList section */ 765 | 9F3B5F6425E28DB80084A6B9 /* Build configuration list for PBXProject "Scre" */ = { 766 | isa = XCConfigurationList; 767 | buildConfigurations = ( 768 | 9F3B5F8D25E28DB90084A6B9 /* Debug */, 769 | 9F3B5F8E25E28DB90084A6B9 /* Release */, 770 | ); 771 | defaultConfigurationIsVisible = 0; 772 | defaultConfigurationName = Release; 773 | }; 774 | 9F3B5F8F25E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "Scre" */ = { 775 | isa = XCConfigurationList; 776 | buildConfigurations = ( 777 | 9F3B5F9025E28DB90084A6B9 /* Debug */, 778 | 9F3B5F9125E28DB90084A6B9 /* Release */, 779 | ); 780 | defaultConfigurationIsVisible = 0; 781 | defaultConfigurationName = Release; 782 | }; 783 | 9F3B5F9225E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreTests" */ = { 784 | isa = XCConfigurationList; 785 | buildConfigurations = ( 786 | 9F3B5F9325E28DB90084A6B9 /* Debug */, 787 | 9F3B5F9425E28DB90084A6B9 /* Release */, 788 | ); 789 | defaultConfigurationIsVisible = 0; 790 | defaultConfigurationName = Release; 791 | }; 792 | 9F3B5F9525E28DB90084A6B9 /* Build configuration list for PBXNativeTarget "ScreUITests" */ = { 793 | isa = XCConfigurationList; 794 | buildConfigurations = ( 795 | 9F3B5F9625E28DB90084A6B9 /* Debug */, 796 | 9F3B5F9725E28DB90084A6B9 /* Release */, 797 | ); 798 | defaultConfigurationIsVisible = 0; 799 | defaultConfigurationName = Release; 800 | }; 801 | /* End XCConfigurationList section */ 802 | }; 803 | rootObject = 9F3B5F6125E28DB80084A6B9 /* Project object */; 804 | } 805 | --------------------------------------------------------------------------------