├── starter.zip
├── .gitattributes
├── mt12_1_demo_app_preview.png
├── TinyEditor
├── Assets.xcassets
│ ├── Contents.json
│ ├── bgcolor.imageset
│ │ ├── bgcolor.png
│ │ ├── bgcolor@2x.png
│ │ └── Contents.json
│ ├── textcolor.imageset
│ │ ├── textcolor.png
│ │ ├── textcolor@2x.png
│ │ └── Contents.json
│ ├── blue.colorset
│ │ └── Contents.json
│ ├── pink.colorset
│ │ └── Contents.json
│ ├── teal.colorset
│ │ └── Contents.json
│ ├── yellow.colorset
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── TinyEditor.entitlements
├── AppColors.swift
├── TinyNote.swift
├── AppDelegate.swift
├── Document.swift
├── ViewController.swift
├── Info.plist
└── Main.storyboard
├── TinyEditor.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── gabriel.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── gabriel.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── project.pbxproj
├── README.md
└── LICENSE
/starter.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/starter.zip
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/mt12_1_demo_app_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/mt12_1_demo_app_preview.png
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/bgcolor.imageset/bgcolor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/TinyEditor/Assets.xcassets/bgcolor.imageset/bgcolor.png
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/bgcolor.imageset/bgcolor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/TinyEditor/Assets.xcassets/bgcolor.imageset/bgcolor@2x.png
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/textcolor.imageset/textcolor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/TinyEditor/Assets.xcassets/textcolor.imageset/textcolor.png
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/textcolor.imageset/textcolor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/TinyEditor/Assets.xcassets/textcolor.imageset/textcolor@2x.png
--------------------------------------------------------------------------------
/TinyEditor.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TinyEditor.xcodeproj/project.xcworkspace/xcuserdata/gabriel.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appcoda/TinyEditor/HEAD/TinyEditor.xcodeproj/project.xcworkspace/xcuserdata/gabriel.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TinyEditor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TinyEditor/TinyEditor.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-write
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/blue.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0xF9",
9 | "green" : "0xDE",
10 | "red" : "0xA9"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/pink.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0x9E",
9 | "green" : "0xA6",
10 | "red" : "0xFF"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/teal.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0xC6",
9 | "green" : "0xDC",
10 | "red" : "0x84"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/yellow.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0x70",
9 | "green" : "0xD6",
10 | "red" : "0xFF"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/TinyEditor.xcodeproj/xcuserdata/gabriel.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TinyEditor.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/bgcolor.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "bgcolor.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "bgcolor@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/textcolor.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "textcolor.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "textcolor@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TinyEditor - Learn to build a document based Mac app
2 |
3 | 
4 |
5 | Welcome to another macOS tutorial! In this post we are about to learn how to create a macOS application that belongs to a unique category of apps; a category that is quite common but also quite important, and contains a large number of existing and new macOS apps. We are going to learn how to create a document based application.
6 |
7 | For the full tutorial, please refer to the following link:
8 |
9 | https://www.appcoda.com/document-based-app-macos/
10 |
--------------------------------------------------------------------------------
/TinyEditor/AppColors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppColors.swift
3 | // TinyEditor
4 | //
5 | // Created by Gabriel Theodoropoulos.
6 | // Copyright © 2020 AppCoda. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | struct AppColors {
12 | static let bgColors: [(name: String, color: NSColor)] = [
13 | ("Default", NSColor.textBackgroundColor),
14 | ("Blue", NSColor(named: "blue") ?? NSColor.black),
15 | ("Yellow", NSColor(named: "yellow") ?? NSColor.black),
16 | ("Pink", NSColor(named: "pink") ?? NSColor.black),
17 | ("Teal", NSColor(named: "teal") ?? NSColor.black)]
18 |
19 |
20 | static let textColors: [(name: String, color: NSColor)] = [
21 | ("Dark", NSColor.black),
22 | ("Light", NSColor.white)]
23 | }
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Simon Ng
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 |
--------------------------------------------------------------------------------
/TinyEditor/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/TinyEditor/TinyNote.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TinyNote.swift
3 | // TinyEditor
4 | //
5 | // Created by Gabriel Theodoropoulos.
6 | // Copyright © 2020 AppCoda. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class TinyNote: Codable {
12 |
13 | var note = ""
14 |
15 | var bgColorIndex: Int = 0
16 |
17 | var textColorIndex: Int = 1
18 |
19 |
20 | // MARK: - Init()
21 |
22 | init() {
23 |
24 | }
25 |
26 |
27 | func getNoteAsJSON() -> Data? {
28 | let encoder = JSONEncoder()
29 | return try? encoder.encode(self)
30 | }
31 |
32 |
33 | func use(data: Data) -> Bool {
34 | let decoder = JSONDecoder()
35 |
36 | guard let decoded = try? decoder.decode(TinyNote.self, from: data) else {
37 | // Data was not a JSON.
38 | // Try to create a String object using it.
39 | guard let text = String(data: data, encoding: .utf8) else { return false }
40 |
41 | // Data was converted to a string successfully!
42 | note = text
43 | return true
44 | }
45 |
46 | // Data was a JSON and has been decoded successfully!
47 | note = decoded.note
48 | bgColorIndex = decoded.bgColorIndex
49 | textColorIndex = decoded.textColorIndex
50 |
51 | return true
52 | }
53 |
54 |
55 | func getNoteText() -> Data? {
56 | return note.data(using: .utf8)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/TinyEditor/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TinyEditor
4 | //
5 | // Created by Gabriel Theodoropoulos.
6 | // Copyright © 2020 AppCoda. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 | @IBOutlet weak var bgColorMenu: NSMenu?
15 |
16 | @IBOutlet weak var textColorMenu: NSMenu?
17 |
18 |
19 | func applicationDidFinishLaunching(_ aNotification: Notification) {
20 | // Insert code here to initialize your application
21 | }
22 |
23 | func applicationWillTerminate(_ aNotification: Notification) {
24 | // Insert code here to tear down your application
25 | }
26 |
27 |
28 | override func awakeFromNib() {
29 | super.awakeFromNib()
30 | configureBGColorsMenu()
31 | configureTextColorsMenu()
32 | }
33 |
34 |
35 | fileprivate func configureBGColorsMenu() {
36 | AppColors.bgColors.forEach { bgColorMenu?.addItem(withTitle: $0.name, action: #selector(handleBGColorSelection(_:)), keyEquivalent: "")}
37 | }
38 |
39 |
40 | @objc fileprivate func handleBGColorSelection(_ menuItem: NSMenuItem) {
41 | let docController = NSDocumentController()
42 | guard let vc = docController.currentDocument?.windowControllers.first?.contentViewController as? ViewController else { return }
43 | vc.setBGColor(with: menuItem.title)
44 | }
45 |
46 |
47 | fileprivate func configureTextColorsMenu() {
48 | AppColors.textColors.forEach { textColorMenu?.addItem(withTitle: $0.name, action: #selector(handleTextColorSelection(_:)), keyEquivalent: "")}
49 | }
50 |
51 | @objc fileprivate func handleTextColorSelection(_ menuItem: NSMenuItem) {
52 | let docController = NSDocumentController()
53 | guard let vc = docController.currentDocument?.windowControllers.first?.contentViewController as? ViewController else { return }
54 | vc.setTextColor(with: menuItem.title)
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/TinyEditor/Document.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Document.swift
3 | // TinyEditor
4 | //
5 | // Created by Gabriel Theodoropoulos.
6 | // Copyright © 2020 AppCoda. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class Document: NSDocument {
12 |
13 | var content = TinyNote()
14 |
15 | var didReadData = false
16 |
17 |
18 | override init() {
19 | super.init()
20 | // Add your subclass-specific initialization here.
21 | }
22 |
23 | override class var autosavesInPlace: Bool {
24 | return true
25 | }
26 |
27 | override func makeWindowControllers() {
28 | // Returns the Storyboard that contains your Document window.
29 | let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
30 | let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
31 | self.addWindowController(windowController)
32 |
33 | windowController.contentViewController?.representedObject = content
34 | }
35 |
36 | override func data(ofType typeName: String) throws -> Data {
37 | // Insert code here to write your document to data of the specified type, throwing an error in case of failure.
38 | // Alternatively, you could remove this method and override fileWrapper(ofType:), write(to:ofType:), or write(to:ofType:for:originalContentsURL:) instead.
39 |
40 | if typeName == "TinyEditor Document" {
41 | if let noteData = content.getNoteAsJSON() {
42 | return noteData
43 | }
44 | } else {
45 | if let noteData = content.getNoteText() {
46 | return noteData
47 | }
48 | }
49 |
50 |
51 |
52 | throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
53 | }
54 |
55 | override func read(from data: Data, ofType typeName: String) throws {
56 | // Insert code here to read your document from the given data of the specified type, throwing an error in case of failure.
57 | // Alternatively, you could remove this method and override read(from:ofType:) instead.
58 | // If you do, you should also override isEntireFileLoaded to return false if the contents are lazily loaded.
59 |
60 | if content.use(data: data) {
61 |
62 | // Make didReadData flag true to indicate that data has been read from a file!
63 | didReadData = true
64 |
65 | return
66 | }
67 |
68 | throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
69 | }
70 |
71 |
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/TinyEditor/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // TinyEditor
4 | //
5 | // Created by Gabriel Theodoropoulos.
6 | // Copyright © 2020 AppCoda. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class ViewController: NSViewController {
12 |
13 | @IBOutlet var textView: NSTextView!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | // Do any additional setup after loading the view.
19 | }
20 |
21 |
22 | override func viewWillAppear() {
23 | super.viewWillAppear()
24 |
25 | textView.font = NSFont.systemFont(ofSize: 17.0)
26 | textView.delegate = self
27 |
28 | handleOpenDocumentOperation()
29 | }
30 |
31 |
32 | override var representedObject: Any? {
33 | didSet {
34 | // Update the view, if already loaded.
35 | }
36 | }
37 |
38 |
39 | func setBGColor(with name: String) {
40 | textView.backgroundColor = AppColors.bgColors.filter { $0.name == name }.first?.color ?? NSColor.textBackgroundColor
41 |
42 | if let colorIndex = AppColors.bgColors.firstIndex(where: { $0.name == name }) {
43 | (representedObject as? TinyNote)?.bgColorIndex = colorIndex
44 | }
45 | }
46 |
47 |
48 | func setTextColor(with name: String) {
49 | // Update the text color.
50 | textView.textColor = AppColors.textColors.filter { $0.name == name }.first?.color ?? NSColor.textColor
51 |
52 | // Update the cursor color!
53 | textView.insertionPointColor = textView.textColor ?? NSColor.textColor
54 |
55 | if let colorIndex = AppColors.textColors.firstIndex(where: { $0.name == name }) {
56 | (representedObject as? TinyNote)?.textColorIndex = colorIndex
57 | }
58 | }
59 |
60 |
61 | func handleOpenDocumentOperation() {
62 | if let document = self.view.window?.windowController?.document as? Document {
63 | if document.didReadData {
64 | populateDocumentContent()
65 | document.didReadData = false
66 | }
67 | }
68 | }
69 |
70 |
71 | func populateDocumentContent() {
72 | guard let content = representedObject as? TinyNote else { return }
73 | textView.string = content.note
74 | setBGColor(with: AppColors.bgColors[content.bgColorIndex].name)
75 | setTextColor(with: AppColors.textColors[content.textColorIndex].name)
76 | }
77 | }
78 |
79 |
80 | // MARK: - NSTextViewDelegate
81 |
82 | extension ViewController: NSTextViewDelegate {
83 | func textViewDidChangeSelection(_ notification: Notification) {
84 | (representedObject as? TinyNote)?.note = textView.string
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/TinyEditor/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDocumentTypes
8 |
9 |
10 | CFBundleTypeExtensions
11 |
12 | tinyeditor
13 |
14 | CFBundleTypeIconFile
15 |
16 | CFBundleTypeName
17 | TinyEditor Document
18 | CFBundleTypeOSTypes
19 |
20 | ????
21 |
22 | CFBundleTypeRole
23 | Editor
24 | NSDocumentClass
25 | $(PRODUCT_MODULE_NAME).Document
26 |
27 |
28 | CFBundleTypeExtensions
29 |
30 | txt
31 |
32 | CFBundleTypeMIMETypes
33 |
34 | CFBundleTypeName
35 | Plain Text Document
36 | CFBundleTypeRole
37 | Editor
38 | LSHandlerRank
39 | alternate
40 | LSItemContentTypes
41 |
42 | public.plain-text
43 |
44 | NSDocumentClass
45 | $(PRODUCT_MODULE_NAME).Document
46 |
47 |
48 | CFBundleExecutable
49 | $(EXECUTABLE_NAME)
50 | CFBundleIconFile
51 |
52 | CFBundleIdentifier
53 | $(PRODUCT_BUNDLE_IDENTIFIER)
54 | CFBundleInfoDictionaryVersion
55 | 6.0
56 | CFBundleName
57 | $(PRODUCT_NAME)
58 | CFBundlePackageType
59 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
60 | CFBundleShortVersionString
61 | 1.0
62 | CFBundleVersion
63 | 1
64 | LSMinimumSystemVersion
65 | $(MACOSX_DEPLOYMENT_TARGET)
66 | NSHumanReadableCopyright
67 | Copyright © 2020 AppCoda. All rights reserved.
68 | NSMainStoryboardFile
69 | Main
70 | NSPrincipalClass
71 | NSApplication
72 | NSSupportsAutomaticTermination
73 |
74 | NSSupportsSuddenTermination
75 |
76 | UTExportedTypeDeclarations
77 |
78 |
79 | UTTypeDescription
80 | TinyEditor Document UTI
81 | UTTypeIdentifier
82 | com.appcoda.tinyeditor
83 | UTTypeTagSpecification
84 |
85 | public.filename-extension
86 |
87 | tinyeditor
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/TinyEditor.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | C006630824680B6D00D759A6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C006630724680B6D00D759A6 /* AppDelegate.swift */; };
11 | C006630A24680B6D00D759A6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C006630924680B6D00D759A6 /* ViewController.swift */; };
12 | C006630C24680B6D00D759A6 /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = C006630B24680B6D00D759A6 /* Document.swift */; };
13 | C006631C246815C900D759A6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C006631B246815C900D759A6 /* Assets.xcassets */; };
14 | C00663222468226400D759A6 /* AppColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00663212468226400D759A6 /* AppColors.swift */; };
15 | C00663242468372E00D759A6 /* TinyNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00663232468372E00D759A6 /* TinyNote.swift */; };
16 | C006632824689D8C00D759A6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C006632724689D8C00D759A6 /* Main.storyboard */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | C006630424680B6D00D759A6 /* TinyEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TinyEditor.app; sourceTree = BUILT_PRODUCTS_DIR; };
21 | C006630724680B6D00D759A6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
22 | C006630924680B6D00D759A6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
23 | C006630B24680B6D00D759A6 /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = ""; };
24 | C006631224680B7000D759A6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | C006631324680B7000D759A6 /* TinyEditor.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TinyEditor.entitlements; sourceTree = ""; };
26 | C006631B246815C900D759A6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
27 | C00663212468226400D759A6 /* AppColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppColors.swift; sourceTree = ""; };
28 | C00663232468372E00D759A6 /* TinyNote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TinyNote.swift; sourceTree = ""; };
29 | C006632724689D8C00D759A6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
30 | /* End PBXFileReference section */
31 |
32 | /* Begin PBXFrameworksBuildPhase section */
33 | C006630124680B6D00D759A6 /* Frameworks */ = {
34 | isa = PBXFrameworksBuildPhase;
35 | buildActionMask = 2147483647;
36 | files = (
37 | );
38 | runOnlyForDeploymentPostprocessing = 0;
39 | };
40 | /* End PBXFrameworksBuildPhase section */
41 |
42 | /* Begin PBXGroup section */
43 | C00662FB24680B6D00D759A6 = {
44 | isa = PBXGroup;
45 | children = (
46 | C006630624680B6D00D759A6 /* TinyEditor */,
47 | C006630524680B6D00D759A6 /* Products */,
48 | );
49 | sourceTree = "";
50 | };
51 | C006630524680B6D00D759A6 /* Products */ = {
52 | isa = PBXGroup;
53 | children = (
54 | C006630424680B6D00D759A6 /* TinyEditor.app */,
55 | );
56 | name = Products;
57 | sourceTree = "";
58 | };
59 | C006630624680B6D00D759A6 /* TinyEditor */ = {
60 | isa = PBXGroup;
61 | children = (
62 | C00663212468226400D759A6 /* AppColors.swift */,
63 | C006630724680B6D00D759A6 /* AppDelegate.swift */,
64 | C00663232468372E00D759A6 /* TinyNote.swift */,
65 | C006630924680B6D00D759A6 /* ViewController.swift */,
66 | C006630B24680B6D00D759A6 /* Document.swift */,
67 | C006631B246815C900D759A6 /* Assets.xcassets */,
68 | C006632724689D8C00D759A6 /* Main.storyboard */,
69 | C006631224680B7000D759A6 /* Info.plist */,
70 | C006631324680B7000D759A6 /* TinyEditor.entitlements */,
71 | );
72 | path = TinyEditor;
73 | sourceTree = "";
74 | };
75 | /* End PBXGroup section */
76 |
77 | /* Begin PBXNativeTarget section */
78 | C006630324680B6D00D759A6 /* TinyEditor */ = {
79 | isa = PBXNativeTarget;
80 | buildConfigurationList = C006631624680B7000D759A6 /* Build configuration list for PBXNativeTarget "TinyEditor" */;
81 | buildPhases = (
82 | C006630024680B6D00D759A6 /* Sources */,
83 | C006630124680B6D00D759A6 /* Frameworks */,
84 | C006630224680B6D00D759A6 /* Resources */,
85 | );
86 | buildRules = (
87 | );
88 | dependencies = (
89 | );
90 | name = TinyEditor;
91 | productName = TinyEditor;
92 | productReference = C006630424680B6D00D759A6 /* TinyEditor.app */;
93 | productType = "com.apple.product-type.application";
94 | };
95 | /* End PBXNativeTarget section */
96 |
97 | /* Begin PBXProject section */
98 | C00662FC24680B6D00D759A6 /* Project object */ = {
99 | isa = PBXProject;
100 | attributes = {
101 | LastSwiftUpdateCheck = 1140;
102 | LastUpgradeCheck = 1140;
103 | ORGANIZATIONNAME = AppCoda;
104 | TargetAttributes = {
105 | C006630324680B6D00D759A6 = {
106 | CreatedOnToolsVersion = 11.4.1;
107 | };
108 | };
109 | };
110 | buildConfigurationList = C00662FF24680B6D00D759A6 /* Build configuration list for PBXProject "TinyEditor" */;
111 | compatibilityVersion = "Xcode 9.3";
112 | developmentRegion = en;
113 | hasScannedForEncodings = 0;
114 | knownRegions = (
115 | en,
116 | Base,
117 | );
118 | mainGroup = C00662FB24680B6D00D759A6;
119 | productRefGroup = C006630524680B6D00D759A6 /* Products */;
120 | projectDirPath = "";
121 | projectRoot = "";
122 | targets = (
123 | C006630324680B6D00D759A6 /* TinyEditor */,
124 | );
125 | };
126 | /* End PBXProject section */
127 |
128 | /* Begin PBXResourcesBuildPhase section */
129 | C006630224680B6D00D759A6 /* Resources */ = {
130 | isa = PBXResourcesBuildPhase;
131 | buildActionMask = 2147483647;
132 | files = (
133 | C006631C246815C900D759A6 /* Assets.xcassets in Resources */,
134 | C006632824689D8C00D759A6 /* Main.storyboard in Resources */,
135 | );
136 | runOnlyForDeploymentPostprocessing = 0;
137 | };
138 | /* End PBXResourcesBuildPhase section */
139 |
140 | /* Begin PBXSourcesBuildPhase section */
141 | C006630024680B6D00D759A6 /* Sources */ = {
142 | isa = PBXSourcesBuildPhase;
143 | buildActionMask = 2147483647;
144 | files = (
145 | C006630A24680B6D00D759A6 /* ViewController.swift in Sources */,
146 | C00663242468372E00D759A6 /* TinyNote.swift in Sources */,
147 | C00663222468226400D759A6 /* AppColors.swift in Sources */,
148 | C006630824680B6D00D759A6 /* AppDelegate.swift in Sources */,
149 | C006630C24680B6D00D759A6 /* Document.swift in Sources */,
150 | );
151 | runOnlyForDeploymentPostprocessing = 0;
152 | };
153 | /* End PBXSourcesBuildPhase section */
154 |
155 | /* Begin XCBuildConfiguration section */
156 | C006631424680B7000D759A6 /* Debug */ = {
157 | isa = XCBuildConfiguration;
158 | buildSettings = {
159 | ALWAYS_SEARCH_USER_PATHS = NO;
160 | CLANG_ANALYZER_NONNULL = YES;
161 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
162 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
163 | CLANG_CXX_LIBRARY = "libc++";
164 | CLANG_ENABLE_MODULES = YES;
165 | CLANG_ENABLE_OBJC_ARC = YES;
166 | CLANG_ENABLE_OBJC_WEAK = YES;
167 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
168 | CLANG_WARN_BOOL_CONVERSION = YES;
169 | CLANG_WARN_COMMA = YES;
170 | CLANG_WARN_CONSTANT_CONVERSION = YES;
171 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
173 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
174 | CLANG_WARN_EMPTY_BODY = YES;
175 | CLANG_WARN_ENUM_CONVERSION = YES;
176 | CLANG_WARN_INFINITE_RECURSION = YES;
177 | CLANG_WARN_INT_CONVERSION = YES;
178 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
179 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
180 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
182 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
183 | CLANG_WARN_STRICT_PROTOTYPES = YES;
184 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
185 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
186 | CLANG_WARN_UNREACHABLE_CODE = YES;
187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
188 | COPY_PHASE_STRIP = NO;
189 | DEBUG_INFORMATION_FORMAT = dwarf;
190 | ENABLE_STRICT_OBJC_MSGSEND = YES;
191 | ENABLE_TESTABILITY = YES;
192 | GCC_C_LANGUAGE_STANDARD = gnu11;
193 | GCC_DYNAMIC_NO_PIC = NO;
194 | GCC_NO_COMMON_BLOCKS = YES;
195 | GCC_OPTIMIZATION_LEVEL = 0;
196 | GCC_PREPROCESSOR_DEFINITIONS = (
197 | "DEBUG=1",
198 | "$(inherited)",
199 | );
200 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
201 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
202 | GCC_WARN_UNDECLARED_SELECTOR = YES;
203 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
204 | GCC_WARN_UNUSED_FUNCTION = YES;
205 | GCC_WARN_UNUSED_VARIABLE = YES;
206 | MACOSX_DEPLOYMENT_TARGET = 10.15;
207 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
208 | MTL_FAST_MATH = YES;
209 | ONLY_ACTIVE_ARCH = YES;
210 | SDKROOT = macosx;
211 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
212 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
213 | };
214 | name = Debug;
215 | };
216 | C006631524680B7000D759A6 /* Release */ = {
217 | isa = XCBuildConfiguration;
218 | buildSettings = {
219 | ALWAYS_SEARCH_USER_PATHS = NO;
220 | CLANG_ANALYZER_NONNULL = YES;
221 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
223 | CLANG_CXX_LIBRARY = "libc++";
224 | CLANG_ENABLE_MODULES = YES;
225 | CLANG_ENABLE_OBJC_ARC = YES;
226 | CLANG_ENABLE_OBJC_WEAK = YES;
227 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
228 | CLANG_WARN_BOOL_CONVERSION = YES;
229 | CLANG_WARN_COMMA = YES;
230 | CLANG_WARN_CONSTANT_CONVERSION = YES;
231 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
232 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
233 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
234 | CLANG_WARN_EMPTY_BODY = YES;
235 | CLANG_WARN_ENUM_CONVERSION = YES;
236 | CLANG_WARN_INFINITE_RECURSION = YES;
237 | CLANG_WARN_INT_CONVERSION = YES;
238 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
239 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
240 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
241 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
242 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
243 | CLANG_WARN_STRICT_PROTOTYPES = YES;
244 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
245 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
246 | CLANG_WARN_UNREACHABLE_CODE = YES;
247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
248 | COPY_PHASE_STRIP = NO;
249 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
250 | ENABLE_NS_ASSERTIONS = NO;
251 | ENABLE_STRICT_OBJC_MSGSEND = YES;
252 | GCC_C_LANGUAGE_STANDARD = gnu11;
253 | GCC_NO_COMMON_BLOCKS = YES;
254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
256 | GCC_WARN_UNDECLARED_SELECTOR = YES;
257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
258 | GCC_WARN_UNUSED_FUNCTION = YES;
259 | GCC_WARN_UNUSED_VARIABLE = YES;
260 | MACOSX_DEPLOYMENT_TARGET = 10.15;
261 | MTL_ENABLE_DEBUG_INFO = NO;
262 | MTL_FAST_MATH = YES;
263 | SDKROOT = macosx;
264 | SWIFT_COMPILATION_MODE = wholemodule;
265 | SWIFT_OPTIMIZATION_LEVEL = "-O";
266 | };
267 | name = Release;
268 | };
269 | C006631724680B7000D759A6 /* Debug */ = {
270 | isa = XCBuildConfiguration;
271 | buildSettings = {
272 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
273 | CODE_SIGN_ENTITLEMENTS = TinyEditor/TinyEditor.entitlements;
274 | CODE_SIGN_STYLE = Automatic;
275 | COMBINE_HIDPI_IMAGES = YES;
276 | DEVELOPMENT_TEAM = 9BTCAVN99V;
277 | ENABLE_HARDENED_RUNTIME = YES;
278 | INFOPLIST_FILE = TinyEditor/Info.plist;
279 | LD_RUNPATH_SEARCH_PATHS = (
280 | "$(inherited)",
281 | "@executable_path/../Frameworks",
282 | );
283 | PRODUCT_BUNDLE_IDENTIFIER = com.appcoda.TinyEditor;
284 | PRODUCT_NAME = "$(TARGET_NAME)";
285 | SWIFT_VERSION = 5.0;
286 | };
287 | name = Debug;
288 | };
289 | C006631824680B7000D759A6 /* Release */ = {
290 | isa = XCBuildConfiguration;
291 | buildSettings = {
292 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
293 | CODE_SIGN_ENTITLEMENTS = TinyEditor/TinyEditor.entitlements;
294 | CODE_SIGN_STYLE = Automatic;
295 | COMBINE_HIDPI_IMAGES = YES;
296 | DEVELOPMENT_TEAM = 9BTCAVN99V;
297 | ENABLE_HARDENED_RUNTIME = YES;
298 | INFOPLIST_FILE = TinyEditor/Info.plist;
299 | LD_RUNPATH_SEARCH_PATHS = (
300 | "$(inherited)",
301 | "@executable_path/../Frameworks",
302 | );
303 | PRODUCT_BUNDLE_IDENTIFIER = com.appcoda.TinyEditor;
304 | PRODUCT_NAME = "$(TARGET_NAME)";
305 | SWIFT_VERSION = 5.0;
306 | };
307 | name = Release;
308 | };
309 | /* End XCBuildConfiguration section */
310 |
311 | /* Begin XCConfigurationList section */
312 | C00662FF24680B6D00D759A6 /* Build configuration list for PBXProject "TinyEditor" */ = {
313 | isa = XCConfigurationList;
314 | buildConfigurations = (
315 | C006631424680B7000D759A6 /* Debug */,
316 | C006631524680B7000D759A6 /* Release */,
317 | );
318 | defaultConfigurationIsVisible = 0;
319 | defaultConfigurationName = Release;
320 | };
321 | C006631624680B7000D759A6 /* Build configuration list for PBXNativeTarget "TinyEditor" */ = {
322 | isa = XCConfigurationList;
323 | buildConfigurations = (
324 | C006631724680B7000D759A6 /* Debug */,
325 | C006631824680B7000D759A6 /* Release */,
326 | );
327 | defaultConfigurationIsVisible = 0;
328 | defaultConfigurationName = Release;
329 | };
330 | /* End XCConfigurationList section */
331 | };
332 | rootObject = C00662FC24680B6D00D759A6 /* Project object */;
333 | }
334 |
--------------------------------------------------------------------------------
/TinyEditor/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
--------------------------------------------------------------------------------