├── .github
├── FUNDING.yml
└── workflows
│ └── swift.yml
├── .gitignore
├── .spi.yml
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Document
├── SKAsyncOperation.md
├── SKCrashReporter.md
├── SKDispatchFile.md
├── SKDispatchFileMonitor.md
├── SKFileLock.md
├── SKFinderExtension.md
├── SKMessagePort.md
├── SKNetworkInterface.md
├── SKNetworkMonitor.md
├── SKPermission.md
├── SKProcess.md
├── SKProcessMonitor.md
├── SKProtocol.md
├── SKSecurity.md
├── SKSignal.md
├── SKSystem.md
└── SKUserDefault.md
├── LICENSE
├── ObjcSources
└── Cryptor
│ ├── SKSecurity.h
│ └── SKSecurity.mm
├── Package.swift
├── README.md
└── Sources
├── Common
├── SKData+Extension.swift
├── SKDouble+Extension.swift
└── SKString+Extension.swift
├── Communication
├── SKMessagePort+Define.swift
└── SKMessagePort.swift
├── Dispatch
├── SKDispatchFile.swift
├── SKDispatchFileMonitor+Define.swift
├── SKDispatchFileMonitor.swift
├── SKDispatchTimer+Define.swift
└── SKDispatchTimer.swift
├── IO
├── SKIOBattery.swift
├── SKIOProcess.swift
├── SKIOResult.swift
├── SKIOReturn.swift
└── SKIOSystem.swift
├── Network
├── SKNetworkInterface.swift
├── SKNetworkInterfaceDefine.swift
├── SKNetworkMonitor.swift
└── SKNetworkMonitorDefine.swift
├── Permission
├── SKPermissionDefine.swift
└── SKPreferencePaneDefine.swift
├── PrivacyInfo.xcprivacy
├── Process
├── SKProcess.swift
├── SKProcessMonitor.swift
└── SKProcessMonitorDefine.swift
├── Protocol
├── SKClass+Protocol.swift
└── SKOperation+Protocol.swift
├── SKAsyncOperation.swift
├── SKAtomicValue.swift
├── SKCrashReporter.swift
├── SKFileLock.swift
├── SKFinderExtension.swift
├── SKSignal.swift
├── SKUserDefault.swift
├── System
├── SKSystem+iOS.swift
├── SKSystem+macOS.swift
├── SKSystem.swift
├── SKSystemDefine.swift
├── SKSystemProcessResource+Additions.swift
├── SKSystemProcessResource+Define.swift
├── SKSystemProcessResource.swift
├── SKSystemResource+Additions.swift
├── SKSystemResource+Define.swift
└── SKSystemResource.swift
└── SystemKit.swift
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/.github/workflows/swift.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Swift project
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift
3 |
4 | name: Swift
5 |
6 | on:
7 | push:
8 | branches: [ "main" ]
9 | pull_request:
10 | branches: [ "main" ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: macos-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v3
19 | - name: Build
20 | run: swift build -v
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/macos,swift,swiftpackagemanager,xcode,objective-c,git
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos,swift,swiftpackagemanager,xcode,objective-c,git
3 |
4 | ### Git ###
5 | # Created by git for backups. To disable backups in Git:
6 | # $ git config --global mergetool.keepBackup false
7 | *.orig
8 |
9 | # Created by git when using merge tools for conflicts
10 | *.BACKUP.*
11 | *.BASE.*
12 | *.LOCAL.*
13 | *.REMOTE.*
14 | *_BACKUP_*.txt
15 | *_BASE_*.txt
16 | *_LOCAL_*.txt
17 | *_REMOTE_*.txt
18 |
19 | ### macOS ###
20 | # General
21 | .DS_Store
22 | .AppleDouble
23 | .LSOverride
24 |
25 | # Icon must end with two \r
26 | Icon
27 |
28 |
29 | # Thumbnails
30 | ._*
31 |
32 | # Files that might appear in the root of a volume
33 | .DocumentRevisions-V100
34 | .fseventsd
35 | .Spotlight-V100
36 | .TemporaryItems
37 | .Trashes
38 | .VolumeIcon.icns
39 | .com.apple.timemachine.donotpresent
40 |
41 | # Directories potentially created on remote AFP share
42 | .AppleDB
43 | .AppleDesktop
44 | Network Trash Folder
45 | Temporary Items
46 | .apdisk
47 |
48 | ### macOS Patch ###
49 | # iCloud generated files
50 | *.icloud
51 |
52 | ### Objective-C ###
53 | # Xcode
54 | #
55 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
56 |
57 | ## User settings
58 | xcuserdata/
59 |
60 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
61 | *.xcscmblueprint
62 | *.xccheckout
63 |
64 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
65 | build/
66 | DerivedData/
67 | *.moved-aside
68 | *.pbxuser
69 | !default.pbxuser
70 | *.mode1v3
71 | !default.mode1v3
72 | *.mode2v3
73 | !default.mode2v3
74 | *.perspectivev3
75 | !default.perspectivev3
76 |
77 | ## Obj-C/Swift specific
78 | *.hmap
79 |
80 | ## App packaging
81 | *.ipa
82 | *.dSYM.zip
83 | *.dSYM
84 |
85 | # CocoaPods
86 | # We recommend against adding the Pods directory to your .gitignore. However
87 | # you should judge for yourself, the pros and cons are mentioned at:
88 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
89 | # Pods/
90 | # Add this line if you want to avoid checking in source code from the Xcode workspace
91 | # *.xcworkspace
92 |
93 | # Carthage
94 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
95 | # Carthage/Checkouts
96 |
97 | Carthage/Build/
98 |
99 | # fastlane
100 | # It is recommended to not store the screenshots in the git repo.
101 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
102 | # For more information about the recommended setup visit:
103 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
104 |
105 | fastlane/report.xml
106 | fastlane/Preview.html
107 | fastlane/screenshots/**/*.png
108 | fastlane/test_output
109 |
110 | # Code Injection
111 | # After new code Injection tools there's a generated folder /iOSInjectionProject
112 | # https://github.com/johnno1962/injectionforxcode
113 |
114 | iOSInjectionProject/
115 |
116 | ### Objective-C Patch ###
117 |
118 | ### Swift ###
119 | # Xcode
120 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
121 |
122 |
123 |
124 |
125 |
126 |
127 | ## Playgrounds
128 | timeline.xctimeline
129 | playground.xcworkspace
130 |
131 | # Swift Package Manager
132 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
133 | # Packages/
134 | # Package.pins
135 | # Package.resolved
136 | # *.xcodeproj
137 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
138 | # hence it is not needed unless you have added a package configuration file to your project
139 | # .swiftpm
140 |
141 | .build/
142 |
143 | # CocoaPods
144 | # We recommend against adding the Pods directory to your .gitignore. However
145 | # you should judge for yourself, the pros and cons are mentioned at:
146 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
147 | # Pods/
148 | # Add this line if you want to avoid checking in source code from the Xcode workspace
149 | # *.xcworkspace
150 |
151 | # Carthage
152 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
153 | # Carthage/Checkouts
154 |
155 |
156 | # Accio dependency management
157 | Dependencies/
158 | .accio/
159 |
160 | # fastlane
161 | # It is recommended to not store the screenshots in the git repo.
162 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
163 | # For more information about the recommended setup visit:
164 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
165 |
166 |
167 | # Code Injection
168 | # After new code Injection tools there's a generated folder /iOSInjectionProject
169 | # https://github.com/johnno1962/injectionforxcode
170 |
171 |
172 | ### SwiftPackageManager ###
173 | Packages
174 | xcuserdata
175 | *.xcodeproj
176 |
177 |
178 | ### Xcode ###
179 |
180 | ## Xcode 8 and earlier
181 |
182 | ### Xcode Patch ###
183 | *.xcodeproj/*
184 | !*.xcodeproj/project.pbxproj
185 | !*.xcodeproj/xcshareddata/
186 | !*.xcodeproj/project.xcworkspace/
187 | !*.xcworkspace/contents.xcworkspacedata
188 | /*.gcno
189 | **/xcshareddata/WorkspaceSettings.xcsettings
190 |
191 | # End of https://www.toptal.com/developers/gitignore/api/macos,swift,swiftpackagemanager,xcode,objective-c,git
192 |
--------------------------------------------------------------------------------
/.spi.yml:
--------------------------------------------------------------------------------
1 | version: 1
2 | builder:
3 | configs:
4 | - documentation_targets: [SystemKit]
5 | metadata:
6 | authors: “ChangYeop-Yang”
7 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Document/SKAsyncOperation.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKAsyncOperation
2 |
3 | `SKAsyncOperation`는 iOS 또는 macOS 플렛폼에서 공용적으로 사용할 수 있는 `Concurrent OperationQueue`를 효율적으로 사용할 수 있도록 기능을 제공합니다. `SKAsyncOperation`는 상속 (Inheritance)을 통해서 사용할 수 있습니다.
4 |
5 | # Example Source
6 |
7 | `SKAsyncOperation` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | public class CurrentOperation: SKAsyncOperation {
11 |
12 | override func start() {
13 | super.start()
14 |
15 | // 특정 작업을 수행할 수 있는 비즈니스 로직을 추가합니다.
16 | print("START")
17 | }
18 |
19 | override func cancel() {
20 | super.cancel()
21 |
22 | // 작업에 대하여 취소 작업 수행 로직을 추가합니다.
23 | print("CANCEL")
24 | }
25 | }
26 |
27 | let operation: Operation = CurrentOperation()
28 | OperationQueue().addOperation(operation)
29 | ```
30 |
31 | # License
32 |
33 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
34 |
35 |
36 |
37 | ```TEXT
38 | MIT License
39 |
40 | Copyright (c) 2022 Universal-SystemKit
41 |
42 | Permission is hereby granted, free of charge, to any person obtaining a copy
43 | of this software and associated documentation files (the "Software"), to deal
44 | in the Software without restriction, including without limitation the rights
45 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46 | copies of the Software, and to permit persons to whom the Software is
47 | furnished to do so, subject to the following conditions:
48 |
49 | The above copyright notice and this permission notice shall be included in all
50 | copies or substantial portions of the Software.
51 |
52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
58 | SOFTWARE.
59 | ```
60 |
--------------------------------------------------------------------------------
/Document/SKCrashReporter.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKCrashReporter
2 |
3 | `SKCrashReporter`는 iOS 또는 macOS 플렛폼에서 구동이되는 애플리케이션이 특정한 이유로 충돌 (Crash) 발생 시 관련 내용들을 파일 저장 또는 충돌 내용을 확인할 수 있는 기능을 제공합니다. 충돌이 발생하여 애플리케이션 (Application)이 종료되는 경우에는 종료직전 입력받은 `Callback`으로 `CompletionHandler`을 받으며 애플리케이션 재시작 시 충돌 내용이 저장 된 `.plcrash` 확장자를 가진 파일이 생성됩니다.
4 |
5 | * 해당 기능을 사용하기 위해서는 `Xcode Debug executable` 환경이 아닌 `Release` 모드에서만 구동이 됩니다.
6 |
7 | * `SKCrashReporter` 기능은 [PLCrashReporter](https://github.com/microsoft/plcrashreporter) 오픈소스를 사용하여 제공하는 기능입니다. 해당 오픈소스 라이센스는 `Copyright (c) Microsoft Corporation.`를 적용받습니다.
8 |
9 | # Example Source
10 |
11 | `SKCrashReporter` 예제 소스코드는 아래와 같습니다.
12 |
13 | ```Swift
14 | // SKCrashReporter Instance를 사용하기 위해서는 충돌파일을 저장하기 위한 폴더 경로 및 파일 이름을 매개변수로 전달합니다.
15 | let crashReport = SKCrashReporter(crashReportDirectory: "DIRECTORY_REPORT", crashReportFileName: "REPORT_NAME")
16 |
17 | // typedef void (*PLCrashReporterPostCrashSignalCallback)(siginfo_t *info, ucontext_t *uap, void *context);
18 | crashReport.enable(handleSignal: PLCrashReporterPostCrashSignalCallback)
19 |
20 | // SKCrashReporter 비활성화를 수행합니다.
21 | crashReport.disable()
22 | ```
23 |
24 | # License
25 |
26 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
27 |
28 |
29 |
30 | ```TEXT
31 | MIT License
32 |
33 | Copyright (c) 2022 Universal-SystemKit
34 |
35 | Permission is hereby granted, free of charge, to any person obtaining a copy
36 | of this software and associated documentation files (the "Software"), to deal
37 | in the Software without restriction, including without limitation the rights
38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39 | copies of the Software, and to permit persons to whom the Software is
40 | furnished to do so, subject to the following conditions:
41 |
42 | The above copyright notice and this permission notice shall be included in all
43 | copies or substantial portions of the Software.
44 |
45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
51 | SOFTWARE.
52 | ```
53 |
--------------------------------------------------------------------------------
/Document/SKDispatchFile.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKDispatchFile
2 |
3 | `SKDispatchFile`는 DispatchIO를 기반으로 파일 읽기 및 쓰기 작업에 대한 기능을 제공합니다. `SKDispatchFile`는 파일 잠금(file locking) 매커니즘을 기반으로 구현이 되어있어 쓰레드 안전 (Thread Safety)합니다.
4 |
5 | * 파일 잠금 (File Locking)은 오직 특정한 시간에 한 명의 사용자나 프로세스 접근만을 허용함으로써 컴퓨터 파일에 접근을 제한하는 구조입니다.
6 |
7 | # Example Source
8 |
9 | `SKDispatchFile` 예제 소스코드는 아래와 같습니다.
10 |
11 | ```Swift
12 | let dispatch = SKDispatchFile(qualityOfService: .background)
13 |
14 | // 파일 읽기 작업
15 | dispatch.read(filePath: "/Desktop/Symbols.txt") { contents, error in
16 | print(error)
17 | }
18 |
19 | // 파일 쓰기 작업
20 | let data = "A String".data(using: .utf8) ?? Data()
21 | dispatch.write(contents: data, filePath: "/Desktop/Example.txt") { error in
22 | print(error)
23 | }
24 | ```
25 |
26 | # License
27 |
28 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
29 |
30 |
31 |
32 | ```TEXT
33 | MIT License
34 |
35 | Copyright (c) 2023 Universal-SystemKit
36 |
37 | Permission is hereby granted, free of charge, to any person obtaining a copy
38 | of this software and associated documentation files (the "Software"), to deal
39 | in the Software without restriction, including without limitation the rights
40 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41 | copies of the Software, and to permit persons to whom the Software is
42 | furnished to do so, subject to the following conditions:
43 |
44 | The above copyright notice and this permission notice shall be included in all
45 | copies or substantial portions of the Software.
46 |
47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53 | SOFTWARE.
54 | ```
55 |
--------------------------------------------------------------------------------
/Document/SKDispatchFileMonitor.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKDispatchFileMonitor
2 |
3 | `SKDispatchFileMonitor`는 iOS 또는 macOS 플렛폼에서 공용적으로 사용할 수 있는 파일에 대한 이벤트를 감시하는 기능을 제공합니다.
4 |
5 | `SKDispatchFileMonitor` provides a common interface for monitoring file events on both iOS and macOS platforms.
6 |
7 | `DispatchSource.FileSystemEvent`에 대한 설명은 아래와 같습니다.
8 |
9 | - static let all: DispatchSource.FileSystemEvent → 파일에 대하여 모든 파일 이벤트를 수신받습니다.
10 |
11 | - static let attrib: DispatchSource.FileSystemEvent → 파일 메타 데이터 변경 이벤트를 수신받습니다.
12 |
13 | - static let delete: DispatchSource.FileSystemEvent → 파일 삭제 이벤트를 수신받습니다.
14 |
15 | - static let extend: DispatchSource.FileSystemEvent → 파일 크기 변경에 대한 이벤트를 수신받습니다.
16 |
17 | - static let funlock: DispatchSource.FileSystemEvent → 파일 Unlocking 이벤트를 수신받습니다.
18 |
19 | - static let link: DispatchSource.FileSystemEvent → 파일 Link Count 변경에 대한 이벤트를 수신받습니다.
20 |
21 | - static let rename: DispatchSource.FileSystemEvent → 파일 이름 변경에 대한 이벤트를 수신받습니다.
22 |
23 | - static let revoke: DispatchSource.FileSystemEvent → 파일 접근 권한 이벤트를 수신받습니다.
24 |
25 | - static let write: DispatchSource.FileSystemEvent → 파일에 대하여 데이터 쓰기 이벤트를 수신받습니다.
26 |
27 | # Example Source
28 |
29 | `SKDispatchFileMonitor` 예제 소스코드는 아래와 같습니다.
30 |
31 | ```Swift
32 | let eventMask: DispatchSource.FileSystemEvent = [.delete, .write]
33 | let monitor = SKDispatchFileMonitor(filePath: "FILE_PATH", eventMask: eventMask) { event in
34 | print(event)
35 | }
36 |
37 | // 지정 된 파일 경로에 대하여 파일 이벤트를 탐지합니다.
38 | monitor?.start()
39 |
40 | // 지정 된 파일 경로에 대하여 파일 이벤트 탐지를 중단합니다.
41 | monitor?.stop()
42 | ```
43 |
44 | # License
45 |
46 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
47 |
48 |
49 |
50 | ```TEXT
51 | MIT License
52 |
53 | Copyright (c) 2024 Universal-SystemKit
54 |
55 | Permission is hereby granted, free of charge, to any person obtaining a copy
56 | of this software and associated documentation files (the "Software"), to deal
57 | in the Software without restriction, including without limitation the rights
58 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59 | copies of the Software, and to permit persons to whom the Software is
60 | furnished to do so, subject to the following conditions:
61 |
62 | The above copyright notice and this permission notice shall be included in all
63 | copies or substantial portions of the Software.
64 |
65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
68 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
69 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
70 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
71 | SOFTWARE.
72 | ```
73 |
--------------------------------------------------------------------------------
/Document/SKFileLock.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKFileLock
2 |
3 | `SKFileLock`는 iOS 그리고 macOS 운영체제 환경에서 작동하며 오직 특정 시간에 단일 프로세스 접근만을 허용함으로써 컴퓨터 파일에 접근을 제한하는 기능을 제공합니다. `파일 읽기 (Read)`, `파일 쓰기 (Write)`, `파일 수정 (Modify)` 등의 작업을 할 수 있습니다.
4 |
5 | * [파일 잠금 (File Locking)](https://en.wikipedia.org/wiki/File_locking) → File locking is a mechanism that restricts access to a computer file, or to a region of a file, by allowing only one user or process to modify or delete it at a specific time and to prevent reading of the file while it's being modified or deleted.
6 |
7 | # Example Source
8 |
9 | `SKFileLock` 예제 소스코드는 아래와 같습니다.
10 |
11 | ```Swift
12 | // FileLockMode (.read, .write, update)
13 | let filePath = "/Users/~/Desktop/file.txt"
14 | let locker = SKFileLock(filePath: filePath, .read)
15 |
16 | // 파일 접근에 대하여 잠금 (Locking) 작업을 수행합니다.
17 | locker.lock()
18 |
19 | // 파일 접근에 대하여 잠금 해제 (UnLocking) 작업을 수행합니다.
20 | locker.unlock()
21 | ```
22 |
23 | # License
24 |
25 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
26 |
27 |
28 |
29 | ```TEXT
30 | MIT License
31 |
32 | Copyright (c) 2023 Universal-SystemKit
33 |
34 | Permission is hereby granted, free of charge, to any person obtaining a copy
35 | of this software and associated documentation files (the "Software"), to deal
36 | in the Software without restriction, including without limitation the rights
37 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38 | copies of the Software, and to permit persons to whom the Software is
39 | furnished to do so, subject to the following conditions:
40 |
41 | The above copyright notice and this permission notice shall be included in all
42 | copies or substantial portions of the Software.
43 |
44 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50 | SOFTWARE.
51 | ```
52 |
--------------------------------------------------------------------------------
/Document/SKFinderExtension.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKFinderExtension
2 |
3 | `SKFinderExtension`는 macOS 운영체제 환경에서 사용되는 Finder 확장 프로그램을 추가 (Append), 활성화 (Enable), 비활성화 (Disable), 활성화 여부 (isEnable)를 실행할 수 있습니다.
4 |
5 | # Example Source
6 |
7 | `SKFinderExtension` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | let result: bool = SKFinderExtension.shared.isExtensionEnabled
11 | print(result)
12 |
13 | // 확장 프로그램 활성화
14 | SKFinderExtension.shared.enable(extensionPath: "extensionPath", waitUntilExit: false)
15 |
16 | // 확장 프로그램 비활성화
17 | SKFinderExtension.shared.disable(extensionPath: "extensionPath", waitUntilExit: false)
18 |
19 | // 확장 프로그램 추가
20 | SKFinderExtension.shared.append(extensionPath: "extensionPath", waitUntilExit: false)
21 | ```
22 |
23 | # License
24 |
25 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
26 |
27 |
28 |
29 | ```TEXT
30 | MIT License
31 |
32 | Copyright (c) 2022 Universal-SystemKit
33 |
34 | Permission is hereby granted, free of charge, to any person obtaining a copy
35 | of this software and associated documentation files (the "Software"), to deal
36 | in the Software without restriction, including without limitation the rights
37 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38 | copies of the Software, and to permit persons to whom the Software is
39 | furnished to do so, subject to the following conditions:
40 |
41 | The above copyright notice and this permission notice shall be included in all
42 | copies or substantial portions of the Software.
43 |
44 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50 | SOFTWARE.
51 | ```
52 |
--------------------------------------------------------------------------------
/Document/SKMessagePort.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKMessagePort
2 |
3 | `SKMessagePort`는 주로 메시지 기반의 단방향 통신을 위해서 설계 되었으며 iOS 또는 macOS 플렛폼에서 로컬 장비 상에서 다중 쓰레드 및 프로세스들 간에 임의의 데이터를 전달하는 통신 채널을 제공합니다. 즉, 서로 다른 애플리케이션, 또는 애플리케이션과 프레임워크, 또는 서로 다른 프레임워크 사이의 통신을 할 수 있는 기능을 제공합니다.
4 |
5 |
6 |
7 | CFMessagePort는 아래의 주요한 메서드를 기반으로 동작합니다.
8 |
9 | * `CFMessagePortCreateLocal`: 로컬 메시지 포트를 생성합니다.
10 | * `CFMessagePortCreateRemote`: 원격 메시지 포트를 생성합니다.
11 | * `CFMessagePortSendRequest`: 원격 포트에 메시지를 전송합니다.
12 | * `CFMessagePortSetInvalidationCallBack`: 로컬 메시지 포트 또는 원격 메시지 포트가 무효화될 때 호출되는 콜백을 설정합니다.
13 | * `CFMessagePortInvalidate`: 로컬 메시지 포트 또는 원격 메시지 포트를 무효화합니다.
14 | * `CFMessagePortIsValid`: 로컬 메시지 포트 또는 원격 메시지 포트가 유효한지 확인합니다.
15 |
16 | # Example Source
17 |
18 | `SKMessagePort` 예제 소스코드는 아래와 같습니다.
19 |
20 | ```Swift
21 | // https://developer.apple.com/documentation/corefoundation/cfmessageportcallback
22 | let callback: CFMessagePortCallBack = { local, msgid, data, info -> Unmanaged? in
23 |
24 | let pointee = info?.assumingMemoryBound(to: ViewController.self).pointee
25 |
26 | /* here is processing data */
27 |
28 | return nil
29 | }
30 |
31 | // https://developer.apple.com/documentation/corefoundation/cfmessageportinvalidationcallback
32 | let callout: CFMessagePortInvalidationCallBack = { local, info in
33 |
34 | /* here is processing invaild local port */
35 | }
36 |
37 | let messagePort = SKMessagePort(portName: "com.message.port", callout)
38 |
39 | messagePort.listen(dispatch: .global(qos: .userInitiated), info: self, callback)
40 |
41 | messagePort.send(messageID: 777, message: "Hello World!".data(using: .utf8)!)
42 |
43 | messagePort.invalidate()
44 | ```
45 |
46 | # License
47 |
48 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
49 |
50 |
51 |
52 | ```TEXT
53 | MIT License
54 |
55 | Copyright (c) 2022 SystemKit
56 |
57 | Permission is hereby granted, free of charge, to any person obtaining a copy
58 | of this software and associated documentation files (the "Software"), to deal
59 | in the Software without restriction, including without limitation the rights
60 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61 | copies of the Software, and to permit persons to whom the Software is
62 | furnished to do so, subject to the following conditions:
63 |
64 | The above copyright notice and this permission notice shall be included in all
65 | copies or substantial portions of the Software.
66 |
67 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
72 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
73 | SOFTWARE.
74 | ```
75 |
--------------------------------------------------------------------------------
/Document/SKNetworkInterface.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKNetworkInterface
2 |
3 | `SKNetworkInterface`는 iOS 운영체제 또는 macOS 운영체제 환경에서
4 |
5 | # Example Source
6 |
7 | `SKNetworkInterface` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | ```
11 |
12 | # License
13 |
14 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
15 |
16 |
17 |
18 | ```TEXT
19 | MIT License
20 |
21 | Copyright (c) 2022 Universal-SystemKit
22 |
23 | Permission is hereby granted, free of charge, to any person obtaining a copy
24 | of this software and associated documentation files (the "Software"), to deal
25 | in the Software without restriction, including without limitation the rights
26 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 | copies of the Software, and to permit persons to whom the Software is
28 | furnished to do so, subject to the following conditions:
29 |
30 | The above copyright notice and this permission notice shall be included in all
31 | copies or substantial portions of the Software.
32 |
33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39 | SOFTWARE.
40 | ```
41 |
--------------------------------------------------------------------------------
/Document/SKNetworkMonitor.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKNetworkMonitor
2 |
3 | `SKNetworkMonitor`는 iOS 운영체제 또는 macOS 운영체제 환경에서 네트워크 환경 (WiFi, Ethernet, Cellular, LoopBack 등)에 대한 정보를 얻을 수 있도록 기능을 제공합니다.
4 |
5 | # Example Source
6 |
7 | `SKNetworkMonitor` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | // 네트워크 상태에 대한 정보 수집을 종료합니다.
11 | let monitor = SKNetworkMonitor { result in
12 |
13 | // NWPath 정보를 가져옵니다.
14 | print(result.newPath)
15 |
16 | // 네트워크 상태 정보를 가져옵니다.
17 | print(result.status)
18 |
19 | // 네트워크 연결 상태를 가져옵니다.
20 | print(result.connectionType)
21 | }
22 |
23 | // 네트워크 상태에 대한 정보 수집을 시작합니다.
24 | monitor.startMonitor()
25 |
26 | // 네트워크 상태에 대한 정보 수집을 종료합니다.
27 | monitor.stopMonitor()
28 | ```
29 |
30 | # License
31 |
32 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
33 |
34 |
35 |
36 | ```TEXT
37 | MIT License
38 |
39 | Copyright (c) 2022 Universal-SystemKit
40 |
41 | Permission is hereby granted, free of charge, to any person obtaining a copy
42 | of this software and associated documentation files (the "Software"), to deal
43 | in the Software without restriction, including without limitation the rights
44 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45 | copies of the Software, and to permit persons to whom the Software is
46 | furnished to do so, subject to the following conditions:
47 |
48 | The above copyright notice and this permission notice shall be included in all
49 | copies or substantial portions of the Software.
50 |
51 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
57 | SOFTWARE.
58 | ```
59 |
--------------------------------------------------------------------------------
/Document/SKPermission.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKPermission
2 |
3 | `SKPermission`는 iOS 또는 macOS 운영체제에서 애플리케이션 구동에 필요 한 다양한 권한 [`파일 및 폴더 권한 (Files and Folders)`, `전체 디스크 접근 권한 (Full Disk Access)`, `사진 (Photos)`, `연락처 (AddressBook)`, `블루투스 (Bluetooth)`, `캘린더 (Calendar)`] 등을 손쉽게 관리할 수 있습니다.
4 |
5 | # Example Source
6 |
7 | `SKPermission` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | // 공유하기 환경설정 페이지를 표시합니다.
11 | SKSystem.shared.openPreferencePane(path: SKSharingPreferencePane.Main.rawValue)
12 |
13 | // Screentime 환경설정 페이지를 표시합니다.
14 | SKPermission.shared.openPreferencePane(path: SKDefaultPreferencePane.Screentime.rawValue)
15 |
16 | // 전체 디스크 접근 권한 (Full Disk Access) 여부를 확인합니다.
17 | let isPermission: Bool = SKPermission.shared.isFullDiskAccessPermission()
18 | print(isPermission)
19 |
20 | // com.apple.Terminal 애플리케이션 권한을 제거합니다.
21 | SKPermission.shared.managePrivacyPermission(service: .SystemPolicyDesktopFolder, bundlePath: "com.apple.Terminal")
22 | ```
23 |
24 | # License
25 |
26 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
27 |
28 |
29 |
30 | ```TEXT
31 | MIT License
32 |
33 | Copyright (c) 2022 Universal-SystemKit
34 |
35 | Permission is hereby granted, free of charge, to any person obtaining a copy
36 | of this software and associated documentation files (the "Software"), to deal
37 | in the Software without restriction, including without limitation the rights
38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39 | copies of the Software, and to permit persons to whom the Software is
40 | furnished to do so, subject to the following conditions:
41 |
42 | The above copyright notice and this permission notice shall be included in all
43 | copies or substantial portions of the Software.
44 |
45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
51 | SOFTWARE.
52 | ```
53 |
--------------------------------------------------------------------------------
/Document/SKProcess.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKProcess
2 |
3 | `SKProcess`는 macOS 운영체제 환경을 기반으로 `Process` Class를 사용하여 스크립트 (Script) 또는 응용 프로그램 (Application)을 실행할 수 있습니다.
4 |
5 | # Example Source
6 |
7 | `SKProcess` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | let arguments: Array = ["-e", "use", "-i", "extensionPath"]
11 | SKProcess.shared.run(launchPath: "launchPath", arguments: arguments, waitUntilExit: true)
12 |
13 | let standardError: Pipe = Pipe()
14 | let arguments: [String] = ["-a", "-vvv", "-t", "install", "atPath"]
15 | SKProcess.shared.run(launchPath: "/usr/sbin/spctl", arguments: arguments, standardError: standardError, terminationHandler: terminationHandler)
16 | ```
17 |
18 | # License
19 |
20 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
21 |
22 |
23 |
24 | ```TEXT
25 | MIT License
26 |
27 | Copyright (c) 2022 Universal-SystemKit
28 |
29 | Permission is hereby granted, free of charge, to any person obtaining a copy
30 | of this software and associated documentation files (the "Software"), to deal
31 | in the Software without restriction, including without limitation the rights
32 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33 | copies of the Software, and to permit persons to whom the Software is
34 | furnished to do so, subject to the following conditions:
35 |
36 | The above copyright notice and this permission notice shall be included in all
37 | copies or substantial portions of the Software.
38 |
39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
45 | SOFTWARE.
46 | ```
47 |
--------------------------------------------------------------------------------
/Document/SKProcessMonitor.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKProcessMonitor
2 |
3 | `SKProcessMonitor`는 `macOS` 운영체제 프로세스 (Process) 상태를 추적하여 Handling 할 수 있도록 기능을 제공합니다.
4 |
5 | 프로세스 (Process) 상태를 추적할 수 있는 상태 값은 아래와 같습니다.
6 |
7 | - 실행 (exec): Process Exec'd
8 |
9 | - 종료 (exit): Process Exited
10 |
11 | - 복제 (fork): Process Forked
12 |
13 | # Example Source
14 |
15 | `SKProcessMonitor` 예제 소스코드는 아래와 같습니다.
16 |
17 | ```Swift
18 | let monitor = SKProcessMonitor(pid: 3447, fflag: .exit) { decriptor, flag, rawValue in
19 | print("Receive Process Monitor: \(decriptor), \(flag), \(rawValue)")
20 | }
21 |
22 | OperationQueue.main.addOperation(monitor)
23 |
24 | // Advises the operation object that it should stop executing its task.
25 | monitor.cancel()
26 | ```
27 |
28 | # License
29 |
30 | `Universal SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
31 |
32 |
33 |
34 | ```TEXT
35 | MIT License
36 |
37 | Copyright (c) 2022 Universal-SystemKit
38 |
39 | Permission is hereby granted, free of charge, to any person obtaining a copy
40 | of this software and associated documentation files (the "Software"), to deal
41 | in the Software without restriction, including without limitation the rights
42 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43 | copies of the Software, and to permit persons to whom the Software is
44 | furnished to do so, subject to the following conditions:
45 |
46 | The above copyright notice and this permission notice shall be included in all
47 | copies or substantial portions of the Software.
48 |
49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55 | SOFTWARE.
56 | ```
57 |
--------------------------------------------------------------------------------
/Document/SKProtocol.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKProtocol
2 |
3 | # Example Source
4 |
5 | `SKProtocol` 예제 소스코드는 아래와 같습니다.
6 |
7 | ```Swift
8 |
9 | ```
10 |
11 | # License
12 |
13 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
14 |
15 |
16 |
17 | ```TEXT
18 | MIT License
19 |
20 | Copyright (c) 2022 Universal-SystemKit
21 |
22 | Permission is hereby granted, free of charge, to any person obtaining a copy
23 | of this software and associated documentation files (the "Software"), to deal
24 | in the Software without restriction, including without limitation the rights
25 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 | copies of the Software, and to permit persons to whom the Software is
27 | furnished to do so, subject to the following conditions:
28 |
29 | The above copyright notice and this permission notice shall be included in all
30 | copies or substantial portions of the Software.
31 |
32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 | SOFTWARE.
39 | ```
40 |
--------------------------------------------------------------------------------
/Document/SKSecurity.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKSecurity
2 |
3 | `SKSecurity`는 고급 암호화 표준 (Advanced Encryption Standard, AES)를 기반으로 입력받은 데이터를 `AES-128`, `AES-192`, `AES-256`들의 대칭키 (Symmetric) 크기를 바탕으로 암호화 또는 복호화 작업을 수행할 수 있습니다. 또한, CBC (Cipher Block Chaining mode) 기반으로 동작하기에 초기화 백터 값이 필요합니다.
4 |
5 |
6 |
7 | * AES (Advanced Encryption Standard) 암호화 기법에 대한 자세한 설명은 [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) 확인 부탁드립니다.
8 |
9 |
10 |
11 | 고급 암호화 표준 (Advanced Encryption Standard, AES) 키의 크기 제약 조건은 아래를 반드시 지켜야 합니다.
12 |
13 | * An AES 128-bit key can be expressed as a hexadecimal string with 32 characters. It will require 24 characters in base64.
14 |
15 | * An AES 192-bit key can be expressed as a hexadecimal string with 48 characters. It will require 32 characters in base64.
16 |
17 | * An AES 256-bit key can be expressed as a hexadecimal string with 64 characters. It will require 44 characters in base64.
18 |
19 | # Example Source
20 |
21 | `SKSecurity` 예제 소스코드는 아래와 같습니다.
22 |
23 | ```Swift
24 | // AES 암호화를 수행하기 위한 IV를 생성합니다.
25 | let iv = SKSecurity.shared().createInitializationVector()
26 | print(iv)
27 |
28 | let key = "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
29 |
30 | // AES 암호화를 수행하기 위한 평문을 생성합니다.
31 | if let rawData = "PASSWORD".data(using: .utf8) {
32 |
33 | // AES 암호화를 수행합니다.
34 | let encrypted = SKSecurity.shared().encrypt(key, .AES256, iv, rawData)
35 |
36 | // AES 복호화를 수행합니다.
37 | let decrypted = SKSecurity.shared().decrypt(key, .AES256, iv, encrypted)
38 | print(String(data: decrypted, encoding: .utf8))
39 | }
40 | ```
41 |
42 | # License
43 |
44 | `Universal SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
45 |
46 |
47 |
48 | ```TEXT
49 | MIT License
50 |
51 | Copyright (c) 2022 Universal-SystemKit
52 |
53 | Permission is hereby granted, free of charge, to any person obtaining a copy
54 | of this software and associated documentation files (the "Software"), to deal
55 | in the Software without restriction, including without limitation the rights
56 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57 | copies of the Software, and to permit persons to whom the Software is
58 | furnished to do so, subject to the following conditions:
59 |
60 | The above copyright notice and this permission notice shall be included in all
61 | copies or substantial portions of the Software.
62 |
63 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
68 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
69 | SOFTWARE.
70 | ```
71 |
--------------------------------------------------------------------------------
/Document/SKSignal.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKSignal
2 |
3 | `SKSignal`는 `macOS` 운영체제에서 쓰이는 제한된 형태의 프로세스 간 통신을 위해서 사용하는 `신호 (Signal)`을 손쉽게 Handling 할 수 있도록 기능을 제공합니다. `신호 (Signal)` 관련하여 추가적인 정보는 [POSIX Signal](https://en.wikipedia.org/wiki/Signal_(IPC))에서 확인할 수 있습니다.
4 |
5 | # Example Source
6 |
7 | `SKSignal` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | let signal = SKSignal(signal: SIGUSR1) { number in
11 | print("Receive Signal: \(number)")
12 | }
13 |
14 | OperationQueue.main.addOperation(signal)
15 |
16 | // Advises the operation object that it should stop executing its task.
17 | signal.cancel()
18 | ```
19 |
20 | # License
21 |
22 | `Universal SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
23 |
24 |
25 |
26 | ```TEXT
27 | MIT License
28 |
29 | Copyright (c) 2022 Universal-SystemKit
30 |
31 | Permission is hereby granted, free of charge, to any person obtaining a copy
32 | of this software and associated documentation files (the "Software"), to deal
33 | in the Software without restriction, including without limitation the rights
34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35 | copies of the Software, and to permit persons to whom the Software is
36 | furnished to do so, subject to the following conditions:
37 |
38 | The above copyright notice and this permission notice shall be included in all
39 | copies or substantial portions of the Software.
40 |
41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
47 | SOFTWARE.
48 | ```
49 |
--------------------------------------------------------------------------------
/Document/SKSystem.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKSystem
2 |
3 | `SKSystem`는 iOS 또는 macOS 플렛폼에서 공용적으로 사용할 수 있도록 시스템 정보 (운영체제, 시스템, 메모리, 중앙 처리 장치, 프로젝트 버전 등)을 손쉽게 가져올 수 있습니다. 또한, 플랫폼에 구애받지 않고 공통적으로 사용할 수 있는 기능을 제공합니다.
4 |
5 | # Example Source
6 |
7 | `SKSystem` 예제 소스코드는 아래와 같습니다.
8 |
9 | ```Swift
10 | // 현재 프로세스를 실행 시킨 작업 대상이 Debug 형태로 실행이 되었는 경우를 확인합니다.
11 | let result = SKSystem.shared.getBeingDebugged(pid: pid)
12 | print(result ? "DEBUG" : "NON DEBUG")
13 |
14 | // 운영체제가 구동 중인 장비에 대한 정보를 가져옵니다.
15 | let resultA = SKSystem.shared.getMachineSystemInfo()
16 | print(resultA)
17 |
18 | // 현재 구동중인 macOS 운영체제 시스템 버전 (System Version) 정보를 가져옵니다.
19 | let resultB = SKSystem.shared.getOperatingSystemVersion()
20 | print(resultB)
21 |
22 | // 현재 구동중인 애플리케이션에 대한 `릴리즈 버전 (Release Version` 그리고 `번들 버전 (Bundle Version)` 정보를 가져옵니다.
23 | let resultC = SKSystem.shared.getApplicationVersion()
24 | print(resultC)
25 |
26 | // 현재 장비에서 사용하고 있는 `메모리 (Memory)` 정보를 가져옵니다.
27 | let resultD = SKSystem.SKSystemMemoryResult()
28 | print(resultD)
29 |
30 | // 현재 장비에서 사용하고 있는 `처리 장치 (Central/Main processor)` 정보를 가져옵니다.
31 | let resultE = SKSystem.SKSystemMainControlResult()
32 | print(resultE)
33 |
34 | // 현재 장비에서 사용하고 있는 `전지 (Battery)` 정보를 가져옵니다.
35 | let resultF = SKSystem.SKBatteryResult()
36 | print(resultF)
37 |
38 | // 현재 iPhone 디바이스가 네트워크에 연결 된 기술 타입 정보를 가져옵니다.
39 | let result = SKSystem.shared.getCurrentRadioAccessTechnology()
40 | print(result)
41 | ```
42 |
43 | # License
44 |
45 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
46 |
47 |
48 |
49 | ```TEXT
50 | MIT License
51 |
52 | Copyright (c) 2022 Universal-SystemKit
53 |
54 | Permission is hereby granted, free of charge, to any person obtaining a copy
55 | of this software and associated documentation files (the "Software"), to deal
56 | in the Software without restriction, including without limitation the rights
57 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
58 | copies of the Software, and to permit persons to whom the Software is
59 | furnished to do so, subject to the following conditions:
60 |
61 | The above copyright notice and this permission notice shall be included in all
62 | copies or substantial portions of the Software.
63 |
64 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
68 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
69 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
70 | SOFTWARE.
71 | ```
72 |
--------------------------------------------------------------------------------
/Document/SKUserDefault.md:
--------------------------------------------------------------------------------
1 | # 🗂 SKUserDefault
2 |
3 | `SKUserDefault`는 `@propertyWrapper` 사용하여 개발자가 보다 손쉽게 `UserDefaults` 사용할 수 있도록 개발되었습니다. 그러므로 [UserDefaults - Apple Developer Documentation](https://developer.apple.com/documentation/foundation/userdefaults)에서 사용할 수 있는 다양한 자료형을 처리할 수 있습니다.
4 |
5 | 아래의 예제 소스코드 이외에도 `Object`, `URL`, `Array`, `Dictionary`, `String`, `Data`, `Bool`, `Integer`, `Float`, `Double` 등의 자료형을 지원합니다.
6 |
7 | # Example Source
8 |
9 | `SKUserDefault` 예제 소스코드는 아래와 같습니다.
10 |
11 | ```Swift
12 | // Usage String UserDefaults
13 | @SKUserDefaults(forKey: "SKUserDefault_TEST_STRING", defaultValue: "TEST")
14 | private var defaultsString: Optional
15 |
16 | self.defaultsString = "SKUserDefault_PRINT"
17 | printf(self.defaultsString)
18 |
19 | // Usage Integer UserDefaults
20 | @SKUserDefaults(forKey: "SKUserDefault_TEST_INTEGER", defaultValue: 3540)
21 | private var defaultsInteger: Optional
22 |
23 | self.defaultsInteger = 8557
24 | printf(self.defaultsInteger)
25 |
26 | // Usage Double UserDefaults
27 | @SKUserDefaults(forKey: "SKUserDefault_TEST_DOUBLE", defaultValue: 3.14)
28 | private var defaultsDouble: Optional
29 |
30 | self.defaultsInteger = 41.3
31 | printf(self.defaultsDouble)
32 | ```
33 |
34 | # License
35 |
36 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
37 |
38 |
39 |
40 | ```TEXT
41 | MIT License
42 |
43 | Copyright (c) 2022 Universal-SystemKit
44 |
45 | Permission is hereby granted, free of charge, to any person obtaining a copy
46 | of this software and associated documentation files (the "Software"), to deal
47 | in the Software without restriction, including without limitation the rights
48 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
49 | copies of the Software, and to permit persons to whom the Software is
50 | furnished to do so, subject to the following conditions:
51 |
52 | The above copyright notice and this permission notice shall be included in all
53 | copies or substantial portions of the Software.
54 |
55 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
61 | SOFTWARE.
62 | ```
63 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Universal-SystemKit
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 |
--------------------------------------------------------------------------------
/ObjcSources/Cryptor/SKSecurity.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #import
24 | #import
25 |
26 | NS_ASSUME_NONNULL_BEGIN
27 |
28 | #pragma mark - Define Enum
29 | typedef NS_ENUM(size_t, SKSecurityAESType) {
30 |
31 | /// AES-128의 경우 128 Bit의 대칭키를 쓰는 암호화 알고리즘
32 | AES128 = kCCKeySizeAES128,
33 |
34 | /// AES-192의 경우 192 Bit의 대칭키를 쓰는 암호화 알고리즘
35 | AES192 = kCCKeySizeAES192,
36 |
37 | /// AES-256의 경우 256 Bit의 대칭키를 쓰는 암호화 알고리
38 | AES256 = kCCKeySizeAES256
39 | };
40 |
41 | typedef NS_ENUM(NSInteger, SKSecurityCryptType) {
42 |
43 | /// 암호화 (Encryption)
44 | Encrypt = 0,
45 |
46 | /// 복호화
47 | Decrypt = 1
48 | };
49 |
50 | @interface SKSecurity : NSObject
51 |
52 | #pragma mark - Define Public Properties
53 | + (instancetype) shared;
54 |
55 | #pragma mark - Define Public Instance Method
56 | - (nonnull NSData *) encrypt: (nonnull NSString *) key
57 | : (const SKSecurityAESType) keyType
58 | : (nonnull NSString *) iv
59 | : (nonnull NSData *) data;
60 |
61 | - (nonnull NSData *) decrypt: (nonnull NSString *) key
62 | : (const SKSecurityAESType) keyType
63 | : (nonnull NSString *) iv
64 | : (nonnull NSData *) data;
65 |
66 | - (nonnull NSString *) createInitializationVector;
67 |
68 | @end
69 |
70 | NS_ASSUME_NONNULL_END
71 |
--------------------------------------------------------------------------------
/ObjcSources/Cryptor/SKSecurity.mm:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #import "SKSecurity.h"
24 |
25 | @interface SKSecurity()
26 |
27 | #pragma mark - Define Private Instance Method
28 | - (nonnull const char *) copyPointer: (const size_t) length
29 | : (nonnull const NSString *) target;
30 |
31 | - (nullable NSData *) getDataByStatus: (CCCryptorStatus) status
32 | : (nonnull void *) dataWithBytes
33 | : (size_t) length;
34 |
35 | - (nullable NSData *) crypt: (const NSString *) key
36 | : (const SKSecurityAESType) keySize
37 | : (const NSString *) iv
38 | : (const NSData *) data
39 | : (const CCOperation) operation;
40 |
41 | @end
42 |
43 | @implementation SKSecurity
44 |
45 | #pragma mark - Public Instance Method
46 | + (instancetype) shared {
47 |
48 | static SKSecurity * shared = nil;
49 |
50 | static dispatch_once_t onceToken;
51 |
52 | dispatch_once(&onceToken, ^{
53 | shared = [SKSecurity new];
54 | });
55 |
56 | return shared;
57 | }
58 |
59 | #pragma mark - Private Instance Method
60 | - (const char *) copyPointer: (const size_t) length
61 | : (const NSString *) target {
62 |
63 | char * pointee = (char *) malloc(length);
64 |
65 | // write zeroes to a byte string
66 | bzero(pointee, length);
67 |
68 | // Converts the string to a given encoding and stores it in a buffer.
69 | [target getCString: pointee maxLength: length encoding: NSUTF8StringEncoding];
70 |
71 | return pointee;
72 | }
73 |
74 | - (NSData *) getDataByStatus: (CCCryptorStatus) status
75 | : (void *) dataWithBytes
76 | : (size_t) length {
77 |
78 | switch (status) {
79 |
80 | case kCCSuccess:
81 | NSLog(@"[SKSecurity] Operation completed normally");
82 | return [NSData dataWithBytes: dataWithBytes length: length];
83 |
84 | case kCCParamError:
85 | NSLog(@"[SKSecurity] Illegal parameter value");
86 | return NULL;
87 |
88 | case kCCBufferTooSmall:
89 | NSLog(@"[SKSecurity] Insufficent Buffer Provided for Specified Operation");
90 | return NULL;
91 |
92 | case kCCMemoryFailure:
93 | NSLog(@"[SKSecurity] Memory allocation failure");
94 | return NULL;
95 |
96 | case kCCDecodeError:
97 | NSLog(@"[SKSecurity] Input Size was not Aligned Properly");
98 | return NULL;
99 |
100 | case kCCUnimplemented:
101 | NSLog(@"[SKSecurity] Function not Implemented for the Current Algorithm");
102 | return NULL;
103 |
104 | case kCCInvalidKey:
105 | NSLog(@"[SKSecurity] Key is not valid");
106 | return NULL;
107 |
108 | default:
109 | NSLog(@"[SKSecurity] Unknown CCCryptorStatus Error");
110 | return NULL;
111 | }
112 | }
113 |
114 | - (NSData *) crypt: (const NSString *) key
115 | : (const SKSecurityAESType) keySize
116 | : (const NSString *) iv
117 | : (const NSData *) data
118 | : (const CCOperation) operation {
119 |
120 | @synchronized (self) {
121 |
122 | // Creating an cryption key buffer
123 | const size_t keyLength = keySize;
124 | const char * keyPointee = [self copyPointer: keyLength
125 | : key];
126 |
127 | // Creating an initialization vector buffer
128 | const size_t ivLength = kCCBlockSizeAES128;
129 | const char * ivPointee = [self copyPointer: ivLength
130 | : iv];
131 |
132 | const size_t blockLength = data.length + kCCBlockSizeAES128;
133 | void * block = (void *) malloc(blockLength);
134 |
135 | // Performing Encryption or Decryption Operation
136 | size_t bytesCrypted = 0;
137 | const CCCryptorStatus status = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
138 | keyPointee, keySize,
139 | ivPointee,
140 | data.bytes, data.length,
141 | block, blockLength,
142 | &bytesCrypted);
143 |
144 | NSData * result = [self getDataByStatus: status
145 | : block
146 | : bytesCrypted];
147 |
148 | // Deallocates or frees a memory block.
149 | free(block);
150 | block = NULL;
151 |
152 | return result;
153 | }
154 | }
155 |
156 | #pragma mark - Public Instance Method
157 | - (NSData *) encrypt: (const NSString *) key
158 | : (const SKSecurityAESType) keyType
159 | : (const NSString *) iv
160 | : (NSData *) data {
161 |
162 | @autoreleasepool {
163 |
164 | NSLog(@"[SKSecurity] Performing Encryption Operation");
165 |
166 | return [self crypt: key
167 | : keyType
168 | : iv
169 | : data
170 | : ::Encrypt];
171 | }
172 | }
173 |
174 | - (NSData *) decrypt: (const NSString *) key
175 | : (const SKSecurityAESType) keyType
176 | : (const NSString *) iv
177 | : (NSData *) data {
178 |
179 | @autoreleasepool {
180 |
181 | NSLog(@"[SKSecurity] Performing Decryption Operation");
182 |
183 | return [self crypt: key
184 | : keyType
185 | : iv
186 | : data
187 | : ::Decrypt];
188 | }
189 | }
190 |
191 | - (NSString *) createInitializationVector {
192 |
193 | @autoreleasepool {
194 |
195 | const NSArray * components = [NSUUID.UUID.UUIDString componentsSeparatedByString: @"-"];
196 |
197 | NSMutableString * stringValue = [[NSMutableString alloc] init];
198 |
199 | for (NSString * element in components) {
200 | [stringValue appendString: element];
201 | }
202 |
203 | NSMutableString * result = [[NSMutableString alloc] init];
204 |
205 | for (int index = 0; index < 16; index++) {
206 |
207 | NSUInteger characterAtIndex = arc4random() % stringValue.length;
208 | const unichar character = [stringValue characterAtIndex: characterAtIndex];
209 | [result appendFormat: @"%C", character];
210 | }
211 |
212 | // The IV (Initialization Vector) must have a length of 16 bytes
213 | return result;
214 | }
215 | }
216 |
217 | @end
218 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.4
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | /*
5 | * Copyright (c) 2023 Universal SystemKit. All rights reserved.
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | // swiftlint:disable all
27 | import PackageDescription
28 |
29 | // The configuration of a Swift package.
30 | let package = Package(
31 | // The name of the Swift package.
32 | name: InfoPackage.PackageName,
33 | // The list of minimum versions for platforms supported by the package.
34 | platforms: [
35 | // macOS 10.15 (Catalina) 이상의 운영체제부터 사용이 가능합니다.
36 | .macOS(SupportedPlatform.MacOSVersion.v10_15),
37 |
38 | // iOS 13 이상의 운영체제부터 사용이 가능합니다.
39 | .iOS(SupportedPlatform.IOSVersion.v13),
40 | ],
41 | // Products define the executables and libraries a package produces, and make them visible to other packages.
42 | products: [
43 | // It is a module library related to Swift source code.
44 | .library(name: InfoPackage.PackageName, targets: [InfoPackage.PackageName]),
45 |
46 | // It is a module library related to Objective-C source code.
47 | .library(name: InfoPackage.PackageObjcName, targets: [InfoPackage.PackageObjcName])
48 | ],
49 | // The list of package dependencies.
50 | dependencies: [
51 | .package(url: RemotePackage.SwiftLog.path, from: RemotePackage.SwiftLog.from),
52 | .package(url: RemotePackage.SwiftHTTPTypes.path, from: RemotePackage.SwiftHTTPTypes.from),
53 | .package(url: RemotePackage.PLCrashReporter.path, from: RemotePackage.PLCrashReporter.from),
54 | ],
55 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
56 | // Targets can depend on other targets in this package, and on products in packages this package depends on.
57 | targets: [
58 | .target(name: InfoPackage.PackageName,
59 | dependencies: [RemotePackage.SwiftLog.target, RemotePackage.SwiftHTTPTypes.target, RemotePackage.PLCrashReporter.target],
60 | path: InfoPackage.PackagePath,
61 | resources: [.process("PrivacyInfo.xcprivacy")]),
62 | .target(name: InfoPackage.PackageObjcName,
63 | path: InfoPackage.PackageObjcPath,
64 | sources: ["Cryptor/SKSecurity.mm"],
65 | publicHeadersPath: ".",
66 | cSettings: [
67 | .headerSearchPath(".")
68 | ])
69 | ],
70 | // The list of Swift versions with which this package is compatible.
71 | swiftLanguageVersions: [.v5]
72 | )
73 |
74 | #if swift(>=5.6)
75 | // Add the documentation compiler plugin if possible
76 | package.dependencies.append(
77 | .package(url: RemotePackage.SwiftDocC.path, from: RemotePackage.SwiftDocC.from)
78 | )
79 | #endif
80 |
81 | // MARK: - Struct
82 | public struct InfoPackage {
83 |
84 | // MARK: String Properties
85 | public static let PackageName: String = "SystemKit"
86 |
87 | public static let PackagePath: String = "Sources"
88 |
89 | public static let PackageObjcName: String = "SystemKit_Objc"
90 |
91 | public static let PackageObjcPath: String = "ObjcSources"
92 |
93 | public static let platforms: [PackageDescription.Platform] = [.iOS, .macOS]
94 | }
95 |
96 | // MARK: - Protocol
97 | public protocol PackageProtocol {
98 |
99 | var name: String { get }
100 | var path: String { get }
101 | var target: Target.Dependency { get }
102 | }
103 |
104 | // MARK: - Enum
105 | public enum RemotePackage: String, CaseIterable, PackageProtocol {
106 |
107 | /// 🌎 [Swift-docc-plugin - GitHub](https://github.com/apple/swift-docc-plugin)
108 | case SwiftDocC = "SwiftDocCPlugin"
109 |
110 | /// 🌎 [SwiftLog - GitHub](https://github.com/apple/swift-log)
111 | case SwiftLog = "swift-log"
112 |
113 | /// 🌎 [Swift-HTTP-Types- GitHub](https://github.com/apple/swift-http-types)
114 | case SwiftHTTPTypes = "swift-http-types"
115 |
116 | /// 🌎 [PLCrashReporter - GitHub](https://github.com/microsoft/plcrashreporter)
117 | case PLCrashReporter = "PLCrashReporter"
118 |
119 | public var path: String {
120 |
121 | switch self {
122 | case .SwiftDocC:
123 | return "https://github.com/apple/swift-docc-plugin.git"
124 | case .SwiftLog:
125 | return "https://github.com/apple/swift-log.git"
126 | case .SwiftHTTPTypes:
127 | return "https://github.com/apple/swift-http-types.git"
128 | case .PLCrashReporter:
129 | return "https://github.com/microsoft/plcrashreporter.git"
130 | }
131 | }
132 |
133 | public var from: Version {
134 |
135 | switch self {
136 | case .SwiftDocC:
137 | // https://github.com/apple/swift-docc-plugin/releases/tag/1.3.0
138 | return Version(1, 3, 0)
139 | case .SwiftLog:
140 | // https://github.com/apple/swift-log/releases/tag/1.6.1
141 | return Version(1, 6, 1)
142 | case .SwiftHTTPTypes:
143 | // https://github.com/apple/swift-http-types/releases/tag/1.3.0
144 | return Version(1, 3, 0)
145 | case .PLCrashReporter:
146 | // https://github.com/microsoft/plcrashreporter/releases/tag/1.11.2
147 | return Version(1, 11, 2)
148 | }
149 | }
150 |
151 | public var target: Target.Dependency {
152 |
153 | switch self {
154 | case .SwiftDocC:
155 | let condition = TargetDependencyCondition.when(platforms: InfoPackage.platforms)
156 | return .target(name: self.name, condition: condition)
157 | case .SwiftLog:
158 | let condition = TargetDependencyCondition.when(platforms: InfoPackage.platforms)
159 | return .product(name: "Logging", package: self.name, condition: condition)
160 | case .SwiftHTTPTypes:
161 | let condition = TargetDependencyCondition.when(platforms: InfoPackage.platforms)
162 | return .product(name: "HTTPTypes", package: self.name, condition: condition)
163 | case .PLCrashReporter:
164 | let condition = TargetDependencyCondition.when(platforms: InfoPackage.platforms)
165 | return .product(name: "CrashReporter", package: self.name, condition: condition)
166 | }
167 | }
168 |
169 | public var name: String { return self.rawValue }
170 | }
171 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://swiftpackageindex.com/ChangYeop-Yang/Universal-SystemKit)
4 | [](https://swiftpackageindex.com/ChangYeop-Yang/Universal-SystemKit)
5 | [](https://dev-dream-world.tistory.com)
6 | [](https://www.linkedin.com/in/창엽-양-3535ab134/)
7 | 
8 | 
9 | 
10 | [](https://github.com/ChangYeop-Yang/Universal-SystemKit/blob/main/LICENSE)
11 |
12 | The `SystemKit` open-source library can be used on Apple Platforms such as `macOS`, `iOS`. and is a common library that enables convenient and efficient use of device system functions.
13 |
14 | # Installation
15 |
16 | The installation method for Universal SystemKit can be done through the [Swift Package Manager](https://www.swift.org/package-manager) or the [Github Repository](https://docs.github.com/en/repositories), and the details are as follows.
17 |
18 | ### Manually
19 |
20 | If you prefer not to use any of the aforementioned dependency managers, you can integrate `SystemKit` into your project manually.
21 |
22 | ### Github Repository
23 |
24 | You can pull the `SystemKit` Github Repository and include the `SystemKit` to build a dynamic or static library.
25 |
26 | ### Swift Package Manager
27 |
28 | The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.
29 |
30 | Once you have your Swift package set up, adding `SystemKit` as a dependency is as easy as adding it to the dependencies value of your Package.swift.
31 |
32 | 1. From the Xcode menu, click File → Swift Packages → Add Package Dependency.
33 |
34 | 2. In the dialog that appears, enter the repository URL: https://github.com/ChangYeop-Yang/Universal-SystemKit.git.
35 |
36 | 3-1. In Branch, Enter text "master".
37 |
38 | ```Swift
39 | dependencies: [
40 | .package(url: "https://github.com/ChangYeop-Yang/Universal-SystemKit", .branch("master"))
41 | ]
42 | ```
43 |
44 | 3-2. In Branch, Enter text "Version(2, 4, 0)".
45 |
46 | ```Swift
47 | dependencies: [
48 | .package(url: "https://github.com/ChangYeop-Yang/Universal-SystemKit", from: Version(2, 4, 0))
49 | ]
50 | ```
51 |
52 | # Requirements
53 |
54 | The detailed build results for the `Universal-SystemKit` library are as follows.
55 |
56 | | Platform | Minimum Swift Version | Installation | Status |
57 | |:--------:|:---------------------:|:------------:|:------:|
58 | | iOS 13.0+ | [5.0](https://www.swift.org/blog/swift-5-released/) | [Swift Package Manager](#swift-package-manager), [Manual](#manually), [Github Repository](#github-repository) | [✅ Fully Tested](https://swiftpackageindex.com/ChangYeop-Yang/Universal-SystemKit/builds) |
59 | | macOS 10.15+ (Catalina) | [5.0](https://www.swift.org/blog/swift-5-released/) | [Swift Package Manager](#swift-package-manager), [Manual](#manually), [Github Repository](#github-repository) | [✅ Fully Tested](https://swiftpackageindex.com/ChangYeop-Yang/Universal-SystemKit/builds) |
60 |
61 | # Using SystemKit
62 |
63 | The method for using the `Universal SystemKit` open-source library is described in the guide path below. For additional related information, please inquire by creating an issue.
64 |
65 | * [SKAsyncOperation](https://dev-dream-world.tistory.com/231)
66 |
67 | * [SKUserDefault](https://dev-dream-world.tistory.com/224)
68 |
69 | * [SKMessagePort](https://dev-dream-world.tistory.com/247)
70 |
71 | * [SKNetworkMonitor](https://dev-dream-world.tistory.com/234)
72 |
73 | * [SKFinderExtension](https://dev-dream-world.tistory.com/226?category=1294828)
74 |
75 | * [SKPermission](https://dev-dream-world.tistory.com/227?category=1294828)
76 |
77 | * [SKProcess](https://dev-dream-world.tistory.com/225?category=1294828)
78 |
79 | * [SKProcessMonitor](https://dev-dream-world.tistory.com/230?category=1294828)
80 |
81 | * [SKSignal](https://dev-dream-world.tistory.com/229?category=1294828)
82 |
83 | * [SKCrashReporter](https://dev-dream-world.tistory.com/236)
84 |
85 | * [SKFileLock](https://dev-dream-world.tistory.com/244)
86 |
87 | * [SKDispatchFile](https://dev-dream-world.tistory.com/246)
88 |
89 | * [SKSecurity](https://dev-dream-world.tistory.com/262)
90 |
91 | * [SKDispatchFileMonitor](https://dev-dream-world.tistory.com/275) → `SKDispatchFileMonitor` provides a common interface for monitoring file events on both iOS and macOS platforms.
92 |
93 | # License
94 |
95 | `SystemKit` is released under the MIT license. [See LICENSE](https://github.com/ChangYeop-Yang/Apple-SystemKit/blob/main/LICENSE) for details.
96 |
97 |
98 |
99 | ```TEXT
100 | MIT License
101 |
102 | Copyright (c) 2022 Universal-SystemKit
103 |
104 | Permission is hereby granted, free of charge, to any person obtaining a copy
105 | of this software and associated documentation files (the "Software"), to deal
106 | in the Software without restriction, including without limitation the rights
107 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108 | copies of the Software, and to permit persons to whom the Software is
109 | furnished to do so, subject to the following conditions:
110 |
111 | The above copyright notice and this permission notice shall be included in all
112 | copies or substantial portions of the Software.
113 |
114 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
115 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
116 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
117 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
118 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
119 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
120 | SOFTWARE.
121 | ```
122 |
--------------------------------------------------------------------------------
/Sources/Common/SKData+Extension.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 |
25 | // MARK: - Public Extension Data
26 | public extension Data {
27 |
28 | var base64DecodedString: String? {
29 |
30 | return String(data: self, encoding: .utf8)?.base64DecodedString
31 | }
32 |
33 | var base64DecodedData: Data? {
34 |
35 | return String(data: self, encoding: .utf8)?.base64DecodedData
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Sources/Common/SKDouble+Extension.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 |
25 | // MARK: - Extension Double
26 | extension Double {
27 |
28 | public var round2dp: Double { return (10.0 * self).rounded() / 10.0 }
29 | }
30 |
--------------------------------------------------------------------------------
/Sources/Common/SKString+Extension.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 |
25 | // MARK: - Public Extension String
26 | public extension String {
27 |
28 | var kCFString: CFString { return self as CFString }
29 |
30 | var kCString: UnsafePointer? { return (self as NSString).cString(using: String.Encoding.utf8.rawValue) }
31 |
32 | var base64EncodedString: String? { return self.data(using: .utf8)?.base64EncodedString() }
33 |
34 | var base64EncodedData: Data? { return self.data(using: .utf8)?.base64EncodedData() }
35 |
36 | var base64DecodedString: String? {
37 |
38 | guard let rawData = Data(base64Encoded: self) else { return nil }
39 |
40 | return String(data: rawData, encoding: .utf8)
41 | }
42 |
43 | var base64DecodedData: Data? { return Data(base64Encoded: self) }
44 |
45 | var kNSNotificationName: NSNotification.Name { return NSNotification.Name(self) }
46 |
47 | var kNotificationName: Notification.Name { return Notification.Name(self) }
48 | }
49 |
--------------------------------------------------------------------------------
/Sources/Communication/SKMessagePort+Define.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 | import CoreFoundation
25 |
26 | // MARK: - Typealias
27 | public typealias SKMessageLocalPort = (messagePort: CFMessagePort, instance: UnsafeMutablePointer)
28 | public typealias SKMessagePortRequestResult = Result
29 |
30 | // MARK: - Enum
31 | public enum SKMessagePortSendRequestErrorCode: Error {
32 |
33 | // https://developer.apple.com/documentation/corefoundation/cfmessageport/1561514-cfmessageportsendrequest_error_c
34 |
35 | /// The message was successfully sent and, if a reply was expected, a reply was received.
36 | case success
37 |
38 | /// The message could not be sent before the send timeout.
39 | case timeoutSend
40 |
41 | /// No reply was received before the receive timeout.
42 | case timeoutReceive
43 |
44 | /// The message could not be sent because the message port is invalid.
45 | case invalid
46 |
47 | /// An error occurred trying to send the message.
48 | case transportError
49 |
50 | /// The message port was invalidated.
51 | case BecameInvalidError
52 |
53 | // MARK: Enum Computed Properties
54 | public var errorCode: Int32 {
55 |
56 | // Error codes for CFMessagePortSendRequest.
57 | switch self {
58 | case .success:
59 | return kCFMessagePortSuccess
60 | case .timeoutSend:
61 | return kCFMessagePortSendTimeout
62 | case .timeoutReceive:
63 | return kCFMessagePortReceiveTimeout
64 | case .invalid:
65 | return kCFMessagePortIsInvalid
66 | case .transportError:
67 | return kCFMessagePortTransportError
68 | case .BecameInvalidError:
69 | return kCFMessagePortBecameInvalidError
70 | }
71 | }
72 |
73 | // MARK: Enum Method
74 | public static func getMessagePortRequestError(_ errorCode: Int32) -> SKMessagePortRequestResult {
75 |
76 | switch errorCode {
77 | case kCFMessagePortSuccess:
78 | return .success(SKMessagePortSendRequestErrorCode.success.errorCode)
79 | case kCFMessagePortSendTimeout:
80 | return .failure(SKMessagePortSendRequestErrorCode.timeoutSend)
81 | case kCFMessagePortReceiveTimeout:
82 | return .failure(SKMessagePortSendRequestErrorCode.timeoutReceive)
83 | case kCFMessagePortIsInvalid:
84 | return .failure(SKMessagePortSendRequestErrorCode.invalid)
85 | case kCFMessagePortTransportError:
86 | return .failure(SKMessagePortSendRequestErrorCode.transportError)
87 | case kCFMessagePortBecameInvalidError:
88 | return .failure(SKMessagePortSendRequestErrorCode.BecameInvalidError)
89 | default:
90 | fatalError("The value of CFMessagePortSendRequest Error Codes is invalid.")
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Sources/Communication/SKMessagePort.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 | import CoreFoundation
25 |
26 | public class SKMessagePort: SKClass {
27 |
28 | // MARK: - Object Properties
29 | public static var label: String = "com.SystemKit.SKMessagePort"
30 | public static var identifier: String = "368027F0-C77F-4F81-B352-F92B7B0370DB"
31 |
32 | private var portName: CFString
33 | private var portAttribute: Optional
34 | private var invalidateCallBack: CFMessagePortInvalidationCallBack
35 |
36 | // MARK: - Initalize
37 | public init(portName: String, _ invalidateCallBack: @escaping CFMessagePortInvalidationCallBack) {
38 | self.portName = portName as CFString
39 | self.portAttribute = nil
40 | self.invalidateCallBack = invalidateCallBack
41 | }
42 | }
43 |
44 | // MARK: - Private Extension SKMessagePort
45 | private extension SKMessagePort {
46 |
47 | final func createMutablePointer(instance: T) -> UnsafeMutablePointer {
48 |
49 | let pointer = UnsafeMutablePointer.allocate(capacity: 1)
50 |
51 | pointer.initialize(to: instance)
52 |
53 | return pointer
54 | }
55 |
56 | /// Returns a local CFMessagePort object.
57 | final func createLocalMessagePort(instance: AnyObject,
58 | _ callback: @escaping CFMessagePortCallBack) -> Optional {
59 |
60 | let pointer = createMutablePointer(instance: instance)
61 |
62 | var context = CFMessagePortContext(version: CFIndex.zero, info: pointer,
63 | retain: nil, release: nil, copyDescription: nil)
64 |
65 | var shouldFreeInfo: DarwinBoolean = false
66 |
67 | // 동일한 프로세스 내에서 메시지를 보낼 때 사용하는 로컬 메시지 포트를 생성합니다.
68 | guard let localPort = CFMessagePortCreateLocal(kCFAllocatorDefault,
69 | self.portName, callback, &context, &shouldFreeInfo) else {
70 | logger.error("[SKMessagePort] Failed to create a CFMessageLocalPort object.")
71 | return nil
72 | }
73 |
74 | // Sets the callback function invoked when a CFMessagePort object is invalidated.
75 | CFMessagePortSetInvalidationCallBack(localPort, self.invalidateCallBack)
76 |
77 | // The flag is set to true on failure or if a local port named name already exists, false otherwise.
78 | switch shouldFreeInfo.boolValue {
79 | case true:
80 | logger.error("[SKMessagePort] Could not create CFMessageLocalPort as it already exists.")
81 | return nil
82 |
83 | case false:
84 | logger.info("[SKMessagePort] CFMessageLocalPort has been created.")
85 | return SKMessageLocalPort(localPort, pointer)
86 | }
87 | }
88 |
89 | /// Returns a CFMessagePort object connected to a remote port.
90 | final func createRemoteMessagePort() -> Optional {
91 |
92 | // 다른 프로세스로 메시지를 보낼 때 사용하는 원격 메시지 포트를 생성합니다.
93 | guard let remotePort = CFMessagePortCreateRemote(kCFAllocatorDefault, self.portName) else {
94 | logger.error("[SKMessagePort] Failed to create a CFMessageRemotePort object.")
95 | return nil
96 | }
97 |
98 | // Sets the callback function invoked when a CFMessagePort object is invalidated.
99 | CFMessagePortSetInvalidationCallBack(remotePort, self.invalidateCallBack)
100 |
101 | logger.info("[SKMessagePort] CFMessageRemotePort has been created.")
102 |
103 | return remotePort
104 | }
105 |
106 | /// Invalidates a CFMessagePort object, stopping it from receiving or sending any more messages.
107 | final func invalidate(_ messagePort: CFMessagePort) {
108 |
109 | logger.info("[SKMessagePort] Performing invalidate on the CFMessagePort.")
110 |
111 | CFMessagePortInvalidate(messagePort)
112 | }
113 | }
114 |
115 | // MARK: - Public Extension SKMessagePort
116 | public extension SKMessagePort {
117 |
118 | final func invalidate() {
119 |
120 | // CFMessagePort 초기화 작업 대상 존재 여부를 확인합니다.
121 | guard let attribuate = self.portAttribute else {
122 | logger.error("[SKMessagePort] There are no targets to perform the invalidation.")
123 | return
124 | }
125 |
126 | // Deallocates the memory block previously allocated at this pointer.
127 | attribuate.instance.deallocate()
128 |
129 | // Invalidates a CFMessagePort object, stopping it from receiving or sending any more messages.
130 | invalidate(attribuate.messagePort)
131 | }
132 |
133 | @discardableResult
134 | final func listen(dispatch: DispatchQueue,
135 | info: AnyObject, _ callback: @escaping CFMessagePortCallBack) -> Bool {
136 |
137 | guard let attribute = createLocalMessagePort(instance: info, callback) else { return false }
138 |
139 | // CFMessagePort가 활성화 상태가 유지되도록 전역 변수에 저장합니다.
140 | self.portAttribute = attribute
141 |
142 | // Schedules callbacks for the specified message port on the specified dispatch queue.
143 | CFMessagePortSetDispatchQueue(attribute.messagePort, dispatch)
144 |
145 | logger.info("[SKMessagePort] Performing the listen on the CFMessagePort by DispatchQueue.")
146 |
147 | return CFMessagePortIsValid(attribute.messagePort)
148 | }
149 |
150 | @discardableResult
151 | final func send(messageID: Int32, message: Data,
152 | sendTimeout: CFTimeInterval = CFTimeInterval.zero,
153 | recvTimeout: CFTimeInterval = CFTimeInterval.zero) -> SKMessagePortRequestResult {
154 |
155 | // 데이터 전송을 위하여 CFMessageRemotePort를 생성합니다.
156 | guard let remotePort = createRemoteMessagePort() else {
157 | return .failure(SKMessagePortSendRequestErrorCode.invalid)
158 | }
159 |
160 | // 데이터 전송 후 CFMessageRemotePort 소멸작업을 수행합니다.
161 | defer { invalidate(remotePort) }
162 |
163 | // 전송하고자 하는 데이터가 비어있는 경우에는 전송하지 않습니다.
164 | if message.isEmpty {
165 | logger.error("[SKMessagePort] The data to be transferred is empty.")
166 | return .failure(SKMessagePortSendRequestErrorCode.transportError)
167 | }
168 |
169 | // Sends a message to a remote CFMessagePort object.
170 | let error = CFMessagePortSendRequest(remotePort, messageID, message as CFData, sendTimeout, recvTimeout, nil, nil)
171 |
172 | switch SKMessagePortSendRequestErrorCode.getMessagePortRequestError(error) {
173 | case .success:
174 | logger.info("[SKMessagePort] \(message.count) Bytes of data has been transferred.")
175 | return .success(kCFMessagePortSuccess)
176 |
177 | case .failure(let error):
178 | logger.error("[SKMessagePort] Error occur: \(error.localizedDescription)")
179 | return .failure(error)
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/Sources/Dispatch/SKDispatchFile.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Darwin
24 | import Dispatch
25 | import Foundation
26 |
27 | @objc public class SKDispatchFile: NSObject, SKClass {
28 |
29 | // MARK: - Typealias
30 | public typealias FileIOReadCompletion = (Data, Int32) -> Swift.Void
31 | public typealias FileIOWriteCompletion = (Int32) -> Swift.Void
32 |
33 | // MARK: - Object Properties
34 | public static var label: String = "com.SystemKit.SKDispatchFile"
35 | public static var identifier: String = "870EBBA7-3167-4147-BE3A-82E0C4A108A2"
36 |
37 | private let mode: mode_t
38 | private let implementQueue: DispatchQueue
39 |
40 | // MARK: - Initalize
41 | public init(qualityOfService qos: DispatchQoS = .default, mode: mode_t = 0o777) {
42 |
43 | // 파일이나 디렉토리 권한에 관련된 정보를 저장하는 변수입니다.
44 | self.mode = mode
45 | self.implementQueue = DispatchQueue(label: SKDispatchFile.label, qos: qos, attributes: .concurrent)
46 | }
47 | }
48 |
49 | // MARK: - Private Extension SKDispatchFile
50 | private extension SKDispatchFile {
51 |
52 | static func closeChannel(channel: DispatchIO, filePath: String, error: Int32) {
53 |
54 | let result: Int32 = flock(channel.fileDescriptor, LOCK_UN)
55 | logger.info("[SKDispatchFile][\(filePath)][error: \(result)] Unlock FileDescriptor")
56 |
57 | channel.close(flags: DispatchIO.CloseFlags.stop)
58 | logger.info("[SKDispatchFile][\(filePath)][error: \(error)] Close DispatchIO Operation")
59 | }
60 |
61 | final func createFileChannel(filePath: String, _ oflag: Int32) -> Optional {
62 |
63 | let fileDescriptor = open(filePath, oflag, self.mode)
64 |
65 | if fileDescriptor == EOF {
66 | logger.error("[SKDispatchFile][\(filePath)] Could't create file descriptor")
67 | return nil
68 | }
69 |
70 | // 파일 작업을 수행하기 전에 다른 프로세스 및 쓰레드에 대하여 원자성을 보장하기 위하여 파일 잠금을 수행합니다.
71 | flock(fileDescriptor, LOCK_EX)
72 |
73 | let channel = DispatchIO(type: .stream, fileDescriptor: fileDescriptor, queue: self.implementQueue) { error in
74 |
75 | // The handler to execute once the channel is closed.
76 | logger.info("[SKDispatchFile][\(filePath)][error: \(error)] DispatchIO Cleanup")
77 | }
78 |
79 | return channel
80 | }
81 | }
82 |
83 | // MARK: - Public Extension SKDispatchFile
84 | public extension SKDispatchFile {
85 |
86 | /**
87 | 파일에 대하여 쓰기 작업을 수행합니다.
88 | Perform a write operation on the file.
89 |
90 | - Version: `1.0.0`
91 | - Authors: `ChangYeop-Yang`
92 | - NOTE: `스레드 안전 (Thread Safety)`
93 | - Parameters:
94 | - contents: 파일에 쓰기 작업을 수행하기 위한 `Data`를 입력받는 매개변수
95 | - filePath: 쓰기 작업을 수행 할 파일 경로를 입력받는 매개변수
96 | - completion: 쓰기 작업을 통한 `(Int32) -> Swift.Void` 형태의 결과물을 전달하는 매개변수
97 | */
98 | final func write(contents: Data, filePath: String, _ completion: @escaping FileIOWriteCompletion) {
99 |
100 | // 쓰기 작업을 수행하기 위한 DispatchIO 생성합니다.
101 | guard let channel = self.createFileChannel(filePath: filePath, O_WRONLY | O_CREAT) else { return }
102 |
103 | let body: (UnsafeRawBufferPointer) throws -> Swift.Void = { pointer in
104 |
105 | // If the baseAddress of this buffer is nil, the count is zero.
106 | guard let baseAddress = pointer.baseAddress else {
107 | SKDispatchFile.closeChannel(channel: channel, filePath: filePath, error: EOF)
108 | return
109 | }
110 |
111 | let bytes = UnsafeRawBufferPointer(start: baseAddress, count: contents.count)
112 |
113 | let data = DispatchData(bytes: bytes)
114 |
115 | channel.write(offset: off_t.zero, data: data, queue: self.implementQueue) { done, data, error in
116 |
117 | // 파일 쓰기 작업에 오류가 발생한 경우에는 읽기 작업을 종료합니다.
118 | guard error == Int32.zero else {
119 | SKDispatchFile.closeChannel(channel: channel, filePath: filePath, error: error)
120 | return
121 | }
122 |
123 | // 정상적으로 파일 쓰기 작업이 완료 된 경우에 파일 내용을 전달합니다.
124 | if done {
125 | // 쓰기 작업에 수행 한 모든 파일 내용을 전달합니다.
126 | completion(error)
127 |
128 | // 파일 쓰기 작업을 위해서 생성 한 DispatchIO을 닫습니다.
129 | SKDispatchFile.closeChannel(channel: channel, filePath: filePath, error: error)
130 | }
131 | }
132 | }
133 |
134 | do { try contents.withUnsafeBytes(body) }
135 | catch let error as NSError {
136 | let errcode: Int32 = Int32(error.code)
137 | SKDispatchFile.closeChannel(channel: channel, filePath: filePath, error: errcode)
138 | return
139 | }
140 | }
141 |
142 | /**
143 | 파일에 대하여 읽기 작업을 수행합니다.
144 | Perform a read operation on the file.
145 |
146 | - Version: `1.0.0`
147 | - Authors: `ChangYeop-Yang`
148 | - NOTE: `스레드 안전 (Thread Safety)`
149 | - Parameters:
150 | - filePath: 읽기 작업을 수행하는 파일 경로를 입력받는 매개변수
151 | - completion: 읽기 작업을 통한 `(Data, Int32) -> Swift.Void` 형태의 결과물을 전달하는 매개변수
152 | */
153 | final func read(filePath: String, _ completion: @escaping FileIOReadCompletion) {
154 |
155 | // 파일 읽기 작업을 수행하기 전에 해당 파일이 실제로 존재하는지 확인합니다.
156 | guard FileManager.default.fileExists(atPath: filePath) else {
157 | logger.error("[SKDispatchFile][\(filePath)] The file does not exist at the specified path")
158 | return
159 | }
160 |
161 | // 읽기 작업을 수행하기 위한 DispatchIO 생성합니다.
162 | guard let channel = createFileChannel(filePath: filePath, O_RDONLY) else { return }
163 |
164 | var rawData = Data()
165 |
166 | channel.read(offset: off_t.zero, length: Int.max, queue: self.implementQueue) { done, data, error in
167 |
168 | // 파일 읽기 작업에 오류가 발생한 경우에는 읽기 작업을 종료합니다.
169 | guard error == Int32.zero else {
170 | SKDispatchFile.closeChannel(channel: channel, filePath: filePath, error: error)
171 | return
172 | }
173 |
174 | // 정상적으로 파일로부터 데이터를 읽어들이는 경우
175 | if let contentsOf = data { rawData.append(contentsOf: contentsOf) }
176 |
177 | // 정상적으로 파일 읽기 작업이 완료 된 경우에 파일 내용을 전달합니다.
178 | if done {
179 | // 읽어들인 모든 파일 내용을 전달합니다.
180 | completion(rawData, error)
181 |
182 | // 파일 읽기 작업을 위해서 생성 한 DispatchIO을 닫습니다.
183 | SKDispatchFile.closeChannel(channel: channel, filePath: filePath, error: error)
184 | }
185 | }
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/Sources/Dispatch/SKDispatchFileMonitor+Define.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 |
25 | // MARK: - Typealias
26 | public typealias SKFileEventHandler = (DispatchSource.FileSystemEvent) -> Swift.Void
27 |
--------------------------------------------------------------------------------
/Sources/Dispatch/SKDispatchFileMonitor.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Dispatch
24 | import Foundation
25 |
26 | @objc public class SKDispatchFileMonitor: NSObject, SKClass {
27 |
28 | // MARK: - Object Properties
29 | public static let label: String = "com.SystemKit.SKDispatchFileMonitor"
30 | public static let identifier: String = "A2BC9AF4-45B0-4C49-8D6B-1B0BAB8AC3FA"
31 | public static let name = Notification.Name(SKDispatchFileMonitor.label)
32 |
33 | private let source: DispatchSourceFileSystemObject
34 | private var handler: Optional
35 |
36 | // MARK: - Initalize
37 | public init?(filePath: String, eventMask: DispatchSource.FileSystemEvent, handler: Optional = nil) {
38 |
39 | // Creating a FileHandle
40 | guard let fileDescriptor = SKDispatchFileMonitor.makeFileDescriptor(filePath: filePath) else { return nil }
41 |
42 | // Creating a DispatchSourceFileSystemObject
43 | guard let source = SKDispatchFileMonitor.makeFileSystemObjectSource(fileDescriptor: fileDescriptor,
44 | eventMask: eventMask) else { return nil }
45 |
46 | self.source = source
47 | self.handler = handler
48 | }
49 |
50 | // MARK: - Deinitalize
51 | deinit { stop() }
52 | }
53 |
54 | // MARK: - Private Extension SKDispatchFileMonitor
55 | private extension SKDispatchFileMonitor {
56 |
57 | static func makeFileDescriptor(filePath: String) -> Optional {
58 |
59 | // Creating a FileDescriptor
60 | let fileDescriptor = open(filePath, O_EVTONLY | F_NOCACHE)
61 |
62 | // Failed to create FileDescriptor
63 | if fileDescriptor < Int32.zero { return nil }
64 |
65 | return fileDescriptor
66 | }
67 |
68 | static func makeFileSystemObjectSource(fileDescriptor: Int32,
69 | eventMask: DispatchSource.FileSystemEvent) -> Optional {
70 |
71 | let queue = DispatchQueue(label: SKDispatchFileMonitor.label, qos: .background, attributes: .concurrent)
72 |
73 | return DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: eventMask, queue: queue)
74 | }
75 |
76 | final func occurEventHandler() {
77 |
78 | logger.info("[SKDispatchFileMonitor] Setting up an EventHandler for FileSystem")
79 |
80 | self.handler?(self.source.data)
81 |
82 | NotificationCenter.default.post(name: SKDispatchFileMonitor.name, object: self.source.data)
83 | }
84 |
85 | final func occurCancelHandler() {
86 |
87 | logger.info("[SKDispatchFileMonitor] Setting up an CancelEventHandler for FileSystem")
88 |
89 | // Cleaning up objects used in FileSystemEvent
90 | self.handler = nil
91 | close(self.source.handle)
92 |
93 | NotificationCenter.default.post(name: SKDispatchFileMonitor.name, object: nil)
94 | }
95 | }
96 |
97 | // MARK: - Public Extension SKDispatchFileMonitor
98 | public extension SKDispatchFileMonitor {
99 |
100 | final func start() {
101 |
102 | // Setting up an EventHandler for DispatchSourceFileSystem
103 | self.source.setEventHandler { [unowned self] in self.occurEventHandler() }
104 |
105 | // Setting up an CancelEventHandler for DispatchSourceFileSystem
106 | self.source.setCancelHandler { [unowned self] in self.occurCancelHandler() }
107 |
108 | // Resumes the DispatchSourceFileSystem
109 | self.source.resume()
110 | }
111 |
112 | final func stop() {
113 |
114 | logger.info("[SKDispatchFileMonitor] Stopping FileSystemEvent monitoring")
115 |
116 | // cancel the DispatchSourceFileSystem
117 | self.source.cancel()
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/Sources/Dispatch/SKDispatchTimer+Define.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // MARK: - Enum
24 | public enum SKDispatchTimerState { case resumed, suspended, canceled, activated }
25 |
--------------------------------------------------------------------------------
/Sources/Dispatch/SKDispatchTimer.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Dispatch
24 | import Foundation
25 |
26 | @objc public class SKDispatchTimer: NSObject, SKClass {
27 |
28 | // MARK: - Typealias
29 | public typealias SKDispatchTimerHandler = () -> Swift.Void
30 |
31 | // MARK: - Object Properties
32 | public static var label: String = "com.SystemKit.SKDispatchTimer"
33 | public static var identifier: String = "A42D0B47-D7B3-4A23-8F30-B3E51555471E"
34 |
35 | private var interval = TimeInterval.zero
36 | private let implementQueue = DispatchQueue(label: SKDispatchFile.label)
37 | private var state = SKDispatchTimerState.suspended
38 | private var handler: Optional = nil
39 | private lazy var timer: Optional = nil
40 |
41 | // MARK: - Initalize
42 | @objc public init(interval: TimeInterval, _ handler: SKDispatchTimerHandler? = nil) {
43 | super.init()
44 |
45 | self.handler = handler
46 | self.interval = interval
47 |
48 | self.timer = makeTimerSource()
49 | }
50 |
51 | // MARK: - Deinitalize
52 | deinit { deinitalize() }
53 | }
54 |
55 | // MARK: - Private Extension SKDispatchTimer
56 | private extension SKDispatchTimer {
57 |
58 | final func makeTimerSource(flags: DispatchSource.TimerFlags = .strict) -> DispatchSourceTimer {
59 |
60 | let timer = DispatchSource.makeTimerSource(flags: flags, queue: self.implementQueue)
61 | timer.schedule(deadline: DispatchTime.now(), repeating: self.interval)
62 | timer.setEventHandler { self.handler?() }
63 |
64 | return timer
65 | }
66 |
67 | final func deinitalize() {
68 |
69 | self.timer?.setEventHandler(handler: nil)
70 |
71 | // if the DispatchSourceTimer state is Cancelled, the cancel will not be performed
72 | if self.timer?.isCancelled == false { self.timer?.cancel() }
73 |
74 | self.handler = nil
75 | }
76 |
77 | final func withLock(_ handler: @escaping SKDispatchTimerHandler) {
78 |
79 | self.implementQueue.async(flags: .barrier) { handler() }
80 | }
81 | }
82 |
83 | // MARK: - Public Extension SKDispatchTimer
84 | public extension SKDispatchTimer {
85 |
86 | @objc final func resume() {
87 |
88 | withLock {
89 |
90 | // If the DispatchSourceTimer state is currently Resume, the Resume will not be performed
91 | if self.state == .resumed || self.state == .activated { return }
92 |
93 | self.state = .resumed
94 | self.timer?.resume()
95 | }
96 | }
97 |
98 | @objc final func suspend() {
99 |
100 | withLock {
101 |
102 | // If the DispatchSourceTimer state is currently Suspend, the Suspend will not be performed
103 | if self.state == .suspended { return }
104 |
105 | // Suspend the DispatchSourceTimer
106 | self.state = .suspended
107 | self.timer?.suspend()
108 | }
109 | }
110 |
111 | @objc final func reschedule(interval: TimeInterval, _ handler: SKDispatchTimerHandler? = nil) {
112 |
113 | withLock {
114 |
115 | // Rescheduling the DispatchSourceTimer's TimeInterval
116 | self.interval = interval
117 | self.timer?.schedule(deadline: DispatchTime.now(), repeating: self.interval)
118 |
119 | // Rescheduling the DispatchSourceTimer's EventHandler
120 | self.handler = handler
121 | self.timer?.setEventHandler { self.handler?() }
122 | }
123 | }
124 |
125 | @objc final func cancel() {
126 |
127 | withLock {
128 |
129 | // If the DispatchSourceTimer state is currently Cancel, the Cancel will not be performed
130 | if self.state == .canceled || self.timer?.isCancelled == true { return }
131 |
132 | // Cancel the DispatchSourceTimer
133 | self.state = .canceled
134 | self.timer?.cancel()
135 | }
136 | }
137 |
138 | @objc final func activate() {
139 |
140 | withLock {
141 |
142 | self.state = .activated
143 | self.timer?.activate()
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/Sources/IO/SKIOProcess.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal SystemKit. All rights reserved.
3 | * Copyright (C) 2014-2017 beltex
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
13 | * all 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
21 | * THE SOFTWARE.
22 | */
23 |
24 | #if os(macOS)
25 | import Darwin
26 | import Foundation
27 |
28 | /// Assuming this is interpreted as unknown for now
29 | public let CPU_TYPE_ANY: cpu_type_t = -1
30 | public let CPU_TYPE_X86: cpu_type_t = 7
31 | public let CPU_TYPE_I386: cpu_type_t = CPU_TYPE_X86 // For compatibility
32 | public let CPU_TYPE_X86_64: cpu_type_t = CPU_TYPE_X86 | CPU_ARCH_ABI64
33 | public let CPU_TYPE_ARM: cpu_type_t = 12
34 | public let CPU_TYPE_ARM64: cpu_type_t = CPU_TYPE_ARM | CPU_ARCH_ABI64
35 | public let CPU_TYPE_POWERPC: cpu_type_t = 18
36 | public let CPU_TYPE_POWERPC64: cpu_type_t = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
37 |
38 | // MARK: - Enum
39 |
40 | /// Process information
41 | public struct SKIOProcessInfo {
42 |
43 | public let pid: Int
44 | public let ppid: Int
45 | public let pgid: Int
46 | public let uid: Int
47 | public let command: String
48 | public let arch: cpu_type_t
49 | public var status: Int32 // sys/proc.h - SIDL, SRUN, SSLEEP, SSTOP, SZOMB
50 | }
51 |
52 | /// Process API
53 | public struct SKIOProcessAPI {
54 |
55 | fileprivate static let machHost = mach_host_self()
56 |
57 | // MARK: Initalize
58 | public init() { NSLog("[SKIOProcessAPI] Initalize") }
59 | }
60 |
61 | // MARK: - Private Extension SKIOProcessAPI
62 | private extension SKIOProcessAPI {
63 |
64 | static func arch(_ pid: pid_t) -> cpu_type_t {
65 |
66 | var arch = CPU_TYPE_ANY
67 |
68 | var mib = [Int32](repeating: 0, count: Int(CTL_MAXNAME))
69 | var mibLength = size_t(CTL_MAXNAME)
70 |
71 | var result = sysctlnametomib("sysctl.proc_cputype", &mib, &mibLength)
72 |
73 | if result != Int32.zero {
74 | #if DEBUG
75 | print("ERROR - \(#file):\(#function):\(#line) - " + "\(result)")
76 | #endif
77 |
78 | return arch
79 | }
80 |
81 | mib[Int(mibLength)] = pid
82 | var size = MemoryLayout.size
83 |
84 | result = sysctl(&mib, u_int(mibLength + 1), &arch, &size, nil, Int.zero)
85 |
86 | if result != Int32.zero {
87 | #if DEBUG
88 | print("ERROR - \(#file):\(#function):\(#line) - " + "\(result)")
89 | #endif
90 |
91 | arch = CPU_TYPE_ANY
92 | }
93 |
94 | return arch
95 | }
96 | }
97 |
98 | // MARK: - Public Extension SKIOProcessAPI
99 | public extension SKIOProcessAPI {
100 |
101 | static func list() -> [SKIOProcessInfo] {
102 |
103 | var list = [SKIOProcessInfo]()
104 | var psets: processor_set_name_array_t? = processor_set_name_array_t.allocate(capacity: 1)
105 | var pcnt: mach_msg_type_number_t = mach_msg_type_number_t.zero
106 |
107 | // Need root
108 | var result = host_processor_sets(machHost, &psets, &pcnt)
109 | if result != KERN_SUCCESS {
110 | #if DEBUG
111 | print("ERROR - \(#file):\(#function) - Need root - " + "kern_return_t: \(result)")
112 | #endif
113 |
114 | return list
115 | }
116 |
117 | // For each CPU set
118 | for i in Int.zero...stride
154 | var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid]
155 |
156 | // TODO: Error check
157 | sysctl(&mib, u_int(mib.count), &kinfo, &size, nil, Int.zero)
158 |
159 | let command = withUnsafePointer(to: &kinfo.kp_proc.p_comm) {
160 | String(cString: UnsafeRawPointer($0).assumingMemoryBound(to: CChar.self))
161 | }
162 |
163 | list.append(SKIOProcessInfo(pid: Int(pid), ppid: Int(kinfo.kp_eproc.e_ppid),
164 | pgid: Int(kinfo.kp_eproc.e_pgid), uid: Int(kinfo.kp_eproc.e_ucred.cr_uid),
165 | command: command, arch: arch(pid), status: Int32(kinfo.kp_proc.p_stat)))
166 |
167 | mach_port_deallocate(mach_task_self_, task)
168 | }
169 |
170 | // TODO: Missing deallocate for tasks
171 | mach_port_deallocate(mach_task_self_, pset)
172 | mach_port_deallocate(mach_task_self_, psets![i])
173 | }
174 |
175 | return list
176 | }
177 | }
178 | #endif
179 |
--------------------------------------------------------------------------------
/Sources/IO/SKIOReturn.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal SystemKit. All rights reserved.
3 | * Copyright (C) 2014-2017 beltex
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
13 | * all 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
21 | * THE SOFTWARE.
22 | */
23 |
24 | #if os(macOS)
25 | import IOKit
26 |
27 | /*
28 | I/O Kit common error codes - as defined in
29 |
30 | Swift can't import complex macros, thus we have to manually add them here.
31 | Most of these are not relevant to us, but for the sake of completeness. See
32 | "Accessing Hardware From Applications -> Handling Errors" Apple document for
33 | more information.
34 |
35 | NOTE: kIOReturnSuccess is the only return code already defined in IOKit module
36 | for us.
37 |
38 | https://developer.apple.com/library/mac/qa/qa1075/_index.html
39 | */
40 |
41 | /// General error
42 | public let kIOReturnError = iokit_common_err(0x2bc)
43 | /// Can't allocate memory
44 | public let kIOReturnNoMemory = iokit_common_err(0x2bd)
45 | /// Resource shortage
46 | public let kIOReturnNoResources = iokit_common_err(0x2be)
47 | /// Error during IPC
48 | public let kIOReturnIPCError = iokit_common_err(0x2bf)
49 | /// No such device
50 | public let kIOReturnNoDevice = iokit_common_err(0x2c0)
51 | /// Privilege violation
52 | //public let kIOReturnNotPrivileged = iokit_common_err(0x2c1)
53 | /// Invalid argument
54 | public let kIOReturnBadArgument = iokit_common_err(0x2c2)
55 | /// Device read locked
56 | public let kIOReturnLockedRead = iokit_common_err(0x2c3)
57 | /// Exclusive access and device already open
58 | public let kIOReturnExclusiveAccess = iokit_common_err(0x2c5)
59 | /// Sent/received messages had different msg_id
60 | public let kIOReturnBadMessageID = iokit_common_err(0x2c6)
61 | /// Unsupported function
62 | public let kIOReturnUnsupported = iokit_common_err(0x2c7)
63 | /// Misc. VM failure
64 | public let kIOReturnVMError = iokit_common_err(0x2c8)
65 | /// Internal error
66 | public let kIOReturnInternalError = iokit_common_err(0x2c9)
67 | /// General I/O error
68 | public let kIOReturnIOError = iokit_common_err(0x2ca)
69 | /// Can't acquire lock
70 | public let kIOReturnCannotLock = iokit_common_err(0x2cc)
71 | /// Device not open
72 | public let kIOReturnNotOpen = iokit_common_err(0x2cd)
73 | /// Read not supported
74 | public let kIOReturnNotReadable = iokit_common_err(0x2ce)
75 | /// Write not supported
76 | public let kIOReturnNotWritable = iokit_common_err(0x2cf)
77 | /// Alignment error
78 | public let kIOReturnNotAligned = iokit_common_err(0x2d0)
79 | /// Media Error
80 | public let kIOReturnBadMedia = iokit_common_err(0x2d1)
81 | /// Device(s) still open
82 | public let kIOReturnStillOpen = iokit_common_err(0x2d2)
83 | /// RLD failure
84 | public let kIOReturnRLDError = iokit_common_err(0x2d3)
85 | /// DMA failure
86 | public let kIOReturnDMAError = iokit_common_err(0x2d4)
87 | /// Device Busy
88 | public let kIOReturnBusy = iokit_common_err(0x2d5)
89 | /// I/O Timeout
90 | public let kIOReturnTimeout = iokit_common_err(0x2d6)
91 | /// Device offline
92 | public let kIOReturnOffline = iokit_common_err(0x2d7)
93 | /// Not ready
94 | public let kIOReturnNotReady = iokit_common_err(0x2d8)
95 | /// Device not attached
96 | public let kIOReturnNotAttached = iokit_common_err(0x2d9)
97 | /// No DMA channels left
98 | public let kIOReturnNoChannels = iokit_common_err(0x2da)
99 | /// No space for data
100 | public let kIOReturnNoSpace = iokit_common_err(0x2db)
101 | /// Port already exists
102 | public let kIOReturnPortExists = iokit_common_err(0x2dd)
103 | /// Can't wire down physical memory
104 | public let kIOReturnCannotWire = iokit_common_err(0x2de)
105 | /// No interrupt attached
106 | public let kIOReturnNoInterrupt = iokit_common_err(0x2df)
107 | /// No DMA frames enqueued
108 | public let kIOReturnNoFrames = iokit_common_err(0x2e0)
109 | /// Oversized msg received on interrupt port
110 | public let kIOReturnMessageTooLarge = iokit_common_err(0x2e1)
111 | /// Not permitted
112 | public let kIOReturnNotPermitted = iokit_common_err(0x2e2)
113 | /// No power to device
114 | public let kIOReturnNoPower = iokit_common_err(0x2e3)
115 | /// Media not present
116 | public let kIOReturnNoMedia = iokit_common_err(0x2e4)
117 | /// Media not formatted
118 | public let kIOReturnUnformattedMedia = iokit_common_err(0x2e5)
119 | /// No such mode
120 | public let kIOReturnUnsupportedMode = iokit_common_err(0x2e6)
121 | /// Data underrun
122 | public let kIOReturnUnderrun = iokit_common_err(0x2e7)
123 | /// Data overrun
124 | public let kIOReturnOverrun = iokit_common_err(0x2e8)
125 | /// The device is not working properly!
126 | public let kIOReturnDeviceError = iokit_common_err(0x2e9)
127 | /// A completion routine is required
128 | public let kIOReturnNoCompletion = iokit_common_err(0x2ea)
129 | /// Operation aborted
130 | public let kIOReturnAborted = iokit_common_err(0x2eb)
131 | /// Bus bandwidth would be exceeded
132 | public let kIOReturnNoBandwidth = iokit_common_err(0x2ec)
133 | /// Device not responding
134 | public let kIOReturnNotResponding = iokit_common_err(0x2ed)
135 | /// Isochronous I/O request for distant past!
136 | public let kIOReturnIsoTooOld = iokit_common_err(0x2ee)
137 | /// Isochronous I/O request for distant future
138 | public let kIOReturnIsoTooNew = iokit_common_err(0x2ef)
139 | /// Data was not found
140 | public let kIOReturnNotFound = iokit_common_err(0x2f0)
141 | /// Should never be seen
142 | public let kIOReturnInvalid = iokit_common_err(0x1)
143 |
144 | /**
145 | I/O Kit system code is 0x38. First 6 bits of error code. Passed to err_system()
146 | macro as defined in .
147 | */
148 | private let SYS_IOKIT: UInt32 = (0x38 & 0x3f) << 26
149 |
150 | /**
151 | I/O Kit subsystem code is 0. Middle 12 bits of error code. Passed to err_sub()
152 | macro as defined in .
153 | */
154 | private let SUB_IOKIT_COMMON: UInt32 = (0 & 0xfff) << 14
155 |
156 | /**
157 | Based on macro of the same name in ``.
158 | Generates the error code.
159 |
160 | - Parameters:
161 | - code: The specific I/O Kit error code. Last 14 bits.
162 | - Returns Full 32 bit error code.
163 | */
164 | private func iokit_common_err(_ code: UInt32) -> kern_return_t {
165 | return Int32(bitPattern: SYS_IOKIT | SUB_IOKIT_COMMON | code)
166 | }
167 | #endif
168 |
--------------------------------------------------------------------------------
/Sources/Network/SKNetworkInterfaceDefine.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | #if os(iOS) || os(macOS)
25 | import Darwin
26 | import Foundation
27 |
28 | // MARK: - Enum
29 |
30 | /// The network interface family (IPv4 or IPv6).
31 | public enum SKFamily: Int {
32 |
33 | /// [IPv4](https://en.wikipedia.org/wiki/Internet_Protocol_version_4)
34 | case ipv4
35 |
36 | /// [IPv6](https://en.wikipedia.org/wiki/IPv6)
37 | case ipv6
38 |
39 | /// Used in case of errors.
40 | case other
41 |
42 | // MARK: Enum Computed Properties
43 | public var toString: String {
44 |
45 | // String representation of the address family.
46 | switch self {
47 | case .ipv4:
48 | return "IPv4"
49 | case .ipv6:
50 | return "IPv6"
51 | case .other:
52 | return "Other"
53 | }
54 | }
55 | }
56 |
57 | // MARK: - Struct
58 | public struct SKInterface: Identifiable, Codable {
59 |
60 | public var id: String = UUID().uuidString
61 |
62 | /// Extracted from `sysctl` based on `if_nametoindex`.
63 | public let macAddress: Optional
64 |
65 | /// Extracted from `ifaddrs->ifa_netmask`, supports both IPv4 and IPv6.
66 | public let netmask: Optional
67 |
68 | /// Extracted from `ifaddrs->ifa_addr`, supports both IPv4 and IPv6.
69 | public let ipAddress: Optional
70 |
71 | /// Extracted from `ifaddrs->ifa_dstaddr`. Not applicable for IPv6.
72 | public let broadcastAddress: Optional
73 |
74 | /// Field `ifaddrs->ifa_name`.
75 | public let interfaceName: String
76 |
77 | /// Field `ifaddrs->ifa_addr->sa_family`.
78 | public let interfaceFamily: String
79 |
80 | /// `IFF_UP` flag of `ifaddrs->ifa_flags`.
81 | public let up: Bool
82 |
83 | /// `IFF_RUNNING` flag of `ifaddrs->ifa_flags`.
84 | public let running: Bool
85 |
86 | /// `IFF_LOOPBACK` flag of `ifaddrs->ifa_flags`.
87 | public let loopBack: Bool
88 |
89 | /// `IFF_MULTICAST` flag of `ifaddrs->ifa_flags`.
90 | public let multicastSupported: Bool
91 |
92 | /// `IFF_BROADCAST` flag of `ifaddrs->ifa_flags`.
93 | public let broadcastSupported: Bool
94 |
95 | // MARK: Initalize
96 | public init(ipAddress: Optional, macAddress: Optional,
97 | broadcastAddress: Optional, netmask: Optional,
98 | interfaceName: String, interfaceFamily: String, ifaFlags: Int32) {
99 |
100 | self.netmask = netmask
101 | self.ipAddress = ipAddress
102 | self.macAddress = macAddress
103 | self.broadcastAddress = broadcastAddress
104 |
105 | self.interfaceName = interfaceName
106 | self.interfaceFamily = interfaceFamily
107 |
108 | self.up = (ifaFlags & IFF_UP) == IFF_UP
109 | self.running = (ifaFlags & IFF_RUNNING) == IFF_RUNNING
110 | self.loopBack = (ifaFlags & IFF_LOOPBACK) == IFF_LOOPBACK
111 | self.multicastSupported = (ifaFlags & IFF_MULTICAST) == IFF_MULTICAST
112 | self.broadcastSupported = (ifaFlags & IFF_BROADCAST) == IFF_BROADCAST
113 | }
114 | }
115 | #endif
116 |
--------------------------------------------------------------------------------
/Sources/Network/SKNetworkMonitor.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | #if os(iOS) || os(macOS)
25 | import Network
26 | import Foundation
27 |
28 | @available(iOS 12.0, macOS 10.14, *)
29 | public class SKNetworkMonitor: SKClass {
30 |
31 | // MARK: - Typealias
32 | public typealias SKNetworkStatus = (isConnected: Bool, image: SKNetworkStatusSymbols)
33 | public typealias SKNetworkStatusUpdateHandler = (SKNetworkMonitorStatus) -> Swift.Void
34 |
35 | // MARK: - Object Properties
36 | public static var label: String = "com.SystemKit.SKNetworkMonitor"
37 | public static var identifier: String = "5C6F96D5-C21E-4A48-9AED-15794E19A4E9"
38 |
39 | private let monitor: NWPathMonitor = NWPathMonitor()
40 | private let pathUpdateHandler: SKNetworkStatusUpdateHandler
41 | private let implementQueue: DispatchQueue = DispatchQueue(label: SKNetworkMonitor.label,
42 | qos: DispatchQoS.background,
43 | attributes: DispatchQueue.Attributes.concurrent)
44 |
45 | // MARK: - Initalize
46 | public init(pathUpdateHandler: @escaping SKNetworkStatusUpdateHandler) {
47 | self.pathUpdateHandler = pathUpdateHandler
48 | }
49 | }
50 |
51 | // MARK: - Public Extension SKNetworkMonitor
52 | @available(iOS 12.0, macOS 10.14, *)
53 | public extension SKNetworkMonitor {
54 |
55 | final func startMonitor() {
56 |
57 | #if DEBUG
58 | NSLog("[%@][%@] Action, Start NWPathMonitor", SKNetworkMonitor.label, SKNetworkMonitor.identifier)
59 | #endif
60 |
61 | self.monitor.pathUpdateHandler = { newPath in
62 |
63 | #if DEBUG
64 | NSLog("[%@][%@] \(newPath)", SKNetworkMonitor.label, SKNetworkMonitor.identifier)
65 | #endif
66 |
67 | let result: SKNetworkMonitorStatus = SKNetworkMonitorStatus(newPath)
68 | self.pathUpdateHandler(result)
69 | }
70 |
71 | self.monitor.start(queue: self.implementQueue)
72 | }
73 |
74 | final func stopMonitor() {
75 |
76 | #if DEBUG
77 | NSLog("[%@][%@] Action, Cancel NWPathMonitor", SKNetworkMonitor.label, SKNetworkMonitor.identifier)
78 | #endif
79 |
80 | self.monitor.cancel()
81 | }
82 | }
83 | #endif
84 |
--------------------------------------------------------------------------------
/Sources/Network/SKNetworkMonitorDefine.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(iOS) || os(macOS)
24 | import Network
25 | import Foundation
26 |
27 | // MARK: - Enum
28 | @available(iOS 12, macOS 10.14, *)
29 | public enum SKNetworkStatusSymbols: String {
30 |
31 | case satisfied = "wifi"
32 | case unsatisfied = "wifi.slash"
33 | case requiresConnection = "wifi.exclamationmark"
34 | }
35 |
36 | @available(iOS 12, macOS 10.14, *)
37 | public enum SKNetworkConnectionType: String {
38 |
39 | case unknown = "unknown"
40 |
41 | /// [Wi-Fi - Wikipedia](https://en.wikipedia.org/wiki/Wi-Fi)
42 | case wifi = "wifi"
43 |
44 | /// [Ethernet - Wikipedia](https://en.wikipedia.org/wiki/Ethernet)
45 | case ethernet = "ethernet"
46 |
47 | /// [Cellular - Wikipedia](https://en.wikipedia.org/wiki/Cellular_network)
48 | case cellular = "cellular"
49 |
50 | /// [Loopback - Wikipedia](https://en.wikipedia.org/wiki/Loopback)
51 | case loopback = "loopback"
52 | }
53 |
54 | // MARK: - Struct
55 | @available(iOS 12, macOS 10.14, *)
56 | public struct SKNetworkMonitorStatus {
57 |
58 | // MARK: Object Properties
59 | public let newPath: NWPath
60 |
61 | // MARK: - Initalize
62 | public init(_ newPath: NWPath) {
63 | self.newPath = newPath
64 | }
65 |
66 | // MARK: - Computed Properties
67 |
68 | /// - NOTE: [NWPath.Status](https://developer.apple.com/documentation/network/nwpath/status)
69 | public var status: SKNetworkMonitor.SKNetworkStatus {
70 |
71 | // 현재 디바이스에 대한 네트워크 연결 상태를 확인합니다.
72 | switch self.newPath.status {
73 |
74 | // The path is not currently available, but establishing a new connection may activate the path.
75 | case .requiresConnection:
76 | return SKNetworkMonitor.SKNetworkStatus(false, SKNetworkStatusSymbols.requiresConnection)
77 |
78 | // The path is not available for use.
79 | case .unsatisfied:
80 | return SKNetworkMonitor.SKNetworkStatus(false, SKNetworkStatusSymbols.unsatisfied)
81 |
82 | // The path is available to establish connections and send data.
83 | case .satisfied:
84 | return SKNetworkMonitor.SKNetworkStatus(true, SKNetworkStatusSymbols.satisfied)
85 |
86 | @unknown default:
87 | NSLog("[%@][%@] Error, Invaild NWPath.Status", SKNetworkMonitor.label, SKNetworkMonitor.identifier)
88 | return SKNetworkMonitor.SKNetworkStatus(false, SKNetworkStatusSymbols.unsatisfied)
89 | }
90 | }
91 |
92 | /// - NOTE: [NWInterface.InterfaceType](https://developer.apple.com/documentation/network/nwinterface/interfacetype)
93 | public var connectionType: SKNetworkConnectionType {
94 |
95 | // The network interface type used for communication over Wi-Fi networks.
96 | if self.newPath.usesInterfaceType(NWInterface.InterfaceType.wifi) {
97 | return SKNetworkConnectionType.wifi
98 | }
99 |
100 | // The network interface type used for communication over cellular networks.
101 | if self.newPath.usesInterfaceType(NWInterface.InterfaceType.cellular) {
102 | return SKNetworkConnectionType.cellular
103 | }
104 |
105 | // The network interface type used for communication over local loopback networks.
106 | if self.newPath.usesInterfaceType(NWInterface.InterfaceType.loopback) {
107 | return SKNetworkConnectionType.loopback
108 | }
109 |
110 | // The network interface type used for communication over wired Ethernet networks.
111 | if self.newPath.usesInterfaceType(NWInterface.InterfaceType.wiredEthernet) {
112 | return SKNetworkConnectionType.ethernet
113 | }
114 |
115 | // The network interface type used for communication over virtual networks or networks of unknown types.
116 | return SKNetworkConnectionType.unknown
117 | }
118 | }
119 | #endif
120 |
--------------------------------------------------------------------------------
/Sources/Permission/SKPermissionDefine.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(iOS) || os(macOS)
24 | import Foundation
25 |
26 | // MARK: - Enum
27 | public enum SKPermissionServiceName: String, CaseIterable {
28 |
29 | case All = "All"
30 |
31 | case AddressBook = "kTCCServiceAddressBook"
32 | case AppleEvents = "kTCCServiceAppleEvents"
33 | case Bluetooth = "kTCCServiceBluetoothAlways"
34 | case Calendar = "kTCCServiceCalendar"
35 | case Camera = "kTCCServiceCamera"
36 | case ContactsFull = "kTCCServiceContactsFull"
37 | case ContactsLimited = "kTCCServiceContactsLimited"
38 | case FileProviderDomain = "kTCCServiceFileProviderDomain"
39 | case FileProviderPresence = "kTCCServiceFileProviderPresence"
40 | case Location = "kTCCServiceLocation"
41 | case MediaLibrary = "kTCCServiceMediaLibrary"
42 | case Microphone = "kTCCServiceMicrophone"
43 | case Motion = "kTCCServiceMotion"
44 | case Photos = "kTCCServicePhotos"
45 | case PhotosAdd = "kTCCServicePhotosAdd"
46 | case Prototype3Rights = "kTCCServicePrototype3Rights"
47 | case Prototype4Rights = "kTCCServicePrototype4Rights"
48 | case Reminders = "kTCCServiceReminders"
49 | case ScreenCapture = "kTCCServiceScreenCapture"
50 | case Siri = "kTCCServiceSiri"
51 | case SpeechRecognition = "kTCCServiceSpeechRecognition"
52 | case Willow = "kTCCServiceWillow"
53 | case Accessibility = "kTCCServiceAccessibility"
54 | case PostEvent = "kTCCServicePostEvent"
55 | case ListenEvent = "kTCCServiceListenEvent"
56 | case DeveloperTool = "kTCCServiceDeveloperTool"
57 | case HomeKit = "kTCCServiceHomeKit"
58 | case SocialService = "kTCCServiceSocial"
59 | case TVProvider = "kTCCServiceTVProvider"
60 |
61 | /* These seem to be carry-overs from macOS */
62 | case SystemPolicyFullDiskAccess = "kTCCServiceSystemPolicyAllFiles"
63 | case SystemPolicyDeveloperFiles = "kTCCServiceSystemPolicyDeveloperFiles"
64 | case SystemPolicyRemovableVolumes = "kTCCServiceSystemPolicyRemovableVolumes"
65 | case SystemPolicyNetworkVolumes = "kTCCServiceSystemPolicyNetworkVolumes"
66 | case SystemPolicyDesktopFolder = "kTCCServiceSystemPolicyDesktopFolder"
67 | case SystemPolicyDownloadsFolder = "kTCCServiceSystemPolicyDownloadsFolder"
68 | case SystemPolicyDocumentsFolder = "kTCCServiceSystemPolicyDocumentsFolder"
69 | case SystemPolicySysAdminFiles = "kTCCServiceSystemPolicySysAdminFiles"
70 |
71 | /* These seem to be carry-overs from iOS */
72 | case LiverPool = "kTCCServiceLiverpool"
73 | case Ubiquity = "kTCCServiceUbiquity"
74 | case ShareKit = "kTCCServiceShareKit"
75 | case LinkedIn = "kTCCServiceLinkedIn"
76 | case Twitter = "kTCCServiceTwitter"
77 | case FaceBook = "kTCCServiceFacebook"
78 | case SinaWeibo = "kTCCServiceSinaWeibo"
79 | case TencentWeibo = "kTCCServiceTencentWeibo"
80 |
81 | // MARK: Enum Computed Properties
82 | public var name: String { self.rawValue }
83 | }
84 | #endif
85 |
--------------------------------------------------------------------------------
/Sources/Permission/SKPreferencePaneDefine.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Foundation
25 |
26 | public enum SKDefaultPreferencePane: String, CaseIterable {
27 |
28 | case Battery = "x-apple.systempreferences:com.apple.preference.battery"
29 | case Password = "x-apple.systempreferences:com.apple.preferences.password"
30 | case Notifications = "x-apple.systempreferences:com.apple.preference.notifications"
31 | case SoftwareUpdate = "x-apple.systempreferences:com.apple.preferences.softwareupdate?client=softwareupdateapp"
32 | case FamilySharingPrefPane = "x-apple.systempreferences:com.apple.preferences.FamilySharingPrefPane"
33 | case AppleID = "x-apple.systempreferences:com.apple.preferences.AppleIDPrefPane"
34 | case Wallet = "x-apple.systempreferences:com.apple.preferences.wallet"
35 | case Profile = "x-apple.systempreferences:com.apple.preferences.configurationprofiles"
36 | case Screentime = "x-apple.systempreferences:com.apple.preference.screentime"
37 |
38 | // MARK: macOS Ventura (Version 13.*)
39 | case LoginItems = "x-apple.systempreferences:com.apple.LoginItems-Settings.extension"
40 | case DesktopScreenEffect = "x-apple.systempreferences:com.apple.preference.desktopscreeneffect"
41 | }
42 |
43 | public enum SKAccessibilityPreferencePane: String, CaseIterable {
44 |
45 | case Display = "x-apple.systempreferences:com.apple.preference.universalaccess?Seeing_Display"
46 | case Zoom = "x-apple.systempreferences:com.apple.preference.universalaccess?Seeing_Zoom"
47 | case VoiceOver = "x-apple.systempreferences:com.apple.preference.universalaccess?Seeing_VoiceOver"
48 | case Descriptions = "x-apple.systempreferences:com.apple.preference.universalaccess?Media_Descriptions"
49 | case Captions = "x-apple.systempreferences:com.apple.preference.universalaccess?Captioning"
50 | case Audio = "x-apple.systempreferences:com.apple.preference.universalaccess?Hearing"
51 | case Keyboard = "x-apple.systempreferences:com.apple.preference.universalaccess?Keyboard"
52 | case Mouse = "x-apple.systempreferences:com.apple.preference.universalaccess?Mouse"
53 | case Switch = "x-apple.systempreferences:com.apple.preference.universalaccess?Switch"
54 | case Dictation = "x-apple.systempreferences:com.apple.preference.universalaccess?SpeakableItems"
55 | }
56 |
57 | public enum SKSharingPreferencePane: String, CaseIterable {
58 |
59 | case Main = "x-apple.systempreferences:com.apple.preferences.sharing"
60 |
61 | case ShareScreen = "x-apple.systempreferences:com.apple.preferences.sharing?Services_ScreenSharing"
62 | case SharePrint = "x-apple.systempreferences:com.apple.preferences.sharing?Services_PrinterSharing"
63 | case ShareFile = "x-apple.systempreferences:com.apple.preferences.sharing?Services_PersonalFileSharing"
64 | case ShareInternet = "x-apple.systempreferences:com.apple.preferences.sharing?Internet"
65 | case ShareBluetooth = "x-apple.systempreferences:com.apple.preferences.sharing?Services_BluetoothSharing"
66 |
67 | case RemoteLogin = "x-apple.systempreferences:com.apple.preferences.sharing?Services_RemoteLogin"
68 | case RemoteAppleEvents = "x-apple.systempreferences:com.apple.preferences.sharing?Services_RemoteAppleEvent"
69 | case RemoteManagement = "x-apple.systempreferences:com.apple.preferences.sharing?Services_ARDService"
70 | }
71 |
72 | public enum SKDictationSpeechPreferencePane: String, CaseIterable {
73 |
74 | case Dictation = "x-apple.systempreferences:com.apple.preference.speech?Dictation"
75 | case TextToSpeech = "x-apple.systempreferences:com.apple.preference.speech?TTS"
76 | }
77 |
78 | public enum SKSecurityPrivacyPreferencePane: String, CaseIterable {
79 |
80 | case Main = "x-apple.systempreferences:com.apple.preference.security"
81 |
82 | case General = "x-apple.systempreferences:com.apple.preference.security?General"
83 | case FileVault = "x-apple.systempreferences:com.apple.preference.security?FDE"
84 | case Firewall = "x-apple.systempreferences:com.apple.preference.security?Firewall"
85 | case Advanced = "x-apple.systempreferences:com.apple.preference.security?Advanced"
86 | case Privacy = "x-apple.systempreferences:com.apple.preference.security?Privacy"
87 |
88 | case PrivacyAccessibility = "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
89 | case PrivacyAssistive = "x-apple.systempreferences:com.apple.preference.security?Privacy_Assistive"
90 | case PrivacyLocationServices = "x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices"
91 | case PrivacyContacts = "x-apple.systempreferences:com.apple.preference.security?Privacy_Contacts"
92 | case PrivacyDiagnosticsUsage = "x-apple.systempreferences:com.apple.preference.security?Privacy_Diagnostics"
93 | case PrivacyCalendars = "x-apple.systempreferences:com.apple.preference.security?Privacy_Calendars"
94 | case PrivacyReminders = "x-apple.systempreferences:com.apple.preference.security?Privacy_Reminders"
95 | case PrivacyTencentWeibo = "x-apple.systempreferences:com.apple.preference.security?Privacy_TencentWeibo"
96 | case PrivacyAutomation = "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
97 | case PrivacyAdvertising = "x-apple.systempreferences:com.apple.preference.security?Privacy_Advertising"
98 |
99 | case PrivacyFacebook = "x-apple.systempreferences:com.apple.preference.security?Privacy_Facebook"
100 | case PrivacyLinkedIn = "x-apple.systempreferences:com.apple.preference.security?Privacy_LinkedIn"
101 | case PrivacyTwitter = "x-apple.systempreferences:com.apple.preference.security?Privacy_Twitter"
102 | case PrivacyWeibo = "x-apple.systempreferences:com.apple.preference.security?Privacy_Weibo"
103 |
104 | case PrivacyFullDiskAccess = "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"
105 |
106 | // MARK: macOS Catalina (Version: 10.15)
107 | case PrivacyDevTools = "x-apple.systempreferences:com.apple.preference.security?Privacy_DevTools"
108 | case PrivacyDesktopFolder = "x-apple.systempreferences:com.apple.preference.security?Privacy_DesktopFolder"
109 | case PrivacyDocumentsFolder = "x-apple.systempreferences:com.apple.preference.security?Privacy_DocumentsFolder"
110 | case PrivacyDownloadsFolder = "x-apple.systempreferences:com.apple.preference.security?Privacy_DownloadsFolder"
111 | case PrivacyNetworkVolume = "x-apple.systempreferences:com.apple.preference.security?Privacy_NetworkVolume"
112 | case PrivacyRemovableVolume = "x-apple.systempreferences:com.apple.preference.security?Privacy_RemovableVolume"
113 | case PrivacyInputMonitoring = "x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"
114 | case PrivacyScreenCapture = "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"
115 | }
116 | #endif
117 |
--------------------------------------------------------------------------------
/Sources/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyTracking
6 |
7 | NSPrivacyAccessedAPITypes
8 |
9 |
10 | NSPrivacyAccessedAPIType
11 | NSPrivacyAccessedAPICategoryFileTimestamp
12 | NSPrivacyAccessedAPITypeReasons
13 |
14 | 0A2A.1
15 |
16 |
17 |
18 | NSPrivacyAccessedAPIType
19 | NSPrivacyAccessedAPICategoryUserDefaults
20 | NSPrivacyAccessedAPITypeReasons
21 |
22 | C56D.1
23 |
24 |
25 |
26 | NSPrivacyAccessedAPIType
27 | NSPrivacyAccessedAPICategoryDiskSpace
28 | NSPrivacyAccessedAPITypeReasons
29 |
30 | 85F4.1
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Sources/Process/SKProcess.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Foundation
25 |
26 | @available(macOS 10.12, *)
27 | public class SKProcess: NSObject, SKClass {
28 |
29 | // MARK: - Typealias
30 | public typealias SKProcessErrorResult = (NSError, Process) -> Swift.Void
31 | public typealias SKProcessTerminationHandler = (Process) -> Swift.Void
32 |
33 | // MARK: - Object Properties
34 | public static let shared: SKProcess = SKProcess()
35 | public static let label: String = "com.SystemKit.SKProcess"
36 | public static let identifier: String = "B275BF0C-3E1B-4897-B6CB-CA3DC7FFD3EB"
37 |
38 | // MARK: - Initalize
39 | private override init() { super.init() }
40 | }
41 |
42 | // MARK: - Private Extension SKProcess
43 | @available(macOS 10.12, *)
44 | private extension SKProcess {
45 |
46 | final func launch(process: Process) throws {
47 |
48 | // macOS 10.13 미만의 운영체제에서는 launch() 함수를 통하여 실행합니다.
49 | guard #available(macOS 10.13, *) else {
50 | process.launch()
51 | return
52 | }
53 |
54 | // macOS 10.13 이상의 운영체제에서는 run() 함수를 통하여 실행합니다.
55 | try process.run()
56 | }
57 |
58 | final func closePipe(_ pipe: Optional) {
59 |
60 | // If the PIPE is not used, the close operation is not performed
61 | guard let target = pipe else { return }
62 |
63 | // The writing file handle close
64 | try? target.fileHandleForWriting.close()
65 |
66 | // The reading file handle close
67 | try? target.fileHandleForReading.close()
68 | }
69 | }
70 |
71 | // MARK: - Public Extension SKProcess
72 | @available(macOS 10.12, *)
73 | public extension SKProcess {
74 |
75 | @discardableResult
76 | final func run(launchPath: String,
77 | arguments: Array,
78 | standardInput: Optional = nil,
79 | standardOutput: Optional = nil,
80 | standardError: Optional = nil,
81 | waitUntilExit: Bool = false,
82 | qualityOfService: QualityOfService = .default,
83 | terminationHandler: Optional = nil,
84 | errorCompletionHandler: Optional = nil) -> Int32 {
85 |
86 | let process = Process()
87 | process.launchPath = launchPath
88 | process.arguments = arguments
89 | process.terminationHandler = terminationHandler
90 | process.standardInput = standardInput
91 | process.standardOutput = standardOutput
92 | process.standardError = standardError
93 | process.qualityOfService = qualityOfService
94 |
95 | do {
96 | try launch(process: process)
97 |
98 | if waitUntilExit { process.waitUntilExit() }
99 |
100 | // Closing the PIPE used in the operation
101 | [standardInput, standardOutput, standardError].forEach(closePipe)
102 |
103 | } catch let error as NSError {
104 | errorCompletionHandler?(error, process)
105 | return EOF
106 | }
107 |
108 | return process.processIdentifier
109 | }
110 | }
111 | #endif
112 |
--------------------------------------------------------------------------------
/Sources/Process/SKProcessMonitor.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Foundation
26 | import CoreFoundation
27 |
28 | public class SKProcessMonitor: SKAsyncOperation {
29 |
30 | // MARK: - Object Properties
31 | public static var label: String = "com.SystemKit.SKProcessMonitor"
32 | public static var identifier: String = "A4031B25-241F-4457-9DF4-B711D022C4EA"
33 |
34 | private var info: ProcessMonitorInfo
35 |
36 | // MARK: - Initalize
37 | public init(name: Optional = SKProcessMonitor.label,
38 | qualityOfService: QualityOfService = .default,
39 | queuePriority: Operation.QueuePriority = .normal,
40 | pid ident: pid_t,
41 | runLoop: CFRunLoop = CFRunLoopGetCurrent(),
42 | fflag: SKProcessMonitorFilterFlag,
43 | handler callback: @escaping CFFileDescriptorCallBack) {
44 |
45 | self.info = ProcessMonitorInfo(pid: ident, runLoop: runLoop, fflag: fflag, handler: callback)
46 |
47 | super.init()
48 |
49 | self.name = name
50 | self.queuePriority = queuePriority
51 | self.qualityOfService = qualityOfService
52 | }
53 | }
54 |
55 | // MARK: - Private Extension SKProcessMonitor
56 | public extension SKProcessMonitor {
57 |
58 | final func enableMonitorProcess() {
59 |
60 | // 현재 작업이 취소가 된 상태인 경우에는 아래의 작업을 수행하지 않습니다.
61 | if self.isCancelled { return }
62 |
63 | let kqueue: Int32 = kqueue()
64 | var processEvent = kevent(ident: UInt(self.info.pid), filter: Int16(EVFILT_PROC),
65 | flags: UInt16(EV_ADD | EV_RECEIPT), fflags: self.info.fflag.define,
66 | data: Int.zero, udata: nil)
67 | kevent(kqueue, &processEvent, 1, nil, 1, nil)
68 |
69 | var context: CFFileDescriptorContext = CFFileDescriptorContext()
70 | self.info.descriptor = CFFileDescriptorCreate(nil, kqueue, true, self.info.handler, &context)
71 |
72 | let source: CFRunLoopSource = CFFileDescriptorCreateRunLoopSource(nil, self.info.descriptor, CFIndex.zero)
73 | CFRunLoopAddSource(self.info.runLoop, source, CFRunLoopMode.defaultMode)
74 |
75 | CFFileDescriptorEnableCallBacks(self.info.descriptor, kCFFileDescriptorReadCallBack)
76 | }
77 |
78 | final func disableMonitorProcess() {
79 |
80 | // 현재 작업이 활성화 상태인 경우에는 아래의 작업을 수행하지 않습니다.
81 | guard self.isCancelled else { return }
82 |
83 | CFRunLoopStop(self.info.runLoop)
84 | CFFileDescriptorDisableCallBacks(self.info.descriptor, kCFFileDescriptorReadCallBack)
85 | }
86 | }
87 |
88 | // MARK: - Public Extension SKProcessMonitor
89 | public extension SKProcessMonitor {
90 |
91 | override func start() {
92 | super.start()
93 |
94 | enableMonitorProcess()
95 | }
96 |
97 | override func cancel() {
98 | super.cancel()
99 |
100 | disableMonitorProcess()
101 | }
102 | }
103 | #endif
104 |
--------------------------------------------------------------------------------
/Sources/Process/SKProcessMonitorDefine.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Foundation
26 |
27 | // MARK: - Struct
28 | internal struct ProcessMonitorInfo {
29 |
30 | internal let pid: pid_t
31 | internal let runLoop: CFRunLoop
32 | internal let fflag: SKProcessMonitorFilterFlag
33 | internal let handler: CFFileDescriptorCallBack
34 |
35 | internal var descriptor: Optional = nil
36 | }
37 |
38 | // MARK: - Enum
39 | public enum SKProcessMonitorFilterFlag {
40 |
41 | /// - NOTE: [exit - System Call](https://en.wikipedia.org/wiki/Exit_(system_call))
42 | case exit
43 |
44 | /// - NOTE: [fork - System Call](https://en.wikipedia.org/wiki/Fork_(system_call))
45 | case fork
46 |
47 | /// - NOTE: [exec - System Call](https://en.wikipedia.org/wiki/Exec_(system_call))
48 | case exec
49 |
50 | // MARK: Enum Properties
51 | public var define: UInt32 {
52 |
53 | switch self {
54 | /// process exec'd: `0x20000000`
55 | case .exec:
56 | return UInt32(NOTE_EXEC)
57 |
58 | /// Process Exited: `0x80000000`
59 | case .exit:
60 | return NOTE_EXIT
61 |
62 | /// process forked: `0x40000000`
63 | case .fork:
64 | return UInt32(NOTE_FORK)
65 | }
66 | }
67 | }
68 | #endif
69 |
--------------------------------------------------------------------------------
/Sources/Protocol/SKClass+Protocol.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | #if os(iOS) || os(macOS) || os(Linux)
25 | import Foundation
26 |
27 | @objc public protocol SKClass: AnyObject {
28 |
29 | // MARK: Required Protocol Properties
30 | static var label: String { get }
31 | static var identifier: String { get }
32 |
33 | // MARK: Optaionl Protocol Method
34 | @objc optional var implementQueue: DispatchQueue { get set }
35 | @objc optional var operationQueue: OperationQueue { get set }
36 | }
37 | #endif
38 |
--------------------------------------------------------------------------------
/Sources/Protocol/SKOperation+Protocol.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | #if os(iOS) || os(macOS) || os(Linux)
25 | import Dispatch
26 | import Foundation
27 |
28 | @objc public protocol SKOperation: SKClass {
29 |
30 | // MARK: Optional Protocol Properties
31 | @objc optional var payload: Optional { get set }
32 | @objc optional var timer: Optional { get set }
33 |
34 | // MARK: Required Initalize
35 | init(name: Optional, qualityOfService: QualityOfService)
36 | }
37 | #endif
38 |
--------------------------------------------------------------------------------
/Sources/SKAsyncOperation.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(iOS) || os(macOS) || os(Linux)
24 | import Foundation
25 |
26 | open class SKAsyncOperation: Operation {
27 |
28 | // MARK: - Enum
29 | public enum State: String {
30 |
31 | case ready = "Ready"
32 | case executing = "Executing"
33 | case finished = "Finished"
34 |
35 | // KVO notifications을 위한 keyPath설정
36 | fileprivate var keyPath: String {
37 | return String(format: "is%@", rawValue.capitalized)
38 | }
39 | }
40 |
41 | // MARK: - Object Properties
42 | public var state = State.ready {
43 |
44 | // 직접적으로 Operation 작업 상태를 관리하기 위한 Status Variable 생성
45 | willSet {
46 | willChangeValue(forKey: newValue.keyPath)
47 | willChangeValue(forKey: state.keyPath)
48 | }
49 |
50 | didSet {
51 | didChangeValue(forKey: oldValue.keyPath)
52 | didChangeValue(forKey: state.keyPath)
53 | }
54 | }
55 | }
56 |
57 | // MARK: - Open Extension AsyncOperation With Properties
58 | extension SKAsyncOperation {
59 |
60 | open override var isReady: Bool { return super.isReady && self.state == State.ready }
61 |
62 | open override var isExecuting: Bool { return self.state == State.executing }
63 |
64 | open override var isFinished: Bool { return self.state == State.finished }
65 |
66 | open override var isAsynchronous: Bool { return true }
67 | }
68 |
69 | // MARK: - Open Extension AsyncOperation With Method
70 | extension SKAsyncOperation {
71 |
72 | open override func start() {
73 |
74 | if self.isCancelled {
75 | self.state = State.finished
76 | return
77 | }
78 |
79 | self.main()
80 |
81 | #if DEBUG
82 | NSLog("[SKAsyncOperation] Action, Operation Start: %@", self.state.keyPath)
83 | #endif
84 |
85 | self.state = State.executing
86 | }
87 |
88 | open override func cancel() {
89 | super.cancel()
90 |
91 | #if DEBUG
92 | NSLog("[SKAsyncOperation] Action, Operation Cancel: %@", self.state.keyPath)
93 | #endif
94 |
95 | self.state = State.finished
96 | }
97 | }
98 | #endif
99 |
--------------------------------------------------------------------------------
/Sources/SKAtomicValue.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(iOS) || os(macOS) || os(Linux)
24 | import Foundation
25 |
26 | @propertyWrapper
27 | public class SKAtomicValue {
28 |
29 | // MARK: - Object Properties
30 | private let dispatch = DispatchQueue(label: "com.SystemKit.SKAtomicValue")
31 | private var value: Value
32 |
33 | // MARK: - Computed Properties
34 | public var wrappedValue: Value {
35 |
36 | get {
37 | return self.dispatch.sync { return self.value }
38 | }
39 |
40 | set {
41 | self.dispatch.sync { self.value = newValue }
42 | }
43 | }
44 |
45 | // MARK: - Initalize
46 | public init(wrappedValue: Value) { self.value = wrappedValue }
47 | }
48 |
49 | // MARK: - Public Extension SKAtomicValue
50 | public extension SKAtomicValue {
51 |
52 | typealias SKMutateHandler = (inout Value) -> Swift.Void
53 | final func mutate(_ mutating: SKMutateHandler) {
54 |
55 | return self.dispatch.sync { mutating(&self.value) }
56 | }
57 | }
58 | #endif
59 |
--------------------------------------------------------------------------------
/Sources/SKFileLock.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | #if os(iOS) || os(macOS) || os(Linux)
25 | import Darwin
26 | import Foundation
27 |
28 | /**
29 | - Date: `2023.05.01.`
30 | - Version: `1.0.0`
31 | - Authors: `ChangYeop-Yang`
32 | */
33 | public class SKFileLock: SKClass {
34 |
35 | // MARK: - Enum
36 | public enum FileLockMode: Int {
37 | case read
38 | case write
39 | case update
40 | }
41 |
42 | // MARK: - Object Properties
43 | public static var label = "com.SystemKit.SKFileLock"
44 | public static var identifier = "7777529A-98A3-4E43-A3AA-AAFBE437BC3F"
45 |
46 | private let filePath: String
47 | private let fileHandle: Optional
48 |
49 | // MARK: - Initalize
50 | public init(filePath: String, _ mode: FileLockMode) {
51 | logger.info("[SKFileLock] init(filePath: String, mode: FileLockMode)")
52 |
53 | self.filePath = filePath
54 | self.fileHandle = SKFileLock.createFileHandle(filePath: filePath, mode)
55 | }
56 |
57 | public init(fileDescriptor: Int32) {
58 | logger.info("[SKFileLock] init(fileDescriptor: Int32)")
59 |
60 | self.filePath = SKFileLock.getFilePath(fileDescriptor: fileDescriptor) ?? String.init()
61 | self.fileHandle = FileHandle(fileDescriptor: fileDescriptor)
62 | }
63 | }
64 |
65 | // MARK: - Private Extension SKFileLock
66 | private extension SKFileLock {
67 |
68 | static func createFileHandle(filePath: String, _ mode: FileLockMode) -> Optional {
69 |
70 | switch mode {
71 | case .read:
72 | return FileHandle(forReadingAtPath: filePath)
73 | case .write:
74 | return FileHandle(forWritingAtPath: filePath)
75 | case .update:
76 | return FileHandle(forUpdatingAtPath: filePath)
77 | }
78 | }
79 |
80 | static func getFilePath(fileDescriptor: Int32) -> Optional {
81 |
82 | let maxPathSize = Int(PATH_MAX)
83 | var filePath = [CChar](repeating: CChar.zero, count: maxPathSize)
84 |
85 | guard fcntl(fileDescriptor, F_GETPATH, &filePath) == Int32.zero else { return nil }
86 |
87 | return String(cString: filePath)
88 | }
89 | }
90 |
91 | // MARK: - Public Extension SKFileLock
92 | public extension SKFileLock {
93 |
94 | /**
95 | 파일에 대하여 `파일 잠금 (File Locking)`을(를) 수행합니다.
96 |
97 | - Version: `1.0.0`
98 | - Returns: `Bool`
99 | */
100 | @discardableResult
101 | final func lock() -> Bool {
102 |
103 | logger.info("[SKFileLock] Perform a file lock on the file located at the \(self.filePath) path.")
104 |
105 | guard let fileDescriptor = self.fileHandle?.fileDescriptor else { return false }
106 |
107 | // 파일 잠금 (File Locking) 작업 수행 여부를 확인합니다.
108 | guard flock(fileDescriptor, LOCK_EX | LOCK_NB) == Int32.zero else { return false }
109 |
110 | return true
111 | }
112 |
113 | /**
114 | 파일에 대하여 `파일 잠금 해제 (File UnLocking)`을(를) 수행합니다.
115 |
116 | - Version: `1.0.0`
117 | - Returns: `Bool`
118 | */
119 | @discardableResult
120 | final func unlock() -> Bool {
121 |
122 | logger.info("[SKFileLock] Perform a file unlock on the file located at the \(self.filePath) path.")
123 |
124 | guard let fileDescriptor = self.fileHandle?.fileDescriptor else { return false }
125 |
126 | // 파일 잠금 해제 (File UnLocking) 작업 수행 여부를 확인합니다.
127 | guard flock(fileDescriptor, LOCK_UN) == Int32.zero else { return false }
128 |
129 | return true
130 | }
131 | }
132 | #endif
133 |
--------------------------------------------------------------------------------
/Sources/SKFinderExtension.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Foundation
25 | import FinderSync
26 |
27 | /**
28 | - Version: `1.0.0`
29 | - Authors: `ChangYeop-Yang`
30 | */
31 | public class SKFinderExtension: NSObject, SKClass {
32 |
33 | // MARK: - Object Properties
34 | public static let shared: SKFinderExtension = SKFinderExtension()
35 | public static let label: String = "com.SystemKit.SKFinderExtension"
36 | public static let identifier: String = "18EF2C59-D9A8-4908-8898-1E64C6E116BF"
37 |
38 | private let launchPath: String = "/usr/bin/pluginkit"
39 |
40 | // MARK: - Initalize
41 | private override init() { super.init() }
42 | }
43 |
44 | // MARK: - Public Extension SKFinderExtension With Properties
45 | public extension SKFinderExtension {
46 |
47 | @available(macOS 10.14, *)
48 | var isExtensionEnabled: Bool { FIFinderSyncController.isExtensionEnabled }
49 | }
50 |
51 | // MARK: - Public Extension SKFinderExtension With Method
52 | public extension SKFinderExtension {
53 |
54 | @available(macOS 10.12, *)
55 | final func append(extensionPath: String, waitUntilExit: Bool) {
56 |
57 | #if DEBUG
58 | NSLog("[%@][%@] Action, Append Application Finder Extension", SKFinderExtension.label, SKFinderExtension.identifier)
59 | #endif
60 |
61 | let arguments: Array = ["-a", extensionPath]
62 | SKProcess.shared.run(launchPath: self.launchPath, arguments: arguments, waitUntilExit: waitUntilExit)
63 | }
64 |
65 | @available(macOS 10.12, *)
66 | final func enable(extensionPath: String, waitUntilExit: Bool) {
67 |
68 | #if DEBUG
69 | NSLog("[%@][%@] Action, Enable Application Finder Extension", SKFinderExtension.label, SKFinderExtension.identifier)
70 | #endif
71 |
72 | let arguments: Array = ["-e", "use", "-i", extensionPath]
73 | SKProcess.shared.run(launchPath: self.launchPath, arguments: arguments, waitUntilExit: waitUntilExit)
74 | }
75 |
76 | @available(macOS 10.12, *)
77 | final func disable(extensionPath: String, waitUntilExit: Bool) {
78 |
79 | #if DEBUG
80 | NSLog("[%@][%@] Action, Disable Application Finder Extension", SKFinderExtension.label, SKFinderExtension.identifier)
81 | #endif
82 |
83 | let arguments: Array = ["-e", "ignore", "-i", extensionPath]
84 | SKProcess.shared.run(launchPath: self.launchPath, arguments: arguments, waitUntilExit: waitUntilExit)
85 | }
86 | }
87 | #endif
88 |
--------------------------------------------------------------------------------
/Sources/SKSignal.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Dispatch
26 | import Foundation
27 |
28 | /**
29 | - Date: `2022.11.10.`
30 | - Version: `1.0.0`
31 | - Authors: `ChangYeop-Yang`
32 | */
33 | public class SKSignal: SKAsyncOperation {
34 |
35 | // MARK: - Typealias
36 | public typealias SKSignalHandler = @convention(c) (Int32) -> Swift.Void
37 | private typealias SKSignalResult = (signal: Int32, handler: SKSignalHandler)
38 |
39 | // MARK: - Object Properties
40 | public static var label: String = "com.SystemKit.SKSignal"
41 | public static var identifier: String = "45F971FC-B05F-4CF5-9927-AD793F461718"
42 |
43 | private let result: SKSignalResult
44 | private var source: Optional = nil
45 |
46 | // MARK: - Initalize
47 | public init(signal number: Int32, handler: @escaping SKSignalHandler) {
48 | self.result = SKSignalResult(number, handler)
49 | }
50 | }
51 |
52 | // MARK: - Private Extension SKSignal
53 | private extension SKSignal {
54 |
55 | final func observeSignal(signal number: Int32, handler: @escaping SKSignalHandler) {
56 |
57 | // 현재 작업이 취소 상태인 경우에는 아래의 등록 작업을 하지 않습니다.
58 | if self.isCancelled { return }
59 |
60 | // SIGNAL 등록 작업을 수행하기 전에 기존의 SIGNAL 이벤트를 거부 작업을 수행합니다.
61 | signal(number, SIG_IGN)
62 |
63 | self.source = DispatchSource.makeSignalSource(signal: number)
64 | self.source?.setEventHandler { handler(number) }
65 | self.source?.resume()
66 | }
67 |
68 | final func removeObserveSignal() {
69 |
70 | // 현재 작업이 취소 상태가 아닌 경우에는 아래의 취소작업을 하지 않습니다.
71 | guard self.isCancelled else { return }
72 |
73 | #if DEBUG
74 | NSLog("[%@][%@] Action, Remove Signal Observe: %@", SKSignal.label, SKSignal.identifier, self.result.signal)
75 | #endif
76 |
77 | self.source?.cancel()
78 | self.source = nil
79 | }
80 | }
81 |
82 | // MARK: - Public Extension SKSignal
83 | public extension SKSignal {
84 |
85 | override func start() {
86 | super.start()
87 |
88 | // Signal Handler 등록 작업을 수행합니다.
89 | observeSignal(signal: self.result.signal, handler: self.result.handler)
90 | }
91 |
92 | override func cancel() {
93 | super.cancel()
94 |
95 | // Signal handler 등록 해제 작업을 수행합니다.
96 | removeObserveSignal()
97 | }
98 | }
99 | #endif
100 |
--------------------------------------------------------------------------------
/Sources/SKUserDefault.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | #if os(iOS) || os(macOS) || os(Linux)
25 | import Foundation
26 |
27 | @propertyWrapper
28 | public struct SKUserDefaults {
29 |
30 | // MARK: - Struct Properties
31 | private let forKey: String
32 | private let defaultValue: Optional
33 |
34 | // Property Wrapper 필수 구현 Property
35 | public var wrappedValue: Optional {
36 | get { UserDefaults.standard.object(forKey: self.forKey) as? Value ?? self.defaultValue }
37 | set { UserDefaults.standard.setValue(newValue, forKey: self.forKey) }
38 | }
39 |
40 | // MARK: - Initalize
41 | public init(forKey: String, defaultValue: Optional = nil) {
42 | self.forKey = forKey
43 | self.defaultValue = defaultValue
44 | }
45 | }
46 | #endif
47 |
--------------------------------------------------------------------------------
/Sources/System/SKSystem.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS) || os(iOS)
24 | import Darwin
25 | import Foundation
26 | import SystemConfiguration
27 |
28 | public class SKSystem: NSObject, SKClass {
29 |
30 | // MARK: - Object Properties
31 | public static let shared: SKSystem = SKSystem()
32 | public static let label: String = "com.SystemKit.SKSystem"
33 | public static let identifier: String = "1735CFB1-19CC-4581-8CB7-F2DC3E16C678"
34 | }
35 |
36 | // MARK: - Public Extension SKSystem With Universal Platform
37 | public extension SKSystem {
38 |
39 | /**
40 | 현재 구동중인 애플리케이션에 대한 `릴리즈 버전 (Release Version` 그리고 `번들 버전 (Bundle Version)` 정보를 가져오는 함수입니다.
41 |
42 | - Version: `1.0.0`
43 | - Authors: `ChangYeop-Yang`
44 | - Returns: `Optional`
45 | */
46 | final func getApplicationVersion() -> Optional {
47 |
48 | guard let infoDictionary = Bundle.main.infoDictionary else { return nil }
49 |
50 | guard let releaseVersion = infoDictionary["CFBundleShortVersionString"] as? String,
51 | let bundleVersion = infoDictionary["CFBundleVersion"] as? String else { return nil }
52 |
53 | return SKSystemApplicationVersionResult(release: releaseVersion, bundle: bundleVersion)
54 | }
55 |
56 | /**
57 | 현재 장비에서 사용중인 메모리 사용률 그리고 전체 메모리 값을 가져오는 함수입니다.
58 |
59 | - Version: `1.0.0`
60 | - Authors: `ChangYeop-Yang`
61 | - NOTE: Units of measurement `Megabyte (MB)`
62 | - Returns: `SKSystemMachineUsageMemeoryResult`
63 | */
64 | final func getMachineUsageMemory() -> SKSystemMachineUsageMemeoryResult {
65 |
66 | var usageMegaBytes: Float = Float.zero
67 | let totalMegaBytes: Float = Float(ProcessInfo.processInfo.physicalMemory) / 1024.0 / 1024.0
68 |
69 | var info: mach_task_basic_info = mach_task_basic_info()
70 | var count: UInt32 = mach_msg_type_number_t(MemoryLayout.size) / 4
71 |
72 | let result: kern_return_t = withUnsafeMutablePointer(to: &info) {
73 | $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
74 | task_info( mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
75 | }
76 | }
77 |
78 | if result == KERN_SUCCESS {
79 | usageMegaBytes = Float(info.resident_size) / 1024.0 / 1024.0
80 | }
81 |
82 | return SKSystemMachineUsageMemeoryResult(usage: usageMegaBytes, total: totalMegaBytes)
83 | }
84 |
85 | /**
86 | 현재 사용중인 장비 모델 명칭을 가져오는 함수입니다.
87 |
88 | - SeeAlso: [Apple Device Database](https://appledb.dev)
89 | - Version: `1.0.0`
90 | - Authors: `ChangYeop-Yang`
91 | - NOTE: 장비 모델 명칭을 가져오고 실제 제품을 판매하기 위한 제품명을 가져오기 위해서는 `getMachineSystemInfo` 함수를 사용하여야합니다.
92 | - Returns: `String`
93 | */
94 | final func getDeviceModelName() -> String {
95 |
96 | var mib: Array = [CTL_HW, HW_MODEL]
97 | var size: Int = MemoryLayout.size
98 | let pointee = UnsafeMutablePointer.allocate(capacity: 1)
99 |
100 | let result = sysctl(&mib, u_int(mib.count), pointee, &size, nil, Int.zero)
101 |
102 | #if DEBUG
103 | NSLog("[%@][%@] Action, Get Device Model: %d", SystemKit.label, SKSystem.identifier, result)
104 | #endif
105 |
106 | let cString: UnsafePointer = UnsafeRawPointer(pointee).assumingMemoryBound(to: CChar.self)
107 |
108 | return String(cString: cString, encoding: String.Encoding.utf8) ?? String.init()
109 | }
110 |
111 | /**
112 | 현재 사용중인 제품에 대한 제품 정보를 가져오는 함수입니다.
113 |
114 | - SeeAlso: [Apple Device Database](https://appledb.dev)
115 | - Version: `1.0.0`
116 | - Authors: `ChangYeop-Yang`
117 | - Returns: `Optional`
118 | */
119 | final func getMachineSystemInfo() -> Optional {
120 |
121 | let toString: (UnsafeRawBufferPointer) -> Optional = { raw in
122 |
123 | guard let cString = raw.baseAddress?.assumingMemoryBound(to: CChar.self) else { return nil }
124 |
125 | return String(cString: cString, encoding: String.Encoding.utf8)
126 | }
127 |
128 | var names: utsname = utsname()
129 | guard Foundation.uname(&names) == Int32.zero else { return nil }
130 |
131 | let sysname = withUnsafeBytes(of: &names.sysname, toString) ?? String.init()
132 | let nodename = withUnsafeBytes(of: &names.nodename, toString) ?? String.init()
133 | let release = withUnsafeBytes(of: &names.release, toString) ?? String.init()
134 | let version = withUnsafeBytes(of: &names.version, toString) ?? String.init()
135 | let machine = withUnsafeBytes(of: &names.machine, toString) ?? String.init()
136 |
137 | return SKSystemMachineSystemResult(operatingSystemName: sysname,
138 | operatingSystemRelease: release, operatingSystemVersion: version,
139 | machineNetworkNodeName: nodename, machineHardwarePlatform: machine)
140 | }
141 | }
142 | #endif
143 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemDefine.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import Foundation
24 |
25 | #if os(macOS) || os(iOS)
26 |
27 | // MARK: Enum With Universal Platform
28 | public enum SKResourceDataUnit: Double {
29 |
30 | case byte = 1 // 1 Byte
31 | case kiloByte = 1024 // 1024 Byte
32 | case megaByte = 1_048_576 // 1024 * 1024 Byte
33 | case gigaByte = 1_073_741_824 // 1024 * 1024 * 1024 Byte
34 | case teraBtye = 1_099_511_627_776 // 1024 * 1024 * 1024 * 1024 Byte
35 | }
36 |
37 | // MARK: - Struct With Universal Platform
38 | public struct SKSystemMachineUsageMemeoryResult: Codable {
39 |
40 | // MARK: Float Proeprties
41 |
42 | public let usage: Float
43 |
44 | public let total: Float
45 | }
46 |
47 | public struct SKSystemApplicationVersionResult: Codable {
48 |
49 | // MARK: String Properties
50 |
51 | public let release: String
52 |
53 | public let bundle: String
54 | }
55 |
56 | public struct SKSystemMachineSystemResult: Codable {
57 |
58 | // MARK: String Proeprties
59 |
60 | /// Name of the operating system implementation
61 | public let operatingSystemName: String
62 |
63 | /// Release level of the operating system
64 | public let operatingSystemRelease: String
65 |
66 | /// Version level of the operating system.
67 | public let operatingSystemVersion: String
68 |
69 | /// Network name of this machine
70 | public let machineNetworkNodeName: String
71 |
72 | /// Machine hardware platform
73 | public let machineHardwarePlatform: String
74 | }
75 | #endif
76 |
77 | #if os(macOS)
78 | // MARK: - Enum With macOS Platform
79 | public enum SKTranslatedRosettaResult: Int32 {
80 |
81 | /// Error Occurs
82 | case error = -1
83 |
84 | /// Native Process
85 | case native = 0
86 |
87 | /// Translated Process
88 | case translated = 1
89 | }
90 |
91 | @available(macOS 10.12, *)
92 | public enum macOSSystemVersion: String {
93 |
94 | /// macOS 10.12 (Sierra)
95 | case Sierra = "Sierra"
96 |
97 | /// macOS 10.13 (High Sierra)
98 | case HighSierra = "High Sierra"
99 |
100 | /// macOS 10.14 (Mojave)
101 | case Mojave = "Mojave"
102 |
103 | /// macOS 10.15 (Catalina)
104 | case Catalina = "Catalina"
105 |
106 | /// macOS 11 (BigSur)
107 | case BigSur = "BigSur"
108 |
109 | /// macOS 12 (Monterey)
110 | case Monterey = "Monterey"
111 |
112 | /// macOS 13 (Ventura)
113 | case Ventura = "Ventura"
114 |
115 | /// macOS 14 (Sonoma)
116 | case Sonoma = "Sonoma"
117 |
118 | /// macOS 15 (Sequoia)
119 | case Sequoia = "Sequoia"
120 |
121 | // MARK: Enum Computed Properties
122 | public var name: String { return String(format: "macOS %@", self.rawValue) }
123 | }
124 |
125 | // MARK: - Struct With macOS Platform
126 | public struct SKDisplayOutputUnitResult: Codable {
127 |
128 | // MARK: Integer Properties
129 |
130 | /// The window number of the window’s window device.
131 | public let windowNumber: Int
132 |
133 | /// the bit depth of the window’s raster image (2-bit, 8-bit, and so forth)
134 | public var bitsPerSample: Optional = nil
135 |
136 | // MARK: Double Properties
137 |
138 | /// A screen resolution width value.
139 | public var frameWidth: Optional = nil
140 |
141 | /// A screen resolution height value.
142 | public var frameHeight: Optional = nil
143 |
144 | /// A raster screen resolution width value.
145 | public var rasterWidth: Optional = nil
146 |
147 | /// A raster screen resolution height value.
148 | public var rasterHeight: Optional = nil
149 |
150 | // MARK: String Properties
151 |
152 | /// The name of the window’s color space.
153 | public var colorSpaceName: Optional = nil
154 |
155 | // MARK: Bool Properties
156 |
157 | /// The display device is a screen.
158 | public var isScreen: Optional = nil
159 |
160 | /// The display device is a printer.
161 | public var isPrinter: Optional = nil
162 | }
163 | #endif
164 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemProcessResource+Additions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Foundation
26 |
27 | // MARK: - Public Extension SKSystemProcessResource
28 | public extension SKSystemProcessResource {
29 |
30 | final func getProcessName(pid: pid_t) -> String {
31 |
32 | // The maximum bytes of argument to execve
33 | var mib: [Int32] = [CTL_KERN, KERN_ARGMAX]
34 |
35 | var buffersize = UInt32.zero
36 | var size = MemoryLayout.size(ofValue: buffersize)
37 |
38 | if sysctl(&mib, UInt32(mib.count), &buffersize, &size, nil, Int.zero) < Int32.zero {
39 | logger.error("[SKSystemProcessResource] Failed to retrieve KERN_ARGMAX buffer size")
40 | return String.init()
41 | }
42 |
43 | let count = Int(buffersize)
44 | var cString = [CChar](repeating: CChar.zero, count: count)
45 |
46 | // Retrieves the process name
47 | if proc_name(pid, &cString, buffersize) < Int32.zero {
48 | logger.error("[SKSystemProcessResource] Failed to retrieve process name")
49 | return String.init()
50 | }
51 |
52 | return String(cString: cString)
53 | }
54 |
55 | final func getProcessInfoList() -> Array {
56 |
57 | var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_ALL]
58 |
59 | // Retrieves information about all processes running on the operating system
60 | var length = size_t.zero
61 | if sysctl(&mib, UInt32(mib.count), nil, &length, nil, Int.zero) < Int32.zero {
62 | logger.error("[SKSystemProcessResource] Failed to retrieve process information")
63 | return Array.init()
64 | }
65 |
66 | // Allocating memory to UnsafeMutablePointer
67 | let capacity = Int(length)
68 | let info = UnsafeMutablePointer.allocate(capacity: capacity)
69 |
70 | // Deallocating memory from UnsafeMutablePointer
71 | defer { info.deallocate() }
72 |
73 | // Retrieves detailed information about processes
74 | if sysctl(&mib, UInt32(mib.count), info, &length, nil, Int.zero) < Int32.zero {
75 | logger.error("[SKSystemProcessResource] Failed to retrieve detailed process information using kinfo_proc")
76 | return Array.init()
77 | }
78 |
79 | var result = Array.init()
80 |
81 | let count = Int(length / MemoryLayout.size)
82 | for index in Int.zero...size)
92 | if proc_pidinfo(pid, PROC_PIDTASKINFO, UInt64.zero, &taskInfo, buffersize) < Int32.zero { continue }
93 |
94 | // Retrieves the process name
95 | let name = getProcessName(pid: pid)
96 |
97 | let newElement = SKProcessResourceInfo(pid: pid, name: name, info: taskInfo)
98 | result.append(newElement)
99 | }
100 |
101 | return result
102 | }
103 | }
104 | #endif
105 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemProcessResource+Define.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Foundation
26 |
27 | // MARK: - Struct
28 | public struct SKProcessResourceInfo: Codable {
29 |
30 | public let pid: pid_t
31 |
32 | public let name: String
33 |
34 | /// Virtual memory size (Bytes)
35 | public let virtualMemSize: UInt64
36 |
37 | /// Resident memory size (Bytes)
38 | public let residentMemSize: UInt64
39 |
40 | /// Task priority
41 | public let priority: Int32
42 |
43 | /// Number of running threads
44 | public let runningThreads: Int32
45 |
46 | /// Number of threads in the task
47 | public let totalThreads: Int32
48 |
49 | /// Number of context switches
50 | public let contextSwitch: Int32
51 |
52 | /// Total time `[User]`
53 | public let totalUserTime: UInt64
54 |
55 | /// Total Time `[System]`
56 | public let totalSystemTime: UInt64
57 |
58 | /// Number of page faults
59 | public let totalPageFaults: Int32
60 |
61 | /// Number of copy-on-write faults
62 | public let onCopyWritePageFaluts: Int32
63 |
64 | // MARK: Initalize
65 | public init(pid: pid_t, name: String, info: proc_taskinfo) {
66 |
67 | self.pid = pid
68 | self.name = name
69 | self.onCopyWritePageFaluts = info.pti_cow_faults
70 | self.totalPageFaults = info.pti_faults
71 | self.totalUserTime = info.pti_total_user
72 | self.totalSystemTime = info.pti_total_system
73 | self.priority = info.pti_priority
74 | self.contextSwitch = info.pti_csw
75 | self.totalThreads = info.pti_threadnum
76 | self.runningThreads = info.pti_numrunning
77 | self.virtualMemSize = info.pti_virtual_size
78 | self.residentMemSize = info.pti_resident_size
79 | }
80 | }
81 | #endif
82 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemProcessResource.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Foundation
25 |
26 | public class SKSystemProcessResource: SKClass {
27 |
28 | // MARK: - Object Properties
29 | public static let label: String = "com.SystemKit.SKSystemResource"
30 | public static let identifier: String = "D6217410-E762-478B-A97F-D5E8EC05D0CA"
31 | public static let shared: SKSystemProcessResource = SKSystemProcessResource()
32 |
33 | // MARK: - Initalize
34 | private init() { /* Initalize */ }
35 | }
36 | #endif
37 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemResource+Additions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Foundation
26 |
27 | // MARK: - Private Extension SKSystemResource
28 | private extension SKSystemResource {
29 |
30 | final func getHostStatisticsWithCPU() -> host_cpu_load_info {
31 |
32 | var size = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size)
33 |
34 | let capacity = Int(size)
35 |
36 | let hostInfo = host_cpu_load_info_t.allocate(capacity: 1)
37 | let _ = hostInfo.withMemoryRebound(to: integer_t.self, capacity: capacity) { (pointer) -> kern_return_t in
38 | return host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, pointer, &size)
39 | }
40 |
41 | let data = hostInfo.move()
42 | hostInfo.deallocate()
43 |
44 | return data
45 | }
46 |
47 | final func getStatisticsWithMemory() -> vm_statistics64 {
48 |
49 | var size = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size)
50 |
51 | let capacity = Int(size)
52 |
53 | let hostInfo = vm_statistics64_t.allocate(capacity: 1)
54 | let _ = hostInfo.withMemoryRebound(to: integer_t.self, capacity: capacity) { (pointer) -> kern_return_t in
55 | return host_statistics64(mach_host_self(), HOST_VM_INFO64, pointer, &size)
56 | }
57 |
58 | let data = hostInfo.move()
59 | hostInfo.deallocate()
60 |
61 | return data
62 | }
63 | }
64 |
65 | // MARK: - Public Extension SKSystemResource
66 | public extension SKSystemResource {
67 |
68 | final func getSystemVolumeDiskSpace() -> Optional {
69 |
70 | do {
71 |
72 | let forPath = NSHomeDirectory()
73 |
74 | let attributes = try FileManager.default.attributesOfFileSystem(forPath: forPath)
75 |
76 | guard let totalSpace = attributes[FileAttributeKey.systemSize] as? NSNumber else { return nil }
77 |
78 | guard let freeSpace = attributes[FileAttributeKey.systemFreeSize] as? NSNumber else { return nil }
79 |
80 | let totalSpaceGB = ByteCountFormatter.string(fromByteCount: totalSpace.int64Value,
81 | countStyle: .decimal)
82 | let freeSpaceGB = ByteCountFormatter.string(fromByteCount: freeSpace.int64Value,
83 | countStyle: .decimal)
84 | let usedSpaceGB = ByteCountFormatter.string(fromByteCount: totalSpace.int64Value - freeSpace.int64Value,
85 | countStyle: .decimal)
86 |
87 | return SKDiskSpaceResult(totalSpace: totalSpace.int64Value,
88 | freeSpace: freeSpace.int64Value,
89 | usedSpace: totalSpace.int64Value - freeSpace.int64Value)
90 |
91 | } catch let error as NSError {
92 | logger.error("[SKSystemResource] retrieving file system info: \(error.description)")
93 | return nil
94 | }
95 | }
96 |
97 | final func getSystemCPUResource(type: SKResourceDataUnit = .gigaByte) -> SKCPUResourceInfo {
98 |
99 | let load = getHostStatisticsWithCPU()
100 |
101 | let userDiff = Double(load.cpu_ticks.0 - self.previousSystemResource.cpu_ticks.0)
102 | let sysDiff = Double(load.cpu_ticks.1 - self.previousSystemResource.cpu_ticks.1)
103 | let idleDiff = Double(load.cpu_ticks.2 - self.previousSystemResource.cpu_ticks.2)
104 | let niceDiff = Double(load.cpu_ticks.3 - self.previousSystemResource.cpu_ticks.3)
105 |
106 | self.previousSystemResource = load
107 |
108 | let totalTicks = sysDiff + userDiff + idleDiff + niceDiff
109 | let sys = (100.0 * sysDiff / totalTicks)
110 | let user = (100.0 * userDiff / totalTicks)
111 | let idle = (100.0 * idleDiff / totalTicks)
112 |
113 | return SKCPUResourceInfo(value: min(99.9, (sys + user).round2dp),
114 | systemValue: sys.round2dp,
115 | userValue: user.round2dp,
116 | idleValue: idle.round2dp)
117 | }
118 |
119 | final func getSystemMemoryResource(type: SKResourceDataUnit = .gigaByte) -> SKMemoryResourceInfo {
120 |
121 | let maximumMemory = Double(ProcessInfo.processInfo.physicalMemory) / type.rawValue
122 |
123 | let load = getStatisticsWithMemory()
124 | let unit = Double(vm_kernel_page_size) / type.rawValue
125 |
126 | let active = Double(load.active_count) * unit
127 | let speculative = Double(load.speculative_count) * unit
128 | let inactive = Double(load.inactive_count) * unit
129 | let wired = Double(load.wire_count) * unit
130 | let compressed = Double(load.compressor_page_count) * unit
131 | let purgeable = Double(load.purgeable_count) * unit
132 | let external = Double(load.external_page_count) * unit
133 | let using = active + inactive + speculative + wired + compressed - purgeable - external
134 |
135 | return SKMemoryResourceInfo(value: min(99.9, (100.0 * using / maximumMemory).round2dp),
136 | pressureValue: (100.0 * (wired + compressed) / maximumMemory).round2dp,
137 | appValue: (using - wired - compressed).round2dp,
138 | wiredValue: wired.round2dp,
139 | compressedValue: compressed.round2dp)
140 | }
141 | }
142 | #endif
143 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemResource+Define.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Foundation
25 |
26 | // MARK: - Struct
27 | public struct SKMemoryResourceInfo: Codable {
28 |
29 | /// Using Total RAM `[% Percentage]`
30 | public let value: Double
31 |
32 | /// Efficiently your memory is serving your processing needs `[% Percentage]`
33 | public let pressureValue: Double
34 |
35 | /// The amount of memory being used by apps
36 | public let appValue: Double
37 |
38 | /// Memory required by the system to operate. This memory can’t be cached and must stay in RAM, so it’s not available to other apps
39 | public let wiredValue: Double
40 |
41 | /// The amount of memory that has been compressed to make more RAM available
42 | public let compressedValue: Double
43 | }
44 |
45 | public struct SKCPUResourceInfo: Codable {
46 |
47 | /// Using Total CPU `[% Percentage]`
48 | public let value: Double
49 |
50 | /// The percentage of CPU capability that’s being used by processes that belong to macOS. `[% Percentage]`
51 | public let systemValue: Double
52 |
53 | /// The percentage of CPU capability that’s being used by apps you opened, or by the processes opened by those apps. `[% Percentage]`
54 | public let userValue: Double
55 |
56 | /// The percentage of CPU capability that’s not being used. `[% Percentage]`
57 | public let idleValue: Double
58 | }
59 |
60 | public struct SKDiskSpaceResult: Codable {
61 |
62 | public let totalSpace: Int64
63 |
64 | public let freeSpace: Int64
65 |
66 | public let usedSpace: Int64
67 | }
68 | #endif
69 |
--------------------------------------------------------------------------------
/Sources/System/SKSystemResource.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #if os(macOS)
24 | import Darwin
25 | import Foundation
26 |
27 | public class SKSystemResource: SKClass {
28 |
29 | // MARK: - Object Properties
30 | public static let label: String = "com.SystemKit.SKSystemResource"
31 | public static let identifier: String = "0DEE36A9-02C6-4CEE-9FA7-A8CB6A4093A6"
32 | public static let shared: SKSystemResource = SKSystemResource()
33 |
34 | public var previousSystemResource: host_cpu_load_info = host_cpu_load_info()
35 |
36 | // MARK: - Initalize
37 | private init() { /* Initalize */ }
38 | }
39 | #endif
40 |
--------------------------------------------------------------------------------
/Sources/SystemKit.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Universal-SystemKit. All rights reserved.
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | // swiftlint:disable all
24 | import Foundation
25 |
26 | import Logging
27 |
28 | // MARK: - Global Properties
29 | public let logger: Logger = Logger(label: SystemKit.label)
30 |
31 | public struct SystemKit {
32 |
33 | // MARK: - Object Properties
34 | public static let label: String = "com.SystemKit"
35 | public static let version: String = "2.3.2"
36 | }
37 |
--------------------------------------------------------------------------------