├── CodeReader
├── Assets.xcassets
│ ├── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── Icon-16.png
│ │ ├── Icon-32.png
│ │ ├── Icon-33.png
│ │ ├── Icon-64.png
│ │ ├── Icon-1024.png
│ │ ├── Icon-128.png
│ │ ├── Icon-256.png
│ │ ├── Icon-257.png
│ │ ├── Icon-512.png
│ │ ├── Icon-513.png
│ │ └── Contents.json
│ └── AccentColor.colorset
│ │ └── Contents.json
├── CodeReader.entitlements
├── Info.plist
├── Core
│ ├── MenuItem.swift
│ ├── ClipboardManager.swift
│ ├── Persistence+Helper.swift
│ ├── Persistence.swift
│ └── ImageAnalyser.swift
├── UIHelpers
│ ├── NSDraggingInfo+FilePathURL.swift
│ ├── GradientView.swift
│ └── ARDropView.swift
├── AppDelegate.swift
├── ViewController.swift
└── Base.lproj
│ └── Main.storyboard
├── CodeReader.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── ibrahimhassan.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── ibrahimhassan.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── project.pbxproj
├── LICENSE
└── README.md
/CodeReader/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-16.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-32.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-33.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-64.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-1024.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-128.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-256.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-257.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-257.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-512.png
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-513.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader/Assets.xcassets/AppIcon.appiconset/Icon-513.png
--------------------------------------------------------------------------------
/CodeReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CodeReader/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/CodeReader.xcodeproj/xcuserdata/ibrahimhassan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/CodeReader.xcodeproj/project.xcworkspace/xcuserdata/ibrahimhassan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ibrahimhass/CodeReader/HEAD/CodeReader.xcodeproj/project.xcworkspace/xcuserdata/ibrahimhassan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CodeReader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CodeReader/CodeReader.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/CodeReader.xcodeproj/xcuserdata/ibrahimhassan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CodeReader.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/CodeReader/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSMainStoryboardFile
26 | Main
27 | NSPrincipalClass
28 | NSApplication
29 |
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Md Ibrahim Hassan
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 |
--------------------------------------------------------------------------------
/CodeReader/Core/MenuItem.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | struct MenuItem {
24 |
25 | var title: String
26 | var content: String
27 |
28 | init(title: String, content: String) {
29 | self.title = title
30 | self.content = content
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/CodeReader/Core/ClipboardManager.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Cocoa
24 |
25 | class ClipBoardManager {
26 |
27 | func copy(text: String) {
28 | let pasteboard = NSPasteboard.general
29 | pasteboard.clearContents()
30 | pasteboard.setString(text, forType: .string)
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/CodeReader/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-32.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "Icon-33.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-256.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "Icon-257.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 |
--------------------------------------------------------------------------------
/CodeReader/Core/Persistence+Helper.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | class PersistanceHelper {
24 |
25 | func getFileName(for content: String) -> String {
26 | String(content.prefix(10)) + ".txt"
27 | }
28 |
29 | func createMenuItem(for texts: [String]) -> [MenuItem] {
30 | return texts.map { text in
31 | MenuItem.init(title: getFileName(for: text), content: text)
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CodeReader/UIHelpers/NSDraggingInfo+FilePathURL.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2018 Axel Kee
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Foundation
24 | import AppKit
25 |
26 | extension NSDraggingInfo {
27 | var filePathURLs: [URL] {
28 | var filenames : [String]?
29 | var urls: [URL] = []
30 |
31 | if #available(OSX 10.13, *) {
32 | filenames = draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType("NSFilenamesPboardType")) as? [String]
33 | } else {
34 | // Fallback on earlier versions
35 | filenames = draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType("NSFilenamesPboardType")) as? [String]
36 | }
37 |
38 | if let filenames = filenames {
39 | for filename in filenames {
40 | urls.append(URL(fileURLWithPath: filename))
41 | }
42 | return urls
43 | }
44 |
45 | return []
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/CodeReader/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Cocoa
24 |
25 | @main
26 | class AppDelegate: NSObject, NSApplicationDelegate {
27 |
28 | @IBOutlet weak var menuHistory: NSMenuItem!
29 | private var menuItems: [MenuItem] = []
30 |
31 | func applicationDidFinishLaunching(_ aNotification: Notification) {
32 | // Insert code here to initialize your application
33 | for window in NSApplication.shared.windows {
34 | window.standardWindowButton(.zoomButton)?.isEnabled = false
35 | }
36 | refreshMenuBar()
37 | }
38 |
39 | func applicationWillTerminate(_ aNotification: Notification) {
40 | // Insert code here to tear down your application
41 | }
42 |
43 | func refreshMenuBar() {
44 | menuHistory.submenu?.items.removeAll()
45 | self.menuItems = Persistance().retrieve() ?? []
46 |
47 | for (index, item) in menuItems.enumerated() {
48 | let subItem = NSMenuItem()
49 | subItem.tag = index
50 | subItem.title = item.title
51 | subItem.action = #selector(AppDelegate.subItemSelected)
52 | menuHistory.submenu?.addItem(subItem)
53 | }
54 | }
55 |
56 | @objc func subItemSelected(_ sender: NSMenuItem) {
57 | ClipBoardManager().copy(text: menuItems[sender.tag].content)
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/CodeReader/Core/Persistence.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Foundation
24 |
25 | class Persistance {
26 |
27 | func save(_ str: String) {
28 | let filename = String(str.prefix(10)) + ".txt"
29 | let fileURL = getDocumentsDirectory().appendingPathComponent(filename)
30 |
31 | do {
32 | try str.write(to: fileURL, atomically: true, encoding: String.Encoding.utf8)
33 | } catch {
34 | // failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding
35 | }
36 | }
37 |
38 | func retrieve() -> [MenuItem]? {
39 | let documentsUrl = getDocumentsDirectory()
40 | do {
41 | // Get the directory contents urls (including subfolders urls)
42 | let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil)
43 | let strings = directoryContents.compactMap { (fileURL) -> String? in
44 | if let savedData = try? Data(contentsOf: fileURL),
45 | let savedString = String(data: savedData, encoding: .utf8) {
46 | return (savedString)
47 | }
48 | return nil
49 | }
50 |
51 | return (PersistanceHelper().createMenuItem(for: strings))
52 | } catch {
53 | print(error)
54 | }
55 | return nil
56 | }
57 |
58 | func getDocumentsDirectory() -> URL {
59 | let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
60 | return paths[0]
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/CodeReader/Core/ImageAnalyser.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Cocoa
24 | import Vision
25 | import CoreGraphics
26 |
27 | class ImageAnalyser {
28 |
29 | func analyseImage(image: NSImage, completion: @escaping (_ text: String) -> Void) {
30 | DispatchQueue.global(qos: .userInitiated).async {
31 | // Get the CGImage on which to perform requests.
32 | guard let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return }
33 | // Create a new image-request handler.
34 | let requestHandler = VNImageRequestHandler(cgImage: cgImage)
35 |
36 | // Create a new request to recognize text.
37 |
38 | var request = VNRecognizeTextRequest()
39 | request.recognitionLanguages = ["en"]
40 | request.recognitionLevel = .accurate
41 | request.usesLanguageCorrection = false
42 |
43 | request = VNRecognizeTextRequest { request, error in
44 | guard let observations =
45 | request.results as? [VNRecognizedTextObservation] else {
46 | return
47 | }
48 | let recognizedStrings = observations.compactMap { observation in
49 | // Return the string of the top VNRecognizedText instance.
50 | return observation.topCandidates(1).first?.string
51 | }
52 |
53 | DispatchQueue.main.async {
54 | completion(recognizedStrings.joined(separator: "\n"))
55 | }
56 | // Process the recognized strings.
57 | }
58 | do {
59 | // Perform the text-recognition request.
60 | try requestHandler.perform([request])
61 | } catch {
62 | print("Unable to perform the requests: \(error).")
63 | }
64 | }
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://swift.org/download/)
2 |
3 | # CodeReader
4 |
5 | A simple macOS app to read code from images, written purely in Swift using Vision Framework.
6 |
7 | # Usage
8 | 1) Drag an image
9 | 
10 | 2) Click the convert button
11 | 
12 |
13 | # Result
14 | ``` swift
15 | Converted by Storyboard to Swift Converter - https://swiftify.com/converter/storyboard2swiftui
16 | import Swiftul
17 | import Introspect
18 | // TODO: install 'SwiftUI-Introspect package from https://github.com/siteline/SwiftUI-Introspect
19 | // DefaultViewController
20 | 1/
21 | struct DefaultView: View {
22 | @State private var fullText: String
23 | var body: some View
24 | Stack( alignment: topLeading)
25 | GeometryReader { geometry
26 | TextField( "Placeholder", text: $fullText)
27 | introspectTextField (customize: { textField in
28 | textField.adjustsFontSizeToFitWidth = true
29 | extField. backgroundColor = UIColor. systemTeal
30 | textField. minimumFontSize = 17. 1
31 | textField. superview?. frame = CGRect(x: DynamicSizeHelper.get0ffsetX(20), y:
32 | DynamicSizeHelper-get0ffsetY(274), width: DynamicSizeHelper. getWidth(280), height:
33 | DynamicSizeHelper.getHeight(18.5))
34 | })
35 | . frame (width: DynamicSizeHelper. getWidth(280), height:
36 | DynamicSizeHelper.getHeight(18.5))
37 | . font (. system(size: , weight: . regular))
38 | .offset(x: DynamicSizeHelper.getoffsetX(20), DynamicSizeHelper.get0ffsetY(274))
39 | TextField( "Placeholder", text: $fullText)
40 | prospectTextField ( customize: t textField in
41 | textField.adjustsFontSizeToFitWidth=true
42 | textField. backgroundColor UIColor. systemRed
43 | textField. clearButtonMode = . whileEditing
44 | textField
45 | mFontSize = 17.0
46 | textField. uperview?. frame = CGRect (x: DynamicSizeHelper. getOffsetX(20), y:
47 | DynamicSizeHelper-get0ffsetY(202), width: DynamicSizeHelper.getWidth(280), height:
48 | DynamicSizeHelper.getHeight(26.5))
49 | }
50 | • frame(width: DynamicSizeHelper-getwidth(280), height :
51 | DynamicSizeHelper.getHeight(2
52 | font (. system(size: 14, weight: . regular))
53 | offset(x: DynamicSizeHelper.get0ffsetX(20), y: DynamicSizeHelper.getOffsetY(202))
54 | TextField("Placeholder", text: $fullText)
55 | introspectTextField( customize: { textField in
56 | textField. adjustsFontSizeToFitwidth = true
57 | textField. backgroundColor: : UIColor. systemPurple
58 | textField.clearButtonMode=.unlessEditing
59 | textField. minimumFontSize = 17. 0
60 | textField. superview?. frame = CGRect (x: DynamicSizeHelper.getOffsetX(20), y:
61 | DynamicSizeHelper-getoffsetY(136), width: DynamicSizeHelper.getWidth(280), height:
62 | DynamicSizeHelper.getHeight(28.5))
63 | F
64 | frame (width: DynamicSizeHelper.getWidth(280), height:
65 | DynamicSizeHelper-getHeight(28.5))
66 | font ( .
67 | (size: 14. weight: .regular))
68 | .offset(x: DynamicSizeHelper.get0ffsetX(20), y: DynamicSizeHelper.getOffsetY(136))
69 | TextField( "Placeholder", text: $fullText)
70 | textFieldStyle(RoundedBorderTextFieldStyle())
71 | introspectTextField(customize: textField in
72 | textField.adjustsFontSizeToFitWidth=true
73 | textField. backgroundColor = UIColor. systemOrange
74 | textField.clearButtonMode= always
75 | textField.minimumFontSize = 17.0
76 | })
77 | frame(width: DynamicsizeHelper-getWidth(280), height:
78 | DynamicSizeHelper.getHeight(34))
79 | font (. system (size: 14, weight: regular))
80 | .offset (x: DynamicSizeHelper.get0ffsetX(20), y: DynamicSizeHelper.getOffsetY(75))
81 | . frame(width: DynamicSizeHelper. getwidth(320), height: DynamicSizeHelper.getHeight(568))
82 | . background( Color (. systemBackground))
83 | dgesIgnoringSafeArea(.all)
84 | struct DefaultView_Previews: PreviewProvider {
85 | static var previews: some View
86 | DefaultView()
87 | Dynamic Size Helper
88 | struct DynamicSizeHelper {
89 | static private let baseViewWidth: CGFloat = 320.0
90 | static private
91 | t baseViewHeight:
92 | GFloat
93 | 568.(
94 | static func getHeight (_ height: CGFloat) -> CGFloat
95 | return (height baseViewHeight) * UIScreen. main. bounds. height
96 | static func getWidth(_ width: CGFloat) -> CGFloat
97 | return (width baseViewWidt
98 | UIScreen.
99 | in. bounds. width
100 | static func get0ffsetX(_ x: CGFloat) -> CGFloat
101 | return (x / baseViewWidth) * UIScreen. main. bounds. width
102 | }
103 | static func get0ffsetY(_ y: CGFloat) CGFloat
104 | return ( y / baseViewHeight)
105 | UIScreen.
106 | a. bounds. height
107 | ```
108 |
109 | # Build Requirements
110 |
111 | ## macOS
112 | macOS Catalina
113 |
114 | Download the App directly.
115 | https://github.com/Ibrahimhass/CodeReader/releases/download/1.0.2/CodeReader.zip
116 |
117 |
118 | ## Author
119 |
120 | Md Ibrahim Hassan, mdibrahimhassan@gmail.com
121 |
122 | ## License
123 |
124 | CodeReader is available under the MIT license. See the LICENSE file for more info.
125 |
--------------------------------------------------------------------------------
/CodeReader/UIHelpers/GradientView.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Cocoa
24 |
25 | class NSGradientView: NSView {
26 | var startPosition: CGFloat = 0.0
27 | var middlePosition: CGFloat = 1.1
28 | var endPosition: CGFloat = 1.0
29 |
30 | private func getRandomColor() -> [NSColor] {
31 | var gradientColors: [[NSColor]] = []
32 | var gradientColor: [NSColor] = []
33 |
34 | gradientColor.append(#colorLiteral(red: 0.23, green: 0.11, blue: 0.44, alpha: 1.00))
35 | gradientColor.append(#colorLiteral(red: 0.84, green: 0.43, blue: 0.47, alpha: 1.00))
36 | gradientColor.append(#colorLiteral(red: 1.00, green: 0.69, blue: 0.48, alpha: 1.00))
37 | gradientColors.append(gradientColor)
38 | gradientColor.removeAll()
39 |
40 | gradientColor.append(#colorLiteral(red: 0.50, green: 0.50, blue: 0.84, alpha: 1.00))
41 | gradientColor.append(#colorLiteral(red: 0.53, green: 0.66, blue: 0.91, alpha: 1.00))
42 | gradientColor.append(#colorLiteral(red: 0.57, green: 0.92, blue: 0.89, alpha: 1.00))
43 | gradientColors.append(gradientColor)
44 | gradientColor.removeAll(keepingCapacity: false)
45 |
46 | gradientColor.append(#colorLiteral(red: 0.99, green: 0.36, blue: 0.49, alpha: 1.00))
47 | gradientColor.append(#colorLiteral(red: 0.42, green: 0.51, blue: 0.98, alpha: 1.00))
48 | gradientColors.append(gradientColor)
49 | gradientColor.removeAll()
50 |
51 | gradientColor.append(#colorLiteral(red: 0.40, green: 0.70, blue: 0.44, alpha: 1.00))
52 | gradientColor.append(#colorLiteral(red: 0.30, green: 0.64, blue: 0.80, alpha: 1.00))
53 | gradientColors.append(gradientColor)
54 | gradientColor.removeAll()
55 |
56 | gradientColor.append(#colorLiteral(red: 1.00, green: 0.98, blue: 0.84, alpha: 1.00))
57 | gradientColor.append(#colorLiteral(red: 0.70, green: 0.04, blue: 0.17, alpha: 1.00))
58 | gradientColors.append(gradientColor)
59 | gradientColor.removeAll()
60 |
61 | gradientColor.append(#colorLiteral(red: 0.66, green: 0.75, blue: 1.00, alpha: 1.00))
62 | gradientColor.append(#colorLiteral(red: 0.25, green: 0.17, blue: 0.59, alpha: 1.00))
63 | gradientColors.append(gradientColor)
64 | gradientColor.removeAll()
65 |
66 | gradientColor.append(#colorLiteral(red: 0.66, green: 0.75, blue: 1.00, alpha: 1.00))
67 | gradientColor.append(#colorLiteral(red: 0.25, green: 0.17, blue: 0.59, alpha: 1.00))
68 | gradientColors.append(gradientColor)
69 | gradientColor.removeAll()
70 |
71 | gradientColor.append(#colorLiteral(red: 0.00, green: 0.35, blue: 0.65, alpha: 1.00))
72 | gradientColor.append(#colorLiteral(red: 1.00, green: 0.99, blue: 0.89, alpha: 1.00))
73 | gradientColors.append(gradientColor)
74 | gradientColor.removeAll()
75 |
76 | return gradientColors.randomElement()!
77 | }
78 |
79 |
80 | override open func draw(_ dirtyRect: NSRect) {
81 | super.draw(dirtyRect)
82 | let randomColor = getRandomColor()
83 | if randomColor.count == 2 {
84 | let bgGradient = NSGradient(colorsAndLocations: (randomColor[0], startPosition), (randomColor[1], endPosition))
85 | let path = NSBezierPath(rect: self.frame)
86 | bgGradient?.draw(in: path, angle: CGFloat(Float(arc4random()) / Float(UINT32_MAX)))
87 | } else if randomColor.count == 3 {
88 | let bgGradient = NSGradient(colorsAndLocations: (randomColor[0], startPosition),
89 | (randomColor[1], middlePosition),
90 | (randomColor[2], middlePosition)
91 | )
92 | let path = NSBezierPath(rect: self.frame)
93 | bgGradient?.draw(in: path, angle: 0)
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/CodeReader/UIHelpers/ARDropView.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2018 Axel Kee
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Cocoa
24 |
25 | public final class ADragDropView: NSView {
26 |
27 | // highlight the drop zone when mouse drag enters the drop view
28 | fileprivate var highlight : Bool = false
29 |
30 | // check if the dropped file type is accepted
31 | fileprivate var fileTypeIsOk = false
32 |
33 |
34 | /// Allowed file type extensions to drop, eg: ["png", "jpg", "jpeg"]
35 | public var acceptedFileExtensions : [String] = ["png", "jpg", "jpeg"]
36 |
37 | public weak var delegate: ADragDropViewDelegate?
38 |
39 | public required init?(coder: NSCoder) {
40 | super.init(coder: coder)
41 |
42 | if #available(OSX 10.13, *) {
43 | registerForDraggedTypes([NSPasteboard.PasteboardType.fileURL])
44 | } else {
45 | // Fallback on earlier versions
46 | registerForDraggedTypes([NSPasteboard.PasteboardType("NSFilenamesPboardType")])
47 | }
48 | }
49 |
50 | public override init(frame frameRect: NSRect) {
51 | super.init(frame: frameRect)
52 | }
53 |
54 | public override func draw(_ dirtyRect: NSRect) {
55 | super.draw(dirtyRect)
56 | }
57 |
58 | // MARK: - NSDraggingDestination
59 | public override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
60 | highlight = true
61 | fileTypeIsOk = isExtensionAcceptable(draggingInfo: sender)
62 |
63 | self.setNeedsDisplay(self.bounds)
64 | return []
65 | }
66 |
67 | public override func draggingExited(_ sender: NSDraggingInfo?) {
68 | highlight = false
69 | self.setNeedsDisplay(self.bounds)
70 | }
71 |
72 | public override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
73 | return fileTypeIsOk ? .copy : []
74 | }
75 |
76 | public override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool {
77 | // finished with dragging so remove any highlighting
78 | highlight = false
79 | self.setNeedsDisplay(self.bounds)
80 |
81 | return true
82 | }
83 |
84 | public override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
85 | if sender.filePathURLs.count == 0 {
86 | return false
87 | }
88 |
89 | if(fileTypeIsOk) {
90 | if sender.filePathURLs.count == 1 {
91 | delegate?.dragDropView(self, droppedFileWithURL: sender.filePathURLs.first!)
92 | } else {
93 | delegate?.dragDropView(self, droppedFilesWithURLs: sender.filePathURLs)
94 | }
95 | } else {
96 |
97 | }
98 |
99 | return true
100 | }
101 |
102 | fileprivate func isExtensionAcceptable(draggingInfo: NSDraggingInfo) -> Bool {
103 | if draggingInfo.filePathURLs.count == 0 {
104 | return false
105 | }
106 |
107 | for filePathURL in draggingInfo.filePathURLs {
108 | let fileExtension = filePathURL.pathExtension.lowercased()
109 |
110 | if !acceptedFileExtensions.contains(fileExtension){
111 | return false
112 | }
113 | }
114 |
115 | return true
116 | }
117 |
118 | public override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
119 | return true
120 | }
121 | }
122 |
123 | public protocol ADragDropViewDelegate: AnyObject {
124 | func dragDropView(_ dragDropView: ADragDropView, droppedFileWithURL URL: URL)
125 | func dragDropView(_ dragDropView: ADragDropView, droppedFilesWithURLs URLs: [URL])
126 | }
127 |
128 | extension ADragDropViewDelegate {
129 | func dragDropView(_ dragDropView: ADragDropView, droppedFileWithURL URL: URL) {
130 | }
131 |
132 | func dragDropView(_ dragDropView: ADragDropView, droppedFilesWithURLs URLs: [URL]) {
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/CodeReader/ViewController.swift:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2021 Md Ibrahim Hassan
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Cocoa
24 |
25 | class ViewController: NSViewController {
26 |
27 | @IBOutlet weak var visualEffectView: NSVisualEffectView!
28 | @IBOutlet var mainView: NSGradientView!
29 | @IBOutlet weak var pickedImageView: NSImageView!
30 | @IBOutlet weak var titleLabel: NSTextField!
31 | @IBOutlet var dragView: ADragDropView!
32 | @IBOutlet weak var convertButton: NSButton!
33 | @IBOutlet weak var activityIndicator: NSProgressIndicator!
34 |
35 | private var outputText: String = ""
36 |
37 | private var pickedImagesUrls: [URL] = []
38 |
39 | override func viewWillAppear() {
40 | super.viewWillAppear()
41 | activityIndicator.isHidden = true
42 | activityIndicator.controlTint = .graphiteControlTint
43 | checkAndActivateConvertButton()
44 | }
45 |
46 | private func checkAndActivateConvertButton() {
47 | convertButton.isEnabled = !pickedImagesUrls.isEmpty
48 | }
49 |
50 | override func viewDidLoad() {
51 | super.viewDidLoad()
52 | mainView.wantsLayer = true
53 | dragView.delegate = self
54 | setUpWindowSize()
55 | }
56 |
57 | override var representedObject: Any? {
58 | didSet {
59 | // Update the view, if already loaded.
60 | }
61 | }
62 |
63 | @IBAction func convertTapped(_ sender: NSButton) {
64 | if let imageUrl = pickedImagesUrls.last,
65 | let image = NSImage.init(contentsOf: imageUrl) {
66 | activityIndicator.isHidden = false
67 | activityIndicator.startAnimation(nil)
68 | ImageAnalyser().analyseImage(image: image, completion: { text in
69 | self.pickedImagesUrls = []
70 | self.activityIndicator.isHidden = true
71 | self.outputText = text
72 | self.showDailog()
73 | })
74 | }
75 | }
76 |
77 | func showDailog() {
78 | let copyAlert: NSAlert = NSAlert()
79 | copyAlert.messageText = "Code has been Converted"
80 | copyAlert.informativeText = "The image code has been converted"
81 | copyAlert.addButton(withTitle: "Copy")
82 | copyAlert.alertStyle = NSAlert.Style.informational
83 |
84 | if let window = self.view.window {
85 | copyAlert.beginSheetModal(for: window, completionHandler: { (modalResponse: NSApplication.ModalResponse) -> Void in
86 | if(modalResponse == NSApplication.ModalResponse.alertFirstButtonReturn){
87 | self.copyTappedAndSave()
88 | }
89 | })
90 | }
91 | }
92 |
93 | private func copyTappedAndSave() {
94 | ClipBoardManager().copy(text: self.outputText)
95 | Persistance().save(self.outputText)
96 | refreshMenuBar()
97 | prepareForNextConversion()
98 | }
99 |
100 | private func refreshMenuBar() {
101 | if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
102 | appDelegate.refreshMenuBar()
103 | }
104 | }
105 |
106 | private func prepareForNextConversion() {
107 | visualEffectView.isHidden = false
108 | titleLabel.stringValue = "Drop an image to convert its source code to text"
109 | pickedImageView.image = nil
110 | convertButton.title = "Convert"
111 | checkAndActivateConvertButton()
112 | }
113 | }
114 |
115 |
116 | //MARK: - Styling
117 | extension ViewController {
118 | private func setUpWindowSize() {
119 | self.view.window?.setFrame(NSRect(x:0,y:0,width: 480,height: 272), display: true)
120 | self.preferredContentSize = NSMakeSize(480, 272)
121 | let button = view.window?.standardWindowButton(NSWindow.ButtonType.zoomButton)
122 | button?.isEnabled = false
123 | }
124 | }
125 |
126 | extension ViewController: ADragDropViewDelegate {
127 | // when one file is dropped
128 | func dragDropView(_ dragDropView: ADragDropView, droppedFileWithURL URL: URL) {
129 | pickedImagesUrls.append(URL)
130 | pickedImageView.image = NSImage(contentsOf: URL)
131 | pickedImageView.imageScaling = .scaleProportionallyDown
132 | visualEffectView.isHidden = true
133 | checkAndActivateConvertButton()
134 | }
135 |
136 | // when multiple files are dropped
137 | func dragDropView(_ dragDropView: ADragDropView, droppedFilesWithURLs URLs: [URL]) {
138 | pickedImagesUrls = URLs
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/CodeReader/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/CodeReader.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | ED57E44C268B8E2500EC25D2 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED57E44B268B8E2500EC25D2 /* Persistence.swift */; };
11 | ED57E44E268B8F2700EC25D2 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED57E44D268B8F2700EC25D2 /* MenuItem.swift */; };
12 | ED57E450268B8F7C00EC25D2 /* Persistence+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED57E44F268B8F7C00EC25D2 /* Persistence+Helper.swift */; };
13 | ED57E452268B95D900EC25D2 /* ClipboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED57E451268B95D900EC25D2 /* ClipboardManager.swift */; };
14 | EDF732BD2688D4240069B630 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF732BC2688D4240069B630 /* AppDelegate.swift */; };
15 | EDF732BF2688D4240069B630 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF732BE2688D4240069B630 /* ViewController.swift */; };
16 | EDF732C12688D4260069B630 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EDF732C02688D4260069B630 /* Assets.xcassets */; };
17 | EDF732C42688D4260069B630 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EDF732C22688D4260069B630 /* Main.storyboard */; };
18 | EDF732CD2688D7F90069B630 /* ARDropView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF732CC2688D7F90069B630 /* ARDropView.swift */; };
19 | EDF732CF2688D8130069B630 /* NSDraggingInfo+FilePathURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF732CE2688D8130069B630 /* NSDraggingInfo+FilePathURL.swift */; };
20 | EDF732D12688DCB90069B630 /* ImageAnalyser.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF732D02688DCB90069B630 /* ImageAnalyser.swift */; };
21 | EDF732D3268904DF0069B630 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF732D2268904DF0069B630 /* GradientView.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXFileReference section */
25 | ED57E44B268B8E2500EC25D2 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; };
26 | ED57E44D268B8F2700EC25D2 /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; };
27 | ED57E44F268B8F7C00EC25D2 /* Persistence+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Persistence+Helper.swift"; sourceTree = ""; };
28 | ED57E451268B95D900EC25D2 /* ClipboardManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClipboardManager.swift; sourceTree = ""; };
29 | EDF732B92688D4240069B630 /* CodeReader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeReader.app; sourceTree = BUILT_PRODUCTS_DIR; };
30 | EDF732BC2688D4240069B630 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
31 | EDF732BE2688D4240069B630 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
32 | EDF732C02688D4260069B630 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
33 | EDF732C32688D4260069B630 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
34 | EDF732C52688D4260069B630 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
35 | EDF732C62688D4260069B630 /* CodeReader.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeReader.entitlements; sourceTree = ""; };
36 | EDF732CC2688D7F90069B630 /* ARDropView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARDropView.swift; sourceTree = ""; };
37 | EDF732CE2688D8130069B630 /* NSDraggingInfo+FilePathURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSDraggingInfo+FilePathURL.swift"; sourceTree = ""; };
38 | EDF732D02688DCB90069B630 /* ImageAnalyser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAnalyser.swift; sourceTree = ""; };
39 | EDF732D2268904DF0069B630 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; };
40 | /* End PBXFileReference section */
41 |
42 | /* Begin PBXFrameworksBuildPhase section */
43 | EDF732B62688D4240069B630 /* Frameworks */ = {
44 | isa = PBXFrameworksBuildPhase;
45 | buildActionMask = 2147483647;
46 | files = (
47 | );
48 | runOnlyForDeploymentPostprocessing = 0;
49 | };
50 | /* End PBXFrameworksBuildPhase section */
51 |
52 | /* Begin PBXGroup section */
53 | EDF732B02688D4240069B630 = {
54 | isa = PBXGroup;
55 | children = (
56 | EDF732BB2688D4240069B630 /* CodeReader */,
57 | EDF732BA2688D4240069B630 /* Products */,
58 | );
59 | sourceTree = "";
60 | };
61 | EDF732BA2688D4240069B630 /* Products */ = {
62 | isa = PBXGroup;
63 | children = (
64 | EDF732B92688D4240069B630 /* CodeReader.app */,
65 | );
66 | name = Products;
67 | sourceTree = "";
68 | };
69 | EDF732BB2688D4240069B630 /* CodeReader */ = {
70 | isa = PBXGroup;
71 | children = (
72 | EDF732BC2688D4240069B630 /* AppDelegate.swift */,
73 | EDF732BE2688D4240069B630 /* ViewController.swift */,
74 | EDF732D426890AC10069B630 /* UIHelpers */,
75 | EDF732D526890ACF0069B630 /* Core */,
76 | EDF732C02688D4260069B630 /* Assets.xcassets */,
77 | EDF732C22688D4260069B630 /* Main.storyboard */,
78 | EDF732C52688D4260069B630 /* Info.plist */,
79 | EDF732C62688D4260069B630 /* CodeReader.entitlements */,
80 | );
81 | path = CodeReader;
82 | sourceTree = "";
83 | };
84 | EDF732D426890AC10069B630 /* UIHelpers */ = {
85 | isa = PBXGroup;
86 | children = (
87 | EDF732D2268904DF0069B630 /* GradientView.swift */,
88 | EDF732CC2688D7F90069B630 /* ARDropView.swift */,
89 | EDF732CE2688D8130069B630 /* NSDraggingInfo+FilePathURL.swift */,
90 | );
91 | path = UIHelpers;
92 | sourceTree = "";
93 | };
94 | EDF732D526890ACF0069B630 /* Core */ = {
95 | isa = PBXGroup;
96 | children = (
97 | EDF732D02688DCB90069B630 /* ImageAnalyser.swift */,
98 | ED57E44B268B8E2500EC25D2 /* Persistence.swift */,
99 | ED57E44D268B8F2700EC25D2 /* MenuItem.swift */,
100 | ED57E44F268B8F7C00EC25D2 /* Persistence+Helper.swift */,
101 | ED57E451268B95D900EC25D2 /* ClipboardManager.swift */,
102 | );
103 | path = Core;
104 | sourceTree = "";
105 | };
106 | /* End PBXGroup section */
107 |
108 | /* Begin PBXNativeTarget section */
109 | EDF732B82688D4240069B630 /* CodeReader */ = {
110 | isa = PBXNativeTarget;
111 | buildConfigurationList = EDF732C92688D4260069B630 /* Build configuration list for PBXNativeTarget "CodeReader" */;
112 | buildPhases = (
113 | EDF732B52688D4240069B630 /* Sources */,
114 | EDF732B62688D4240069B630 /* Frameworks */,
115 | EDF732B72688D4240069B630 /* Resources */,
116 | );
117 | buildRules = (
118 | );
119 | dependencies = (
120 | );
121 | name = CodeReader;
122 | productName = CodeReader;
123 | productReference = EDF732B92688D4240069B630 /* CodeReader.app */;
124 | productType = "com.apple.product-type.application";
125 | };
126 | /* End PBXNativeTarget section */
127 |
128 | /* Begin PBXProject section */
129 | EDF732B12688D4240069B630 /* Project object */ = {
130 | isa = PBXProject;
131 | attributes = {
132 | LastSwiftUpdateCheck = 1250;
133 | LastUpgradeCheck = 1250;
134 | TargetAttributes = {
135 | EDF732B82688D4240069B630 = {
136 | CreatedOnToolsVersion = 12.5.1;
137 | };
138 | };
139 | };
140 | buildConfigurationList = EDF732B42688D4240069B630 /* Build configuration list for PBXProject "CodeReader" */;
141 | compatibilityVersion = "Xcode 9.3";
142 | developmentRegion = en;
143 | hasScannedForEncodings = 0;
144 | knownRegions = (
145 | en,
146 | Base,
147 | );
148 | mainGroup = EDF732B02688D4240069B630;
149 | productRefGroup = EDF732BA2688D4240069B630 /* Products */;
150 | projectDirPath = "";
151 | projectRoot = "";
152 | targets = (
153 | EDF732B82688D4240069B630 /* CodeReader */,
154 | );
155 | };
156 | /* End PBXProject section */
157 |
158 | /* Begin PBXResourcesBuildPhase section */
159 | EDF732B72688D4240069B630 /* Resources */ = {
160 | isa = PBXResourcesBuildPhase;
161 | buildActionMask = 2147483647;
162 | files = (
163 | EDF732C12688D4260069B630 /* Assets.xcassets in Resources */,
164 | EDF732C42688D4260069B630 /* Main.storyboard in Resources */,
165 | );
166 | runOnlyForDeploymentPostprocessing = 0;
167 | };
168 | /* End PBXResourcesBuildPhase section */
169 |
170 | /* Begin PBXSourcesBuildPhase section */
171 | EDF732B52688D4240069B630 /* Sources */ = {
172 | isa = PBXSourcesBuildPhase;
173 | buildActionMask = 2147483647;
174 | files = (
175 | ED57E452268B95D900EC25D2 /* ClipboardManager.swift in Sources */,
176 | ED57E450268B8F7C00EC25D2 /* Persistence+Helper.swift in Sources */,
177 | EDF732CF2688D8130069B630 /* NSDraggingInfo+FilePathURL.swift in Sources */,
178 | ED57E44E268B8F2700EC25D2 /* MenuItem.swift in Sources */,
179 | EDF732D12688DCB90069B630 /* ImageAnalyser.swift in Sources */,
180 | EDF732D3268904DF0069B630 /* GradientView.swift in Sources */,
181 | ED57E44C268B8E2500EC25D2 /* Persistence.swift in Sources */,
182 | EDF732BF2688D4240069B630 /* ViewController.swift in Sources */,
183 | EDF732CD2688D7F90069B630 /* ARDropView.swift in Sources */,
184 | EDF732BD2688D4240069B630 /* AppDelegate.swift in Sources */,
185 | );
186 | runOnlyForDeploymentPostprocessing = 0;
187 | };
188 | /* End PBXSourcesBuildPhase section */
189 |
190 | /* Begin PBXVariantGroup section */
191 | EDF732C22688D4260069B630 /* Main.storyboard */ = {
192 | isa = PBXVariantGroup;
193 | children = (
194 | EDF732C32688D4260069B630 /* Base */,
195 | );
196 | name = Main.storyboard;
197 | sourceTree = "";
198 | };
199 | /* End PBXVariantGroup section */
200 |
201 | /* Begin XCBuildConfiguration section */
202 | EDF732C72688D4260069B630 /* Debug */ = {
203 | isa = XCBuildConfiguration;
204 | buildSettings = {
205 | ALWAYS_SEARCH_USER_PATHS = NO;
206 | CLANG_ANALYZER_NONNULL = YES;
207 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
208 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
209 | CLANG_CXX_LIBRARY = "libc++";
210 | CLANG_ENABLE_MODULES = YES;
211 | CLANG_ENABLE_OBJC_ARC = YES;
212 | CLANG_ENABLE_OBJC_WEAK = YES;
213 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
214 | CLANG_WARN_BOOL_CONVERSION = YES;
215 | CLANG_WARN_COMMA = YES;
216 | CLANG_WARN_CONSTANT_CONVERSION = YES;
217 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
218 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
219 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
220 | CLANG_WARN_EMPTY_BODY = YES;
221 | CLANG_WARN_ENUM_CONVERSION = YES;
222 | CLANG_WARN_INFINITE_RECURSION = YES;
223 | CLANG_WARN_INT_CONVERSION = YES;
224 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
225 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
226 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
227 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
228 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
229 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
230 | CLANG_WARN_STRICT_PROTOTYPES = YES;
231 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
232 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
233 | CLANG_WARN_UNREACHABLE_CODE = YES;
234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
235 | COPY_PHASE_STRIP = NO;
236 | DEBUG_INFORMATION_FORMAT = dwarf;
237 | ENABLE_STRICT_OBJC_MSGSEND = YES;
238 | ENABLE_TESTABILITY = YES;
239 | GCC_C_LANGUAGE_STANDARD = gnu11;
240 | GCC_DYNAMIC_NO_PIC = NO;
241 | GCC_NO_COMMON_BLOCKS = YES;
242 | GCC_OPTIMIZATION_LEVEL = 0;
243 | GCC_PREPROCESSOR_DEFINITIONS = (
244 | "DEBUG=1",
245 | "$(inherited)",
246 | );
247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
249 | GCC_WARN_UNDECLARED_SELECTOR = YES;
250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
251 | GCC_WARN_UNUSED_FUNCTION = YES;
252 | GCC_WARN_UNUSED_VARIABLE = YES;
253 | MACOSX_DEPLOYMENT_TARGET = 11.3;
254 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
255 | MTL_FAST_MATH = YES;
256 | ONLY_ACTIVE_ARCH = YES;
257 | SDKROOT = macosx;
258 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
259 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
260 | };
261 | name = Debug;
262 | };
263 | EDF732C82688D4260069B630 /* Release */ = {
264 | isa = XCBuildConfiguration;
265 | buildSettings = {
266 | ALWAYS_SEARCH_USER_PATHS = NO;
267 | CLANG_ANALYZER_NONNULL = YES;
268 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
270 | CLANG_CXX_LIBRARY = "libc++";
271 | CLANG_ENABLE_MODULES = YES;
272 | CLANG_ENABLE_OBJC_ARC = YES;
273 | CLANG_ENABLE_OBJC_WEAK = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
279 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
280 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
281 | CLANG_WARN_EMPTY_BODY = YES;
282 | CLANG_WARN_ENUM_CONVERSION = YES;
283 | CLANG_WARN_INFINITE_RECURSION = YES;
284 | CLANG_WARN_INT_CONVERSION = YES;
285 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
286 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
287 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
288 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
289 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
290 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
291 | CLANG_WARN_STRICT_PROTOTYPES = YES;
292 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
293 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
294 | CLANG_WARN_UNREACHABLE_CODE = YES;
295 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
296 | COPY_PHASE_STRIP = NO;
297 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
298 | ENABLE_NS_ASSERTIONS = NO;
299 | ENABLE_STRICT_OBJC_MSGSEND = YES;
300 | GCC_C_LANGUAGE_STANDARD = gnu11;
301 | GCC_NO_COMMON_BLOCKS = YES;
302 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
303 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
304 | GCC_WARN_UNDECLARED_SELECTOR = YES;
305 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
306 | GCC_WARN_UNUSED_FUNCTION = YES;
307 | GCC_WARN_UNUSED_VARIABLE = YES;
308 | MACOSX_DEPLOYMENT_TARGET = 11.3;
309 | MTL_ENABLE_DEBUG_INFO = NO;
310 | MTL_FAST_MATH = YES;
311 | SDKROOT = macosx;
312 | SWIFT_COMPILATION_MODE = wholemodule;
313 | SWIFT_OPTIMIZATION_LEVEL = "-O";
314 | };
315 | name = Release;
316 | };
317 | EDF732CA2688D4260069B630 /* Debug */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
321 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
322 | CODE_SIGN_ENTITLEMENTS = CodeReader/CodeReader.entitlements;
323 | CODE_SIGN_STYLE = Automatic;
324 | COMBINE_HIDPI_IMAGES = YES;
325 | DEVELOPMENT_TEAM = RP4PNYFADM;
326 | ENABLE_HARDENED_RUNTIME = YES;
327 | INFOPLIST_FILE = CodeReader/Info.plist;
328 | LD_RUNPATH_SEARCH_PATHS = (
329 | "$(inherited)",
330 | "@executable_path/../Frameworks",
331 | );
332 | MACOSX_DEPLOYMENT_TARGET = 10.15;
333 | PRODUCT_BUNDLE_IDENTIFIER = com.demo.CodeReader;
334 | PRODUCT_NAME = "$(TARGET_NAME)";
335 | SWIFT_VERSION = 5.0;
336 | };
337 | name = Debug;
338 | };
339 | EDF732CB2688D4260069B630 /* Release */ = {
340 | isa = XCBuildConfiguration;
341 | buildSettings = {
342 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
343 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
344 | CODE_SIGN_ENTITLEMENTS = CodeReader/CodeReader.entitlements;
345 | CODE_SIGN_STYLE = Automatic;
346 | COMBINE_HIDPI_IMAGES = YES;
347 | DEVELOPMENT_TEAM = RP4PNYFADM;
348 | ENABLE_HARDENED_RUNTIME = YES;
349 | INFOPLIST_FILE = CodeReader/Info.plist;
350 | LD_RUNPATH_SEARCH_PATHS = (
351 | "$(inherited)",
352 | "@executable_path/../Frameworks",
353 | );
354 | MACOSX_DEPLOYMENT_TARGET = 10.15;
355 | PRODUCT_BUNDLE_IDENTIFIER = com.demo.CodeReader;
356 | PRODUCT_NAME = "$(TARGET_NAME)";
357 | SWIFT_VERSION = 5.0;
358 | };
359 | name = Release;
360 | };
361 | /* End XCBuildConfiguration section */
362 |
363 | /* Begin XCConfigurationList section */
364 | EDF732B42688D4240069B630 /* Build configuration list for PBXProject "CodeReader" */ = {
365 | isa = XCConfigurationList;
366 | buildConfigurations = (
367 | EDF732C72688D4260069B630 /* Debug */,
368 | EDF732C82688D4260069B630 /* Release */,
369 | );
370 | defaultConfigurationIsVisible = 0;
371 | defaultConfigurationName = Release;
372 | };
373 | EDF732C92688D4260069B630 /* Build configuration list for PBXNativeTarget "CodeReader" */ = {
374 | isa = XCConfigurationList;
375 | buildConfigurations = (
376 | EDF732CA2688D4260069B630 /* Debug */,
377 | EDF732CB2688D4260069B630 /* Release */,
378 | );
379 | defaultConfigurationIsVisible = 0;
380 | defaultConfigurationName = Release;
381 | };
382 | /* End XCConfigurationList section */
383 | };
384 | rootObject = EDF732B12688D4240069B630 /* Project object */;
385 | }
386 |
--------------------------------------------------------------------------------