├── .DS_Store ├── .gitattributes ├── VoiceRecorderFinished ├── VoiceRecorderFinished.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── andreasschultz.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── andreasschultz.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── VoiceRecorderFinished │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Audio Managers │ │ ├── AudioPlayer.swift │ │ └── AudioRecorder.swift │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Div │ │ ├── Extensions.swift │ │ ├── Helper.swift │ │ └── RecordingDataModel.swift │ ├── Info.plist │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── SceneDelegate.swift │ └── Views │ │ ├── ContentView.swift │ │ └── RecordingsList.swift ├── VoiceRecorderFinishedTests │ ├── Info.plist │ └── VoiceRecorderFinishedTests.swift └── VoiceRecorderFinishedUITests │ ├── Info.plist │ └── VoiceRecorderFinishedUITests.swift └── VoiceRecorderPt.1 ├── VoiceRecorderPt.1.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── andreasschultz.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── andreasschultz.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── VoiceRecorderPt.1 ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── AudioRecorder.swift ├── Base.lproj │ └── LaunchScreen.storyboard ├── ContentView.swift ├── Extensions.swift ├── Helper.swift ├── Info.plist ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── RecordingDataModel.swift ├── RecordingsList.swift └── SceneDelegate.swift ├── VoiceRecorderPt.1Tests ├── Info.plist └── VoiceRecorderPt_1Tests.swift └── VoiceRecorderPt.1UITests ├── Info.plist └── VoiceRecorderPt_1UITests.swift /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCKBIRDS/VoiceRecorderInSwiftUI/f2802c79f0767b27a8d366c8f83e96d090b9dd03/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4567B72823683F74001B9D3E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B72723683F74001B9D3E /* AppDelegate.swift */; }; 11 | 4567B72A23683F74001B9D3E /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B72923683F74001B9D3E /* SceneDelegate.swift */; }; 12 | 4567B72E23683F75001B9D3E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4567B72D23683F75001B9D3E /* Assets.xcassets */; }; 13 | 4567B73123683F75001B9D3E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4567B73023683F75001B9D3E /* Preview Assets.xcassets */; }; 14 | 4567B73423683F75001B9D3E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4567B73223683F75001B9D3E /* LaunchScreen.storyboard */; }; 15 | 4567B73F23683F76001B9D3E /* VoiceRecorderFinishedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B73E23683F76001B9D3E /* VoiceRecorderFinishedTests.swift */; }; 16 | 4567B74A23683F76001B9D3E /* VoiceRecorderFinishedUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B74923683F76001B9D3E /* VoiceRecorderFinishedUITests.swift */; }; 17 | 4567B75D23683F93001B9D3E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B75723683F93001B9D3E /* ContentView.swift */; }; 18 | 4567B75E23683F93001B9D3E /* AudioRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B75823683F93001B9D3E /* AudioRecorder.swift */; }; 19 | 4567B75F23683F93001B9D3E /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B75923683F93001B9D3E /* Extensions.swift */; }; 20 | 4567B76023683F93001B9D3E /* RecordingDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B75A23683F93001B9D3E /* RecordingDataModel.swift */; }; 21 | 4567B76123683F93001B9D3E /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B75B23683F93001B9D3E /* Helper.swift */; }; 22 | 4567B76223683F93001B9D3E /* RecordingsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B75C23683F93001B9D3E /* RecordingsList.swift */; }; 23 | 4567B76723688406001B9D3E /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4567B76623688406001B9D3E /* AudioPlayer.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 4567B73B23683F76001B9D3E /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 4567B71C23683F74001B9D3E /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 4567B72323683F74001B9D3E; 32 | remoteInfo = VoiceRecorderFinished; 33 | }; 34 | 4567B74623683F76001B9D3E /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 4567B71C23683F74001B9D3E /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = 4567B72323683F74001B9D3E; 39 | remoteInfo = VoiceRecorderFinished; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 4567B72423683F74001B9D3E /* VoiceRecorderFinished.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoiceRecorderFinished.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 4567B72723683F74001B9D3E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46 | 4567B72923683F74001B9D3E /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 47 | 4567B72D23683F75001B9D3E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 4567B73023683F75001B9D3E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 49 | 4567B73323683F75001B9D3E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 4567B73523683F75001B9D3E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 4567B73A23683F76001B9D3E /* VoiceRecorderFinishedTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoiceRecorderFinishedTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 4567B73E23683F76001B9D3E /* VoiceRecorderFinishedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceRecorderFinishedTests.swift; sourceTree = ""; }; 53 | 4567B74023683F76001B9D3E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 4567B74523683F76001B9D3E /* VoiceRecorderFinishedUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoiceRecorderFinishedUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 4567B74923683F76001B9D3E /* VoiceRecorderFinishedUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceRecorderFinishedUITests.swift; sourceTree = ""; }; 56 | 4567B74B23683F76001B9D3E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 4567B75723683F93001B9D3E /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 58 | 4567B75823683F93001B9D3E /* AudioRecorder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioRecorder.swift; sourceTree = ""; }; 59 | 4567B75923683F93001B9D3E /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 60 | 4567B75A23683F93001B9D3E /* RecordingDataModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecordingDataModel.swift; sourceTree = ""; }; 61 | 4567B75B23683F93001B9D3E /* Helper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helper.swift; sourceTree = ""; }; 62 | 4567B75C23683F93001B9D3E /* RecordingsList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecordingsList.swift; sourceTree = ""; }; 63 | 4567B76623688406001B9D3E /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | 4567B72123683F74001B9D3E /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 4567B73723683F76001B9D3E /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 4567B74223683F76001B9D3E /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | 4567B71B23683F74001B9D3E = { 92 | isa = PBXGroup; 93 | children = ( 94 | 4567B72623683F74001B9D3E /* VoiceRecorderFinished */, 95 | 4567B73D23683F76001B9D3E /* VoiceRecorderFinishedTests */, 96 | 4567B74823683F76001B9D3E /* VoiceRecorderFinishedUITests */, 97 | 4567B72523683F74001B9D3E /* Products */, 98 | ); 99 | sourceTree = ""; 100 | }; 101 | 4567B72523683F74001B9D3E /* Products */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 4567B72423683F74001B9D3E /* VoiceRecorderFinished.app */, 105 | 4567B73A23683F76001B9D3E /* VoiceRecorderFinishedTests.xctest */, 106 | 4567B74523683F76001B9D3E /* VoiceRecorderFinishedUITests.xctest */, 107 | ); 108 | name = Products; 109 | sourceTree = ""; 110 | }; 111 | 4567B72623683F74001B9D3E /* VoiceRecorderFinished */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 4567B72723683F74001B9D3E /* AppDelegate.swift */, 115 | 4567B72923683F74001B9D3E /* SceneDelegate.swift */, 116 | 4567B76323686A97001B9D3E /* Views */, 117 | 4567B76423686AAE001B9D3E /* Audio Managers */, 118 | 4567B76523686ADC001B9D3E /* Div */, 119 | 4567B72D23683F75001B9D3E /* Assets.xcassets */, 120 | 4567B73223683F75001B9D3E /* LaunchScreen.storyboard */, 121 | 4567B73523683F75001B9D3E /* Info.plist */, 122 | 4567B72F23683F75001B9D3E /* Preview Content */, 123 | ); 124 | path = VoiceRecorderFinished; 125 | sourceTree = ""; 126 | }; 127 | 4567B72F23683F75001B9D3E /* Preview Content */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 4567B73023683F75001B9D3E /* Preview Assets.xcassets */, 131 | ); 132 | path = "Preview Content"; 133 | sourceTree = ""; 134 | }; 135 | 4567B73D23683F76001B9D3E /* VoiceRecorderFinishedTests */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 4567B73E23683F76001B9D3E /* VoiceRecorderFinishedTests.swift */, 139 | 4567B74023683F76001B9D3E /* Info.plist */, 140 | ); 141 | path = VoiceRecorderFinishedTests; 142 | sourceTree = ""; 143 | }; 144 | 4567B74823683F76001B9D3E /* VoiceRecorderFinishedUITests */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 4567B74923683F76001B9D3E /* VoiceRecorderFinishedUITests.swift */, 148 | 4567B74B23683F76001B9D3E /* Info.plist */, 149 | ); 150 | path = VoiceRecorderFinishedUITests; 151 | sourceTree = ""; 152 | }; 153 | 4567B76323686A97001B9D3E /* Views */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 4567B75723683F93001B9D3E /* ContentView.swift */, 157 | 4567B75C23683F93001B9D3E /* RecordingsList.swift */, 158 | ); 159 | path = Views; 160 | sourceTree = ""; 161 | }; 162 | 4567B76423686AAE001B9D3E /* Audio Managers */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 4567B75823683F93001B9D3E /* AudioRecorder.swift */, 166 | 4567B76623688406001B9D3E /* AudioPlayer.swift */, 167 | ); 168 | path = "Audio Managers"; 169 | sourceTree = ""; 170 | }; 171 | 4567B76523686ADC001B9D3E /* Div */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 4567B75A23683F93001B9D3E /* RecordingDataModel.swift */, 175 | 4567B75B23683F93001B9D3E /* Helper.swift */, 176 | 4567B75923683F93001B9D3E /* Extensions.swift */, 177 | ); 178 | path = Div; 179 | sourceTree = ""; 180 | }; 181 | /* End PBXGroup section */ 182 | 183 | /* Begin PBXNativeTarget section */ 184 | 4567B72323683F74001B9D3E /* VoiceRecorderFinished */ = { 185 | isa = PBXNativeTarget; 186 | buildConfigurationList = 4567B74E23683F76001B9D3E /* Build configuration list for PBXNativeTarget "VoiceRecorderFinished" */; 187 | buildPhases = ( 188 | 4567B72023683F74001B9D3E /* Sources */, 189 | 4567B72123683F74001B9D3E /* Frameworks */, 190 | 4567B72223683F74001B9D3E /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = VoiceRecorderFinished; 197 | productName = VoiceRecorderFinished; 198 | productReference = 4567B72423683F74001B9D3E /* VoiceRecorderFinished.app */; 199 | productType = "com.apple.product-type.application"; 200 | }; 201 | 4567B73923683F76001B9D3E /* VoiceRecorderFinishedTests */ = { 202 | isa = PBXNativeTarget; 203 | buildConfigurationList = 4567B75123683F76001B9D3E /* Build configuration list for PBXNativeTarget "VoiceRecorderFinishedTests" */; 204 | buildPhases = ( 205 | 4567B73623683F76001B9D3E /* Sources */, 206 | 4567B73723683F76001B9D3E /* Frameworks */, 207 | 4567B73823683F76001B9D3E /* Resources */, 208 | ); 209 | buildRules = ( 210 | ); 211 | dependencies = ( 212 | 4567B73C23683F76001B9D3E /* PBXTargetDependency */, 213 | ); 214 | name = VoiceRecorderFinishedTests; 215 | productName = VoiceRecorderFinishedTests; 216 | productReference = 4567B73A23683F76001B9D3E /* VoiceRecorderFinishedTests.xctest */; 217 | productType = "com.apple.product-type.bundle.unit-test"; 218 | }; 219 | 4567B74423683F76001B9D3E /* VoiceRecorderFinishedUITests */ = { 220 | isa = PBXNativeTarget; 221 | buildConfigurationList = 4567B75423683F76001B9D3E /* Build configuration list for PBXNativeTarget "VoiceRecorderFinishedUITests" */; 222 | buildPhases = ( 223 | 4567B74123683F76001B9D3E /* Sources */, 224 | 4567B74223683F76001B9D3E /* Frameworks */, 225 | 4567B74323683F76001B9D3E /* Resources */, 226 | ); 227 | buildRules = ( 228 | ); 229 | dependencies = ( 230 | 4567B74723683F76001B9D3E /* PBXTargetDependency */, 231 | ); 232 | name = VoiceRecorderFinishedUITests; 233 | productName = VoiceRecorderFinishedUITests; 234 | productReference = 4567B74523683F76001B9D3E /* VoiceRecorderFinishedUITests.xctest */; 235 | productType = "com.apple.product-type.bundle.ui-testing"; 236 | }; 237 | /* End PBXNativeTarget section */ 238 | 239 | /* Begin PBXProject section */ 240 | 4567B71C23683F74001B9D3E /* Project object */ = { 241 | isa = PBXProject; 242 | attributes = { 243 | LastSwiftUpdateCheck = 1110; 244 | LastUpgradeCheck = 1110; 245 | ORGANIZATIONNAME = "Andreas Schultz"; 246 | TargetAttributes = { 247 | 4567B72323683F74001B9D3E = { 248 | CreatedOnToolsVersion = 11.1; 249 | }; 250 | 4567B73923683F76001B9D3E = { 251 | CreatedOnToolsVersion = 11.1; 252 | TestTargetID = 4567B72323683F74001B9D3E; 253 | }; 254 | 4567B74423683F76001B9D3E = { 255 | CreatedOnToolsVersion = 11.1; 256 | TestTargetID = 4567B72323683F74001B9D3E; 257 | }; 258 | }; 259 | }; 260 | buildConfigurationList = 4567B71F23683F74001B9D3E /* Build configuration list for PBXProject "VoiceRecorderFinished" */; 261 | compatibilityVersion = "Xcode 9.3"; 262 | developmentRegion = en; 263 | hasScannedForEncodings = 0; 264 | knownRegions = ( 265 | en, 266 | Base, 267 | ); 268 | mainGroup = 4567B71B23683F74001B9D3E; 269 | productRefGroup = 4567B72523683F74001B9D3E /* Products */; 270 | projectDirPath = ""; 271 | projectRoot = ""; 272 | targets = ( 273 | 4567B72323683F74001B9D3E /* VoiceRecorderFinished */, 274 | 4567B73923683F76001B9D3E /* VoiceRecorderFinishedTests */, 275 | 4567B74423683F76001B9D3E /* VoiceRecorderFinishedUITests */, 276 | ); 277 | }; 278 | /* End PBXProject section */ 279 | 280 | /* Begin PBXResourcesBuildPhase section */ 281 | 4567B72223683F74001B9D3E /* Resources */ = { 282 | isa = PBXResourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 4567B73423683F75001B9D3E /* LaunchScreen.storyboard in Resources */, 286 | 4567B73123683F75001B9D3E /* Preview Assets.xcassets in Resources */, 287 | 4567B72E23683F75001B9D3E /* Assets.xcassets in Resources */, 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | 4567B73823683F76001B9D3E /* Resources */ = { 292 | isa = PBXResourcesBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | 4567B74323683F76001B9D3E /* Resources */ = { 299 | isa = PBXResourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | /* End PBXResourcesBuildPhase section */ 306 | 307 | /* Begin PBXSourcesBuildPhase section */ 308 | 4567B72023683F74001B9D3E /* Sources */ = { 309 | isa = PBXSourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | 4567B75F23683F93001B9D3E /* Extensions.swift in Sources */, 313 | 4567B76123683F93001B9D3E /* Helper.swift in Sources */, 314 | 4567B76723688406001B9D3E /* AudioPlayer.swift in Sources */, 315 | 4567B72823683F74001B9D3E /* AppDelegate.swift in Sources */, 316 | 4567B76223683F93001B9D3E /* RecordingsList.swift in Sources */, 317 | 4567B72A23683F74001B9D3E /* SceneDelegate.swift in Sources */, 318 | 4567B76023683F93001B9D3E /* RecordingDataModel.swift in Sources */, 319 | 4567B75E23683F93001B9D3E /* AudioRecorder.swift in Sources */, 320 | 4567B75D23683F93001B9D3E /* ContentView.swift in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | 4567B73623683F76001B9D3E /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | 4567B73F23683F76001B9D3E /* VoiceRecorderFinishedTests.swift in Sources */, 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | }; 332 | 4567B74123683F76001B9D3E /* Sources */ = { 333 | isa = PBXSourcesBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | 4567B74A23683F76001B9D3E /* VoiceRecorderFinishedUITests.swift in Sources */, 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | /* End PBXSourcesBuildPhase section */ 341 | 342 | /* Begin PBXTargetDependency section */ 343 | 4567B73C23683F76001B9D3E /* PBXTargetDependency */ = { 344 | isa = PBXTargetDependency; 345 | target = 4567B72323683F74001B9D3E /* VoiceRecorderFinished */; 346 | targetProxy = 4567B73B23683F76001B9D3E /* PBXContainerItemProxy */; 347 | }; 348 | 4567B74723683F76001B9D3E /* PBXTargetDependency */ = { 349 | isa = PBXTargetDependency; 350 | target = 4567B72323683F74001B9D3E /* VoiceRecorderFinished */; 351 | targetProxy = 4567B74623683F76001B9D3E /* PBXContainerItemProxy */; 352 | }; 353 | /* End PBXTargetDependency section */ 354 | 355 | /* Begin PBXVariantGroup section */ 356 | 4567B73223683F75001B9D3E /* LaunchScreen.storyboard */ = { 357 | isa = PBXVariantGroup; 358 | children = ( 359 | 4567B73323683F75001B9D3E /* Base */, 360 | ); 361 | name = LaunchScreen.storyboard; 362 | sourceTree = ""; 363 | }; 364 | /* End PBXVariantGroup section */ 365 | 366 | /* Begin XCBuildConfiguration section */ 367 | 4567B74C23683F76001B9D3E /* Debug */ = { 368 | isa = XCBuildConfiguration; 369 | buildSettings = { 370 | ALWAYS_SEARCH_USER_PATHS = NO; 371 | CLANG_ANALYZER_NONNULL = YES; 372 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 373 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 374 | CLANG_CXX_LIBRARY = "libc++"; 375 | CLANG_ENABLE_MODULES = YES; 376 | CLANG_ENABLE_OBJC_ARC = YES; 377 | CLANG_ENABLE_OBJC_WEAK = YES; 378 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 379 | CLANG_WARN_BOOL_CONVERSION = YES; 380 | CLANG_WARN_COMMA = YES; 381 | CLANG_WARN_CONSTANT_CONVERSION = YES; 382 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 383 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 384 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 385 | CLANG_WARN_EMPTY_BODY = YES; 386 | CLANG_WARN_ENUM_CONVERSION = YES; 387 | CLANG_WARN_INFINITE_RECURSION = YES; 388 | CLANG_WARN_INT_CONVERSION = YES; 389 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 390 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 391 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 392 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 393 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 394 | CLANG_WARN_STRICT_PROTOTYPES = YES; 395 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 396 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 397 | CLANG_WARN_UNREACHABLE_CODE = YES; 398 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 399 | COPY_PHASE_STRIP = NO; 400 | DEBUG_INFORMATION_FORMAT = dwarf; 401 | ENABLE_STRICT_OBJC_MSGSEND = YES; 402 | ENABLE_TESTABILITY = YES; 403 | GCC_C_LANGUAGE_STANDARD = gnu11; 404 | GCC_DYNAMIC_NO_PIC = NO; 405 | GCC_NO_COMMON_BLOCKS = YES; 406 | GCC_OPTIMIZATION_LEVEL = 0; 407 | GCC_PREPROCESSOR_DEFINITIONS = ( 408 | "DEBUG=1", 409 | "$(inherited)", 410 | ); 411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 413 | GCC_WARN_UNDECLARED_SELECTOR = YES; 414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 415 | GCC_WARN_UNUSED_FUNCTION = YES; 416 | GCC_WARN_UNUSED_VARIABLE = YES; 417 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 418 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 419 | MTL_FAST_MATH = YES; 420 | ONLY_ACTIVE_ARCH = YES; 421 | SDKROOT = iphoneos; 422 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 423 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 424 | }; 425 | name = Debug; 426 | }; 427 | 4567B74D23683F76001B9D3E /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | ALWAYS_SEARCH_USER_PATHS = NO; 431 | CLANG_ANALYZER_NONNULL = YES; 432 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_ENABLE_MODULES = YES; 436 | CLANG_ENABLE_OBJC_ARC = YES; 437 | CLANG_ENABLE_OBJC_WEAK = YES; 438 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 439 | CLANG_WARN_BOOL_CONVERSION = YES; 440 | CLANG_WARN_COMMA = YES; 441 | CLANG_WARN_CONSTANT_CONVERSION = YES; 442 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 443 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 444 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 445 | CLANG_WARN_EMPTY_BODY = YES; 446 | CLANG_WARN_ENUM_CONVERSION = YES; 447 | CLANG_WARN_INFINITE_RECURSION = YES; 448 | CLANG_WARN_INT_CONVERSION = YES; 449 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 450 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 451 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 452 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 453 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 454 | CLANG_WARN_STRICT_PROTOTYPES = YES; 455 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 456 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 457 | CLANG_WARN_UNREACHABLE_CODE = YES; 458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 459 | COPY_PHASE_STRIP = NO; 460 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 461 | ENABLE_NS_ASSERTIONS = NO; 462 | ENABLE_STRICT_OBJC_MSGSEND = YES; 463 | GCC_C_LANGUAGE_STANDARD = gnu11; 464 | GCC_NO_COMMON_BLOCKS = YES; 465 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 466 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 467 | GCC_WARN_UNDECLARED_SELECTOR = YES; 468 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 469 | GCC_WARN_UNUSED_FUNCTION = YES; 470 | GCC_WARN_UNUSED_VARIABLE = YES; 471 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 472 | MTL_ENABLE_DEBUG_INFO = NO; 473 | MTL_FAST_MATH = YES; 474 | SDKROOT = iphoneos; 475 | SWIFT_COMPILATION_MODE = wholemodule; 476 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 477 | VALIDATE_PRODUCT = YES; 478 | }; 479 | name = Release; 480 | }; 481 | 4567B74F23683F76001B9D3E /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | buildSettings = { 484 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 485 | CODE_SIGN_STYLE = Automatic; 486 | DEVELOPMENT_ASSET_PATHS = "\"VoiceRecorderFinished/Preview Content\""; 487 | DEVELOPMENT_TEAM = Q5Q99Q7248; 488 | ENABLE_PREVIEWS = YES; 489 | INFOPLIST_FILE = VoiceRecorderFinished/Info.plist; 490 | LD_RUNPATH_SEARCH_PATHS = ( 491 | "$(inherited)", 492 | "@executable_path/Frameworks", 493 | ); 494 | PRODUCT_BUNDLE_IDENTIFIER = com.andreasschultz.VoiceRecorderFinished; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | SWIFT_VERSION = 5.0; 497 | TARGETED_DEVICE_FAMILY = "1,2"; 498 | }; 499 | name = Debug; 500 | }; 501 | 4567B75023683F76001B9D3E /* Release */ = { 502 | isa = XCBuildConfiguration; 503 | buildSettings = { 504 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 505 | CODE_SIGN_STYLE = Automatic; 506 | DEVELOPMENT_ASSET_PATHS = "\"VoiceRecorderFinished/Preview Content\""; 507 | DEVELOPMENT_TEAM = Q5Q99Q7248; 508 | ENABLE_PREVIEWS = YES; 509 | INFOPLIST_FILE = VoiceRecorderFinished/Info.plist; 510 | LD_RUNPATH_SEARCH_PATHS = ( 511 | "$(inherited)", 512 | "@executable_path/Frameworks", 513 | ); 514 | PRODUCT_BUNDLE_IDENTIFIER = com.andreasschultz.VoiceRecorderFinished; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | SWIFT_VERSION = 5.0; 517 | TARGETED_DEVICE_FAMILY = "1,2"; 518 | }; 519 | name = Release; 520 | }; 521 | 4567B75223683F76001B9D3E /* Debug */ = { 522 | isa = XCBuildConfiguration; 523 | buildSettings = { 524 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 525 | BUNDLE_LOADER = "$(TEST_HOST)"; 526 | CODE_SIGN_STYLE = Automatic; 527 | DEVELOPMENT_TEAM = Q5Q99Q7248; 528 | INFOPLIST_FILE = VoiceRecorderFinishedTests/Info.plist; 529 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 530 | LD_RUNPATH_SEARCH_PATHS = ( 531 | "$(inherited)", 532 | "@executable_path/Frameworks", 533 | "@loader_path/Frameworks", 534 | ); 535 | PRODUCT_BUNDLE_IDENTIFIER = com.andreasschultz.VoiceRecorderFinishedTests; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | SWIFT_VERSION = 5.0; 538 | TARGETED_DEVICE_FAMILY = "1,2"; 539 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VoiceRecorderFinished.app/VoiceRecorderFinished"; 540 | }; 541 | name = Debug; 542 | }; 543 | 4567B75323683F76001B9D3E /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 547 | BUNDLE_LOADER = "$(TEST_HOST)"; 548 | CODE_SIGN_STYLE = Automatic; 549 | DEVELOPMENT_TEAM = Q5Q99Q7248; 550 | INFOPLIST_FILE = VoiceRecorderFinishedTests/Info.plist; 551 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 552 | LD_RUNPATH_SEARCH_PATHS = ( 553 | "$(inherited)", 554 | "@executable_path/Frameworks", 555 | "@loader_path/Frameworks", 556 | ); 557 | PRODUCT_BUNDLE_IDENTIFIER = com.andreasschultz.VoiceRecorderFinishedTests; 558 | PRODUCT_NAME = "$(TARGET_NAME)"; 559 | SWIFT_VERSION = 5.0; 560 | TARGETED_DEVICE_FAMILY = "1,2"; 561 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VoiceRecorderFinished.app/VoiceRecorderFinished"; 562 | }; 563 | name = Release; 564 | }; 565 | 4567B75523683F76001B9D3E /* Debug */ = { 566 | isa = XCBuildConfiguration; 567 | buildSettings = { 568 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 569 | CODE_SIGN_STYLE = Automatic; 570 | DEVELOPMENT_TEAM = Q5Q99Q7248; 571 | INFOPLIST_FILE = VoiceRecorderFinishedUITests/Info.plist; 572 | LD_RUNPATH_SEARCH_PATHS = ( 573 | "$(inherited)", 574 | "@executable_path/Frameworks", 575 | "@loader_path/Frameworks", 576 | ); 577 | PRODUCT_BUNDLE_IDENTIFIER = com.andreasschultz.VoiceRecorderFinishedUITests; 578 | PRODUCT_NAME = "$(TARGET_NAME)"; 579 | SWIFT_VERSION = 5.0; 580 | TARGETED_DEVICE_FAMILY = "1,2"; 581 | TEST_TARGET_NAME = VoiceRecorderFinished; 582 | }; 583 | name = Debug; 584 | }; 585 | 4567B75623683F76001B9D3E /* Release */ = { 586 | isa = XCBuildConfiguration; 587 | buildSettings = { 588 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 589 | CODE_SIGN_STYLE = Automatic; 590 | DEVELOPMENT_TEAM = Q5Q99Q7248; 591 | INFOPLIST_FILE = VoiceRecorderFinishedUITests/Info.plist; 592 | LD_RUNPATH_SEARCH_PATHS = ( 593 | "$(inherited)", 594 | "@executable_path/Frameworks", 595 | "@loader_path/Frameworks", 596 | ); 597 | PRODUCT_BUNDLE_IDENTIFIER = com.andreasschultz.VoiceRecorderFinishedUITests; 598 | PRODUCT_NAME = "$(TARGET_NAME)"; 599 | SWIFT_VERSION = 5.0; 600 | TARGETED_DEVICE_FAMILY = "1,2"; 601 | TEST_TARGET_NAME = VoiceRecorderFinished; 602 | }; 603 | name = Release; 604 | }; 605 | /* End XCBuildConfiguration section */ 606 | 607 | /* Begin XCConfigurationList section */ 608 | 4567B71F23683F74001B9D3E /* Build configuration list for PBXProject "VoiceRecorderFinished" */ = { 609 | isa = XCConfigurationList; 610 | buildConfigurations = ( 611 | 4567B74C23683F76001B9D3E /* Debug */, 612 | 4567B74D23683F76001B9D3E /* Release */, 613 | ); 614 | defaultConfigurationIsVisible = 0; 615 | defaultConfigurationName = Release; 616 | }; 617 | 4567B74E23683F76001B9D3E /* Build configuration list for PBXNativeTarget "VoiceRecorderFinished" */ = { 618 | isa = XCConfigurationList; 619 | buildConfigurations = ( 620 | 4567B74F23683F76001B9D3E /* Debug */, 621 | 4567B75023683F76001B9D3E /* Release */, 622 | ); 623 | defaultConfigurationIsVisible = 0; 624 | defaultConfigurationName = Release; 625 | }; 626 | 4567B75123683F76001B9D3E /* Build configuration list for PBXNativeTarget "VoiceRecorderFinishedTests" */ = { 627 | isa = XCConfigurationList; 628 | buildConfigurations = ( 629 | 4567B75223683F76001B9D3E /* Debug */, 630 | 4567B75323683F76001B9D3E /* Release */, 631 | ); 632 | defaultConfigurationIsVisible = 0; 633 | defaultConfigurationName = Release; 634 | }; 635 | 4567B75423683F76001B9D3E /* Build configuration list for PBXNativeTarget "VoiceRecorderFinishedUITests" */ = { 636 | isa = XCConfigurationList; 637 | buildConfigurations = ( 638 | 4567B75523683F76001B9D3E /* Debug */, 639 | 4567B75623683F76001B9D3E /* Release */, 640 | ); 641 | defaultConfigurationIsVisible = 0; 642 | defaultConfigurationName = Release; 643 | }; 644 | /* End XCConfigurationList section */ 645 | }; 646 | rootObject = 4567B71C23683F74001B9D3E /* Project object */; 647 | } 648 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished.xcodeproj/project.xcworkspace/xcuserdata/andreasschultz.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCKBIRDS/VoiceRecorderInSwiftUI/f2802c79f0767b27a8d366c8f83e96d090b9dd03/VoiceRecorderFinished/VoiceRecorderFinished.xcodeproj/project.xcworkspace/xcuserdata/andreasschultz.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished.xcodeproj/xcuserdata/andreasschultz.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | VoiceRecorderFinished.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | //AppDelegate.swift 2 | 3 | //Created by BLCKBIRDS on 29.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import UIKit 7 | 8 | @UIApplicationMain 9 | class AppDelegate: UIResponder, UIApplicationDelegate { 10 | 11 | 12 | 13 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 14 | // Override point for customization after application launch. 15 | return true 16 | } 17 | 18 | // MARK: UISceneSession Lifecycle 19 | 20 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 21 | // Called when a new scene session is being created. 22 | // Use this method to select a configuration to create the new scene with. 23 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 24 | } 25 | 26 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 27 | // Called when the user discards a scene session. 28 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 29 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 30 | } 31 | 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Audio Managers/AudioPlayer.swift: -------------------------------------------------------------------------------- 1 | //AudioPlayer.swift 2 | 3 | //Created by BLCKBIRDS on 29.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | import SwiftUI 8 | import Combine 9 | import AVFoundation 10 | 11 | class AudioPlayer: NSObject, ObservableObject, AVAudioPlayerDelegate { 12 | 13 | let objectWillChange = PassthroughSubject() 14 | 15 | var isPlaying = false { 16 | didSet { 17 | objectWillChange.send(self) 18 | } 19 | } 20 | 21 | var audioPlayer: AVAudioPlayer! 22 | 23 | func startPlayback (audio: URL) { 24 | 25 | let playbackSession = AVAudioSession.sharedInstance() 26 | 27 | do { 28 | try playbackSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker) 29 | } catch { 30 | print("Playing over the device's speakers failed") 31 | } 32 | 33 | do { 34 | audioPlayer = try AVAudioPlayer(contentsOf: audio) 35 | audioPlayer.delegate = self 36 | audioPlayer.play() 37 | isPlaying = true 38 | } catch { 39 | print("Playback failed.") 40 | } 41 | } 42 | 43 | func stopPlayback() { 44 | audioPlayer.stop() 45 | isPlaying = false 46 | } 47 | 48 | func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { 49 | if flag { 50 | isPlaying = false 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Audio Managers/AudioRecorder.swift: -------------------------------------------------------------------------------- 1 | //AudioRecorder.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | import SwiftUI 8 | import AVFoundation 9 | import Combine 10 | 11 | class AudioRecorder: NSObject,ObservableObject { 12 | 13 | override init() { 14 | super.init() 15 | fetchRecordings() 16 | } 17 | 18 | let objectWillChange = PassthroughSubject() 19 | 20 | var audioRecorder: AVAudioRecorder! 21 | 22 | var recordings = [Recording]() 23 | 24 | var recording = false { 25 | didSet { 26 | objectWillChange.send(self) 27 | } 28 | } 29 | 30 | func startRecording() { 31 | let recordingSession = AVAudioSession.sharedInstance() 32 | 33 | do { 34 | try recordingSession.setCategory(.playAndRecord, mode: .default) 35 | try recordingSession.setActive(true) 36 | } catch { 37 | print("Failed to set up recording session") 38 | } 39 | 40 | let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] 41 | let audioFilename = documentPath.appendingPathComponent("\(Date().toString(dateFormat: "dd-MM-YY_'at'_HH:mm:ss")).m4a") 42 | 43 | let settings = [ 44 | AVFormatIDKey: Int(kAudioFormatMPEG4AAC), 45 | AVSampleRateKey: 12000, 46 | AVNumberOfChannelsKey: 1, 47 | AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue 48 | ] 49 | 50 | do { 51 | audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings) 52 | audioRecorder.record() 53 | 54 | recording = true 55 | } catch { 56 | print("Could not start recording") 57 | } 58 | } 59 | 60 | func stopRecording() { 61 | audioRecorder.stop() 62 | recording = false 63 | 64 | fetchRecordings() 65 | } 66 | 67 | func fetchRecordings() { 68 | recordings.removeAll() 69 | 70 | let fileManager = FileManager.default 71 | let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] 72 | let directoryContents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil) 73 | for audio in directoryContents { 74 | let recording = Recording(fileURL: audio, createdAt: getCreationDate(for: audio)) 75 | recordings.append(recording) 76 | } 77 | 78 | recordings.sort(by: { $0.createdAt.compare($1.createdAt) == .orderedAscending}) 79 | 80 | objectWillChange.send(self) 81 | } 82 | 83 | func deleteRecording(urlsToDelete: [URL]) { 84 | 85 | for url in urlsToDelete { 86 | print(url) 87 | do { 88 | try FileManager.default.removeItem(at: url) 89 | } catch { 90 | print("File could not be deleted!") 91 | } 92 | } 93 | 94 | fetchRecordings() 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Div/Extensions.swift: -------------------------------------------------------------------------------- 1 | //Extensions.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | 8 | extension Date 9 | { 10 | func toString( dateFormat format : String ) -> String 11 | { 12 | let dateFormatter = DateFormatter() 13 | dateFormatter.dateFormat = format 14 | return dateFormatter.string(from: self) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Div/Helper.swift: -------------------------------------------------------------------------------- 1 | //Helper.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | 8 | func getCreationDate(for file: URL) -> Date { 9 | if let attributes = try? FileManager.default.attributesOfItem(atPath: file.path) as [FileAttributeKey: Any], 10 | let creationDate = attributes[FileAttributeKey.creationDate] as? Date { 11 | return creationDate 12 | } else { 13 | return Date() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Div/RecordingDataModel.swift: -------------------------------------------------------------------------------- 1 | //RecordingDataModel.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | 8 | struct Recording { 9 | let fileURL: URL 10 | let createdAt: Date 11 | } 12 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSMicrophoneUsageDescription 6 | We need access to your microphone to conduct recording sessions. 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIApplicationSceneManifest 26 | 27 | UIApplicationSupportsMultipleScenes 28 | 29 | UISceneConfigurations 30 | 31 | UIWindowSceneSessionRoleApplication 32 | 33 | 34 | UISceneConfigurationName 35 | Default Configuration 36 | UISceneDelegateClassName 37 | $(PRODUCT_MODULE_NAME).SceneDelegate 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UISupportedInterfaceOrientations~ipad 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | //SceneDelegate.swift 2 | 3 | //Created by BLCKBIRDS on 29.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import UIKit 7 | import SwiftUI 8 | 9 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 10 | 11 | var window: UIWindow? 12 | 13 | 14 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 15 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 16 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 17 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 18 | 19 | // Create the SwiftUI view that provides the window contents. 20 | let contentView = ContentView(audioRecorder: AudioRecorder()) 21 | 22 | // Use a UIHostingController as window root view controller. 23 | if let windowScene = scene as? UIWindowScene { 24 | let window = UIWindow(windowScene: windowScene) 25 | window.rootViewController = UIHostingController(rootView: contentView) 26 | self.window = window 27 | window.makeKeyAndVisible() 28 | } 29 | } 30 | 31 | func sceneDidDisconnect(_ scene: UIScene) { 32 | // Called as the scene is being released by the system. 33 | // This occurs shortly after the scene enters the background, or when its session is discarded. 34 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 35 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 36 | } 37 | 38 | func sceneDidBecomeActive(_ scene: UIScene) { 39 | // Called when the scene has moved from an inactive state to an active state. 40 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 41 | } 42 | 43 | func sceneWillResignActive(_ scene: UIScene) { 44 | // Called when the scene will move from an active state to an inactive state. 45 | // This may occur due to temporary interruptions (ex. an incoming phone call). 46 | } 47 | 48 | func sceneWillEnterForeground(_ scene: UIScene) { 49 | // Called as the scene transitions from the background to the foreground. 50 | // Use this method to undo the changes made on entering the background. 51 | } 52 | 53 | func sceneDidEnterBackground(_ scene: UIScene) { 54 | // Called as the scene transitions from the foreground to the background. 55 | // Use this method to save data, release shared resources, and store enough scene-specific state information 56 | // to restore the scene back to its current state. 57 | } 58 | 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Views/ContentView.swift: -------------------------------------------------------------------------------- 1 | //ContentView.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import SwiftUI 7 | 8 | struct ContentView: View { 9 | 10 | @ObservedObject var audioRecorder: AudioRecorder 11 | 12 | var body: some View { 13 | NavigationView { 14 | VStack { 15 | RecordingsList(audioRecorder: audioRecorder) 16 | if audioRecorder.recording == false { 17 | Button(action: {print(self.audioRecorder.startRecording())}) { 18 | Image(systemName: "circle.fill") 19 | .resizable() 20 | .aspectRatio(contentMode: .fill) 21 | .frame(width: 100, height: 100) 22 | .clipped() 23 | .foregroundColor(.red) 24 | .padding(.bottom, 40) 25 | } 26 | } else { 27 | Button(action: {self.audioRecorder.stopRecording()}) { 28 | Image(systemName: "stop.fill") 29 | .resizable() 30 | .aspectRatio(contentMode: .fill) 31 | .frame(width: 100, height: 100) 32 | .clipped() 33 | .foregroundColor(.red) 34 | .padding(.bottom, 40) 35 | } 36 | } 37 | } 38 | .navigationBarTitle("Voice recorder") 39 | .navigationBarItems(trailing: EditButton()) 40 | } 41 | } 42 | } 43 | 44 | struct ContentView_Previews: PreviewProvider { 45 | static var previews: some View { 46 | ContentView(audioRecorder: AudioRecorder()) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinished/Views/RecordingsList.swift: -------------------------------------------------------------------------------- 1 | //RecordingsList.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import SwiftUI 7 | 8 | struct RecordingsList: View { 9 | 10 | @ObservedObject var audioRecorder: AudioRecorder 11 | 12 | var body: some View { 13 | List { 14 | ForEach(audioRecorder.recordings, id: \.createdAt) { recording in 15 | RecordingRow(audioURL: recording.fileURL) 16 | } 17 | .onDelete(perform: delete) 18 | } 19 | } 20 | 21 | func delete(at offsets: IndexSet) { 22 | 23 | var urlsToDelete = [URL]() 24 | for index in offsets { 25 | urlsToDelete.append(audioRecorder.recordings[index].fileURL) 26 | } 27 | audioRecorder.deleteRecording(urlsToDelete: urlsToDelete) 28 | } 29 | } 30 | 31 | struct RecordingRow: View { 32 | 33 | var audioURL: URL 34 | 35 | @ObservedObject var audioPlayer = AudioPlayer() 36 | 37 | var body: some View { 38 | HStack { 39 | Text("\(audioURL.lastPathComponent)") 40 | Spacer() 41 | if audioPlayer.isPlaying == false { 42 | Button(action: { 43 | self.audioPlayer.startPlayback(audio: self.audioURL) 44 | }) { 45 | Image(systemName: "play.circle") 46 | .imageScale(.large) 47 | } 48 | } else { 49 | Button(action: { 50 | self.audioPlayer.stopPlayback() 51 | }) { 52 | Image(systemName: "stop.fill") 53 | .imageScale(.large) 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | struct RecordingsList_Previews: PreviewProvider { 61 | static var previews: some View { 62 | RecordingsList(audioRecorder: AudioRecorder()) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinishedTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinishedTests/VoiceRecorderFinishedTests.swift: -------------------------------------------------------------------------------- 1 | //VoiceRecorderFinishedTests.swift 2 | 3 | //Created by BLCKBIRDS on 29.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import XCTest 7 | @testable import VoiceRecorderFinished 8 | 9 | class VoiceRecorderFinishedTests: XCTestCase { 10 | 11 | override func setUp() { 12 | // Put setup code here. This method is called before the invocation of each test method in the class. 13 | } 14 | 15 | override func tearDown() { 16 | // Put teardown code here. This method is called after the invocation of each test method in the class. 17 | } 18 | 19 | func testExample() { 20 | // This is an example of a functional test case. 21 | // Use XCTAssert and related functions to verify your tests produce the correct results. 22 | } 23 | 24 | func testPerformanceExample() { 25 | // This is an example of a performance test case. 26 | self.measure { 27 | // Put the code you want to measure the time of here. 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinishedUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /VoiceRecorderFinished/VoiceRecorderFinishedUITests/VoiceRecorderFinishedUITests.swift: -------------------------------------------------------------------------------- 1 | //VoiceRecorderFinishedUITests.swift 2 | 3 | //Created by BLCKBIRDS on 29.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import XCTest 7 | 8 | class VoiceRecorderFinishedUITests: XCTestCase { 9 | 10 | override func setUp() { 11 | // Put setup code here. This method is called before the invocation of each test method in the class. 12 | 13 | // In UI tests it is usually best to stop immediately when a failure occurs. 14 | continueAfterFailure = false 15 | 16 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | } 22 | 23 | func testExample() { 24 | // UI tests must launch the application that they test. 25 | let app = XCUIApplication() 26 | app.launch() 27 | 28 | // Use recording to get started writing UI tests. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | func testLaunchPerformance() { 33 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { 34 | // This measures how long it takes to launch your application. 35 | measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) { 36 | XCUIApplication().launch() 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 453A62642367443D00E95469 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A62632367443D00E95469 /* AppDelegate.swift */; }; 11 | 453A62662367443D00E95469 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A62652367443D00E95469 /* SceneDelegate.swift */; }; 12 | 453A62682367443D00E95469 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A62672367443D00E95469 /* ContentView.swift */; }; 13 | 453A626A2367444000E95469 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 453A62692367444000E95469 /* Assets.xcassets */; }; 14 | 453A626D2367444000E95469 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 453A626C2367444000E95469 /* Preview Assets.xcassets */; }; 15 | 453A62702367444000E95469 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 453A626E2367444000E95469 /* LaunchScreen.storyboard */; }; 16 | 453A627B2367444000E95469 /* VoiceRecorderPt_1Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A627A2367444000E95469 /* VoiceRecorderPt_1Tests.swift */; }; 17 | 453A62862367444000E95469 /* VoiceRecorderPt_1UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A62852367444000E95469 /* VoiceRecorderPt_1UITests.swift */; }; 18 | 453A62942367448900E95469 /* AudioRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A62932367448900E95469 /* AudioRecorder.swift */; }; 19 | 453A62962367466500E95469 /* RecordingsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A62952367466500E95469 /* RecordingsList.swift */; }; 20 | 453A629823674ADC00E95469 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A629723674ADC00E95469 /* Extensions.swift */; }; 21 | 453A629A236750E500E95469 /* RecordingDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A6299236750E500E95469 /* RecordingDataModel.swift */; }; 22 | 453A629C236751BF00E95469 /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453A629B236751BF00E95469 /* Helper.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 453A62772367444000E95469 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 453A62582367443D00E95469 /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 453A625F2367443D00E95469; 31 | remoteInfo = VoiceRecorderPt.1; 32 | }; 33 | 453A62822367444000E95469 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 453A62582367443D00E95469 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 453A625F2367443D00E95469; 38 | remoteInfo = VoiceRecorderPt.1; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 453A62602367443D00E95469 /* VoiceRecorderPt.1.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoiceRecorderPt.1.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 453A62632367443D00E95469 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 45 | 453A62652367443D00E95469 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 46 | 453A62672367443D00E95469 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 47 | 453A62692367444000E95469 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 453A626C2367444000E95469 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 49 | 453A626F2367444000E95469 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 453A62712367444000E95469 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 453A62762367444000E95469 /* VoiceRecorderPt.1Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoiceRecorderPt.1Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 453A627A2367444000E95469 /* VoiceRecorderPt_1Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceRecorderPt_1Tests.swift; sourceTree = ""; }; 53 | 453A627C2367444000E95469 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 453A62812367444000E95469 /* VoiceRecorderPt.1UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoiceRecorderPt.1UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 453A62852367444000E95469 /* VoiceRecorderPt_1UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceRecorderPt_1UITests.swift; sourceTree = ""; }; 56 | 453A62872367444000E95469 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 453A62932367448900E95469 /* AudioRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecorder.swift; sourceTree = ""; }; 58 | 453A62952367466500E95469 /* RecordingsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingsList.swift; sourceTree = ""; }; 59 | 453A629723674ADC00E95469 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 60 | 453A6299236750E500E95469 /* RecordingDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingDataModel.swift; sourceTree = ""; }; 61 | 453A629B236751BF00E95469 /* Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helper.swift; sourceTree = ""; }; 62 | /* End PBXFileReference section */ 63 | 64 | /* Begin PBXFrameworksBuildPhase section */ 65 | 453A625D2367443D00E95469 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | 453A62732367444000E95469 /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 453A627E2367444000E95469 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXFrameworksBuildPhase section */ 87 | 88 | /* Begin PBXGroup section */ 89 | 453A62572367443D00E95469 = { 90 | isa = PBXGroup; 91 | children = ( 92 | 453A62622367443D00E95469 /* VoiceRecorderPt.1 */, 93 | 453A62792367444000E95469 /* VoiceRecorderPt.1Tests */, 94 | 453A62842367444000E95469 /* VoiceRecorderPt.1UITests */, 95 | 453A62612367443D00E95469 /* Products */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | 453A62612367443D00E95469 /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 453A62602367443D00E95469 /* VoiceRecorderPt.1.app */, 103 | 453A62762367444000E95469 /* VoiceRecorderPt.1Tests.xctest */, 104 | 453A62812367444000E95469 /* VoiceRecorderPt.1UITests.xctest */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 453A62622367443D00E95469 /* VoiceRecorderPt.1 */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 453A62632367443D00E95469 /* AppDelegate.swift */, 113 | 453A62652367443D00E95469 /* SceneDelegate.swift */, 114 | 453A62672367443D00E95469 /* ContentView.swift */, 115 | 453A6299236750E500E95469 /* RecordingDataModel.swift */, 116 | 453A62952367466500E95469 /* RecordingsList.swift */, 117 | 453A62932367448900E95469 /* AudioRecorder.swift */, 118 | 453A629B236751BF00E95469 /* Helper.swift */, 119 | 453A629723674ADC00E95469 /* Extensions.swift */, 120 | 453A62692367444000E95469 /* Assets.xcassets */, 121 | 453A626E2367444000E95469 /* LaunchScreen.storyboard */, 122 | 453A62712367444000E95469 /* Info.plist */, 123 | 453A626B2367444000E95469 /* Preview Content */, 124 | ); 125 | path = VoiceRecorderPt.1; 126 | sourceTree = ""; 127 | }; 128 | 453A626B2367444000E95469 /* Preview Content */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 453A626C2367444000E95469 /* Preview Assets.xcassets */, 132 | ); 133 | path = "Preview Content"; 134 | sourceTree = ""; 135 | }; 136 | 453A62792367444000E95469 /* VoiceRecorderPt.1Tests */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 453A627A2367444000E95469 /* VoiceRecorderPt_1Tests.swift */, 140 | 453A627C2367444000E95469 /* Info.plist */, 141 | ); 142 | path = VoiceRecorderPt.1Tests; 143 | sourceTree = ""; 144 | }; 145 | 453A62842367444000E95469 /* VoiceRecorderPt.1UITests */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 453A62852367444000E95469 /* VoiceRecorderPt_1UITests.swift */, 149 | 453A62872367444000E95469 /* Info.plist */, 150 | ); 151 | path = VoiceRecorderPt.1UITests; 152 | sourceTree = ""; 153 | }; 154 | /* End PBXGroup section */ 155 | 156 | /* Begin PBXNativeTarget section */ 157 | 453A625F2367443D00E95469 /* VoiceRecorderPt.1 */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 453A628A2367444000E95469 /* Build configuration list for PBXNativeTarget "VoiceRecorderPt.1" */; 160 | buildPhases = ( 161 | 453A625C2367443D00E95469 /* Sources */, 162 | 453A625D2367443D00E95469 /* Frameworks */, 163 | 453A625E2367443D00E95469 /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | ); 169 | name = VoiceRecorderPt.1; 170 | productName = VoiceRecorderPt.1; 171 | productReference = 453A62602367443D00E95469 /* VoiceRecorderPt.1.app */; 172 | productType = "com.apple.product-type.application"; 173 | }; 174 | 453A62752367444000E95469 /* VoiceRecorderPt.1Tests */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 453A628D2367444000E95469 /* Build configuration list for PBXNativeTarget "VoiceRecorderPt.1Tests" */; 177 | buildPhases = ( 178 | 453A62722367444000E95469 /* Sources */, 179 | 453A62732367444000E95469 /* Frameworks */, 180 | 453A62742367444000E95469 /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | 453A62782367444000E95469 /* PBXTargetDependency */, 186 | ); 187 | name = VoiceRecorderPt.1Tests; 188 | productName = VoiceRecorderPt.1Tests; 189 | productReference = 453A62762367444000E95469 /* VoiceRecorderPt.1Tests.xctest */; 190 | productType = "com.apple.product-type.bundle.unit-test"; 191 | }; 192 | 453A62802367444000E95469 /* VoiceRecorderPt.1UITests */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 453A62902367444000E95469 /* Build configuration list for PBXNativeTarget "VoiceRecorderPt.1UITests" */; 195 | buildPhases = ( 196 | 453A627D2367444000E95469 /* Sources */, 197 | 453A627E2367444000E95469 /* Frameworks */, 198 | 453A627F2367444000E95469 /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | 453A62832367444000E95469 /* PBXTargetDependency */, 204 | ); 205 | name = VoiceRecorderPt.1UITests; 206 | productName = VoiceRecorderPt.1UITests; 207 | productReference = 453A62812367444000E95469 /* VoiceRecorderPt.1UITests.xctest */; 208 | productType = "com.apple.product-type.bundle.ui-testing"; 209 | }; 210 | /* End PBXNativeTarget section */ 211 | 212 | /* Begin PBXProject section */ 213 | 453A62582367443D00E95469 /* Project object */ = { 214 | isa = PBXProject; 215 | attributes = { 216 | LastSwiftUpdateCheck = 1110; 217 | LastUpgradeCheck = 1110; 218 | ORGANIZATIONNAME = "Andreas Schultz"; 219 | TargetAttributes = { 220 | 453A625F2367443D00E95469 = { 221 | CreatedOnToolsVersion = 11.1; 222 | }; 223 | 453A62752367444000E95469 = { 224 | CreatedOnToolsVersion = 11.1; 225 | TestTargetID = 453A625F2367443D00E95469; 226 | }; 227 | 453A62802367444000E95469 = { 228 | CreatedOnToolsVersion = 11.1; 229 | TestTargetID = 453A625F2367443D00E95469; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 453A625B2367443D00E95469 /* Build configuration list for PBXProject "VoiceRecorderPt.1" */; 234 | compatibilityVersion = "Xcode 9.3"; 235 | developmentRegion = en; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | Base, 240 | ); 241 | mainGroup = 453A62572367443D00E95469; 242 | productRefGroup = 453A62612367443D00E95469 /* Products */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 453A625F2367443D00E95469 /* VoiceRecorderPt.1 */, 247 | 453A62752367444000E95469 /* VoiceRecorderPt.1Tests */, 248 | 453A62802367444000E95469 /* VoiceRecorderPt.1UITests */, 249 | ); 250 | }; 251 | /* End PBXProject section */ 252 | 253 | /* Begin PBXResourcesBuildPhase section */ 254 | 453A625E2367443D00E95469 /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | 453A62702367444000E95469 /* LaunchScreen.storyboard in Resources */, 259 | 453A626D2367444000E95469 /* Preview Assets.xcassets in Resources */, 260 | 453A626A2367444000E95469 /* Assets.xcassets in Resources */, 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | }; 264 | 453A62742367444000E95469 /* Resources */ = { 265 | isa = PBXResourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 453A627F2367444000E95469 /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | /* End PBXResourcesBuildPhase section */ 279 | 280 | /* Begin PBXSourcesBuildPhase section */ 281 | 453A625C2367443D00E95469 /* Sources */ = { 282 | isa = PBXSourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 453A62642367443D00E95469 /* AppDelegate.swift in Sources */, 286 | 453A629823674ADC00E95469 /* Extensions.swift in Sources */, 287 | 453A629A236750E500E95469 /* RecordingDataModel.swift in Sources */, 288 | 453A62662367443D00E95469 /* SceneDelegate.swift in Sources */, 289 | 453A62962367466500E95469 /* RecordingsList.swift in Sources */, 290 | 453A62942367448900E95469 /* AudioRecorder.swift in Sources */, 291 | 453A62682367443D00E95469 /* ContentView.swift in Sources */, 292 | 453A629C236751BF00E95469 /* Helper.swift in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | 453A62722367444000E95469 /* Sources */ = { 297 | isa = PBXSourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | 453A627B2367444000E95469 /* VoiceRecorderPt_1Tests.swift in Sources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | 453A627D2367444000E95469 /* Sources */ = { 305 | isa = PBXSourcesBuildPhase; 306 | buildActionMask = 2147483647; 307 | files = ( 308 | 453A62862367444000E95469 /* VoiceRecorderPt_1UITests.swift in Sources */, 309 | ); 310 | runOnlyForDeploymentPostprocessing = 0; 311 | }; 312 | /* End PBXSourcesBuildPhase section */ 313 | 314 | /* Begin PBXTargetDependency section */ 315 | 453A62782367444000E95469 /* PBXTargetDependency */ = { 316 | isa = PBXTargetDependency; 317 | target = 453A625F2367443D00E95469 /* VoiceRecorderPt.1 */; 318 | targetProxy = 453A62772367444000E95469 /* PBXContainerItemProxy */; 319 | }; 320 | 453A62832367444000E95469 /* PBXTargetDependency */ = { 321 | isa = PBXTargetDependency; 322 | target = 453A625F2367443D00E95469 /* VoiceRecorderPt.1 */; 323 | targetProxy = 453A62822367444000E95469 /* PBXContainerItemProxy */; 324 | }; 325 | /* End PBXTargetDependency section */ 326 | 327 | /* Begin PBXVariantGroup section */ 328 | 453A626E2367444000E95469 /* LaunchScreen.storyboard */ = { 329 | isa = PBXVariantGroup; 330 | children = ( 331 | 453A626F2367444000E95469 /* Base */, 332 | ); 333 | name = LaunchScreen.storyboard; 334 | sourceTree = ""; 335 | }; 336 | /* End PBXVariantGroup section */ 337 | 338 | /* Begin XCBuildConfiguration section */ 339 | 453A62882367444000E95469 /* Debug */ = { 340 | isa = XCBuildConfiguration; 341 | buildSettings = { 342 | ALWAYS_SEARCH_USER_PATHS = NO; 343 | CLANG_ANALYZER_NONNULL = YES; 344 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 345 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 346 | CLANG_CXX_LIBRARY = "libc++"; 347 | CLANG_ENABLE_MODULES = YES; 348 | CLANG_ENABLE_OBJC_ARC = YES; 349 | CLANG_ENABLE_OBJC_WEAK = YES; 350 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 351 | CLANG_WARN_BOOL_CONVERSION = YES; 352 | CLANG_WARN_COMMA = YES; 353 | CLANG_WARN_CONSTANT_CONVERSION = YES; 354 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 355 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 356 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 357 | CLANG_WARN_EMPTY_BODY = YES; 358 | CLANG_WARN_ENUM_CONVERSION = YES; 359 | CLANG_WARN_INFINITE_RECURSION = YES; 360 | CLANG_WARN_INT_CONVERSION = YES; 361 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 362 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 363 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 364 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 365 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 366 | CLANG_WARN_STRICT_PROTOTYPES = YES; 367 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 368 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 369 | CLANG_WARN_UNREACHABLE_CODE = YES; 370 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 371 | COPY_PHASE_STRIP = NO; 372 | DEBUG_INFORMATION_FORMAT = dwarf; 373 | ENABLE_STRICT_OBJC_MSGSEND = YES; 374 | ENABLE_TESTABILITY = YES; 375 | GCC_C_LANGUAGE_STANDARD = gnu11; 376 | GCC_DYNAMIC_NO_PIC = NO; 377 | GCC_NO_COMMON_BLOCKS = YES; 378 | GCC_OPTIMIZATION_LEVEL = 0; 379 | GCC_PREPROCESSOR_DEFINITIONS = ( 380 | "DEBUG=1", 381 | "$(inherited)", 382 | ); 383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 385 | GCC_WARN_UNDECLARED_SELECTOR = YES; 386 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 387 | GCC_WARN_UNUSED_FUNCTION = YES; 388 | GCC_WARN_UNUSED_VARIABLE = YES; 389 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 390 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 391 | MTL_FAST_MATH = YES; 392 | ONLY_ACTIVE_ARCH = YES; 393 | SDKROOT = iphoneos; 394 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 395 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 396 | }; 397 | name = Debug; 398 | }; 399 | 453A62892367444000E95469 /* Release */ = { 400 | isa = XCBuildConfiguration; 401 | buildSettings = { 402 | ALWAYS_SEARCH_USER_PATHS = NO; 403 | CLANG_ANALYZER_NONNULL = YES; 404 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 405 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 406 | CLANG_CXX_LIBRARY = "libc++"; 407 | CLANG_ENABLE_MODULES = YES; 408 | CLANG_ENABLE_OBJC_ARC = YES; 409 | CLANG_ENABLE_OBJC_WEAK = YES; 410 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 411 | CLANG_WARN_BOOL_CONVERSION = YES; 412 | CLANG_WARN_COMMA = YES; 413 | CLANG_WARN_CONSTANT_CONVERSION = YES; 414 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 415 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 416 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 417 | CLANG_WARN_EMPTY_BODY = YES; 418 | CLANG_WARN_ENUM_CONVERSION = YES; 419 | CLANG_WARN_INFINITE_RECURSION = YES; 420 | CLANG_WARN_INT_CONVERSION = YES; 421 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 422 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 423 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 424 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 425 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 426 | CLANG_WARN_STRICT_PROTOTYPES = YES; 427 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 428 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 429 | CLANG_WARN_UNREACHABLE_CODE = YES; 430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 431 | COPY_PHASE_STRIP = NO; 432 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 433 | ENABLE_NS_ASSERTIONS = NO; 434 | ENABLE_STRICT_OBJC_MSGSEND = YES; 435 | GCC_C_LANGUAGE_STANDARD = gnu11; 436 | GCC_NO_COMMON_BLOCKS = YES; 437 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 438 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 439 | GCC_WARN_UNDECLARED_SELECTOR = YES; 440 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 441 | GCC_WARN_UNUSED_FUNCTION = YES; 442 | GCC_WARN_UNUSED_VARIABLE = YES; 443 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 444 | MTL_ENABLE_DEBUG_INFO = NO; 445 | MTL_FAST_MATH = YES; 446 | SDKROOT = iphoneos; 447 | SWIFT_COMPILATION_MODE = wholemodule; 448 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 449 | VALIDATE_PRODUCT = YES; 450 | }; 451 | name = Release; 452 | }; 453 | 453A628B2367444000E95469 /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 457 | CODE_SIGN_STYLE = Automatic; 458 | DEVELOPMENT_ASSET_PATHS = "\"VoiceRecorderPt.1/Preview Content\""; 459 | DEVELOPMENT_TEAM = Q5Q99Q7248; 460 | ENABLE_PREVIEWS = YES; 461 | INFOPLIST_FILE = VoiceRecorderPt.1/Info.plist; 462 | LD_RUNPATH_SEARCH_PATHS = ( 463 | "$(inherited)", 464 | "@executable_path/Frameworks", 465 | ); 466 | PRODUCT_BUNDLE_IDENTIFIER = "com.andreasschultz.VoiceRecorderPt-1"; 467 | PRODUCT_NAME = "$(TARGET_NAME)"; 468 | SWIFT_VERSION = 5.0; 469 | TARGETED_DEVICE_FAMILY = "1,2"; 470 | }; 471 | name = Debug; 472 | }; 473 | 453A628C2367444000E95469 /* Release */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 477 | CODE_SIGN_STYLE = Automatic; 478 | DEVELOPMENT_ASSET_PATHS = "\"VoiceRecorderPt.1/Preview Content\""; 479 | DEVELOPMENT_TEAM = Q5Q99Q7248; 480 | ENABLE_PREVIEWS = YES; 481 | INFOPLIST_FILE = VoiceRecorderPt.1/Info.plist; 482 | LD_RUNPATH_SEARCH_PATHS = ( 483 | "$(inherited)", 484 | "@executable_path/Frameworks", 485 | ); 486 | PRODUCT_BUNDLE_IDENTIFIER = "com.andreasschultz.VoiceRecorderPt-1"; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | SWIFT_VERSION = 5.0; 489 | TARGETED_DEVICE_FAMILY = "1,2"; 490 | }; 491 | name = Release; 492 | }; 493 | 453A628E2367444000E95469 /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 497 | BUNDLE_LOADER = "$(TEST_HOST)"; 498 | CODE_SIGN_STYLE = Automatic; 499 | DEVELOPMENT_TEAM = Q5Q99Q7248; 500 | INFOPLIST_FILE = VoiceRecorderPt.1Tests/Info.plist; 501 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 502 | LD_RUNPATH_SEARCH_PATHS = ( 503 | "$(inherited)", 504 | "@executable_path/Frameworks", 505 | "@loader_path/Frameworks", 506 | ); 507 | PRODUCT_BUNDLE_IDENTIFIER = "com.andreasschultz.VoiceRecorderPt-1Tests"; 508 | PRODUCT_NAME = "$(TARGET_NAME)"; 509 | SWIFT_VERSION = 5.0; 510 | TARGETED_DEVICE_FAMILY = "1,2"; 511 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VoiceRecorderPt.1.app/VoiceRecorderPt.1"; 512 | }; 513 | name = Debug; 514 | }; 515 | 453A628F2367444000E95469 /* Release */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 519 | BUNDLE_LOADER = "$(TEST_HOST)"; 520 | CODE_SIGN_STYLE = Automatic; 521 | DEVELOPMENT_TEAM = Q5Q99Q7248; 522 | INFOPLIST_FILE = VoiceRecorderPt.1Tests/Info.plist; 523 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 524 | LD_RUNPATH_SEARCH_PATHS = ( 525 | "$(inherited)", 526 | "@executable_path/Frameworks", 527 | "@loader_path/Frameworks", 528 | ); 529 | PRODUCT_BUNDLE_IDENTIFIER = "com.andreasschultz.VoiceRecorderPt-1Tests"; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | SWIFT_VERSION = 5.0; 532 | TARGETED_DEVICE_FAMILY = "1,2"; 533 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VoiceRecorderPt.1.app/VoiceRecorderPt.1"; 534 | }; 535 | name = Release; 536 | }; 537 | 453A62912367444000E95469 /* Debug */ = { 538 | isa = XCBuildConfiguration; 539 | buildSettings = { 540 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 541 | CODE_SIGN_STYLE = Automatic; 542 | DEVELOPMENT_TEAM = Q5Q99Q7248; 543 | INFOPLIST_FILE = VoiceRecorderPt.1UITests/Info.plist; 544 | LD_RUNPATH_SEARCH_PATHS = ( 545 | "$(inherited)", 546 | "@executable_path/Frameworks", 547 | "@loader_path/Frameworks", 548 | ); 549 | PRODUCT_BUNDLE_IDENTIFIER = "com.andreasschultz.VoiceRecorderPt-1UITests"; 550 | PRODUCT_NAME = "$(TARGET_NAME)"; 551 | SWIFT_VERSION = 5.0; 552 | TARGETED_DEVICE_FAMILY = "1,2"; 553 | TEST_TARGET_NAME = VoiceRecorderPt.1; 554 | }; 555 | name = Debug; 556 | }; 557 | 453A62922367444000E95469 /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 561 | CODE_SIGN_STYLE = Automatic; 562 | DEVELOPMENT_TEAM = Q5Q99Q7248; 563 | INFOPLIST_FILE = VoiceRecorderPt.1UITests/Info.plist; 564 | LD_RUNPATH_SEARCH_PATHS = ( 565 | "$(inherited)", 566 | "@executable_path/Frameworks", 567 | "@loader_path/Frameworks", 568 | ); 569 | PRODUCT_BUNDLE_IDENTIFIER = "com.andreasschultz.VoiceRecorderPt-1UITests"; 570 | PRODUCT_NAME = "$(TARGET_NAME)"; 571 | SWIFT_VERSION = 5.0; 572 | TARGETED_DEVICE_FAMILY = "1,2"; 573 | TEST_TARGET_NAME = VoiceRecorderPt.1; 574 | }; 575 | name = Release; 576 | }; 577 | /* End XCBuildConfiguration section */ 578 | 579 | /* Begin XCConfigurationList section */ 580 | 453A625B2367443D00E95469 /* Build configuration list for PBXProject "VoiceRecorderPt.1" */ = { 581 | isa = XCConfigurationList; 582 | buildConfigurations = ( 583 | 453A62882367444000E95469 /* Debug */, 584 | 453A62892367444000E95469 /* Release */, 585 | ); 586 | defaultConfigurationIsVisible = 0; 587 | defaultConfigurationName = Release; 588 | }; 589 | 453A628A2367444000E95469 /* Build configuration list for PBXNativeTarget "VoiceRecorderPt.1" */ = { 590 | isa = XCConfigurationList; 591 | buildConfigurations = ( 592 | 453A628B2367444000E95469 /* Debug */, 593 | 453A628C2367444000E95469 /* Release */, 594 | ); 595 | defaultConfigurationIsVisible = 0; 596 | defaultConfigurationName = Release; 597 | }; 598 | 453A628D2367444000E95469 /* Build configuration list for PBXNativeTarget "VoiceRecorderPt.1Tests" */ = { 599 | isa = XCConfigurationList; 600 | buildConfigurations = ( 601 | 453A628E2367444000E95469 /* Debug */, 602 | 453A628F2367444000E95469 /* Release */, 603 | ); 604 | defaultConfigurationIsVisible = 0; 605 | defaultConfigurationName = Release; 606 | }; 607 | 453A62902367444000E95469 /* Build configuration list for PBXNativeTarget "VoiceRecorderPt.1UITests" */ = { 608 | isa = XCConfigurationList; 609 | buildConfigurations = ( 610 | 453A62912367444000E95469 /* Debug */, 611 | 453A62922367444000E95469 /* Release */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | defaultConfigurationName = Release; 615 | }; 616 | /* End XCConfigurationList section */ 617 | }; 618 | rootObject = 453A62582367443D00E95469 /* Project object */; 619 | } 620 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1.xcodeproj/project.xcworkspace/xcuserdata/andreasschultz.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCKBIRDS/VoiceRecorderInSwiftUI/f2802c79f0767b27a8d366c8f83e96d090b9dd03/VoiceRecorderPt.1/VoiceRecorderPt.1.xcodeproj/project.xcworkspace/xcuserdata/andreasschultz.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1.xcodeproj/xcuserdata/andreasschultz.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | VoiceRecorderPt.1.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | //AppDelegate.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import UIKit 7 | 8 | @UIApplicationMain 9 | class AppDelegate: UIResponder, UIApplicationDelegate { 10 | 11 | 12 | 13 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 14 | // Override point for customization after application launch. 15 | return true 16 | } 17 | 18 | // MARK: UISceneSession Lifecycle 19 | 20 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 21 | // Called when a new scene session is being created. 22 | // Use this method to select a configuration to create the new scene with. 23 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 24 | } 25 | 26 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 27 | // Called when the user discards a scene session. 28 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 29 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 30 | } 31 | 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/AudioRecorder.swift: -------------------------------------------------------------------------------- 1 | //AudioRecorder.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | import SwiftUI 8 | import AVFoundation 9 | import Combine 10 | 11 | class AudioRecorder: NSObject,ObservableObject { 12 | 13 | override init() { 14 | super.init() 15 | fetchRecordings() 16 | } 17 | 18 | let objectWillChange = PassthroughSubject() 19 | 20 | var audioRecorder: AVAudioRecorder! 21 | 22 | var recordings = [Recording]() 23 | 24 | var recording = false { 25 | didSet { 26 | objectWillChange.send(self) 27 | } 28 | } 29 | 30 | func startRecording() { 31 | let recordingSession = AVAudioSession.sharedInstance() 32 | 33 | do { 34 | try recordingSession.setCategory(.playAndRecord, mode: .default) 35 | try recordingSession.setActive(true) 36 | } catch { 37 | print("Failed to set up recording session") 38 | } 39 | 40 | let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] 41 | let audioFilename = documentPath.appendingPathComponent("\(Date().toString(dateFormat: "dd-MM-YY_'at'_HH:mm:ss")).m4a") 42 | 43 | let settings = [ 44 | AVFormatIDKey: Int(kAudioFormatMPEG4AAC), 45 | AVSampleRateKey: 12000, 46 | AVNumberOfChannelsKey: 1, 47 | AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue 48 | ] 49 | 50 | do { 51 | audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings) 52 | audioRecorder.record() 53 | 54 | recording = true 55 | } catch { 56 | print("Could not start recording") 57 | } 58 | } 59 | 60 | func stopRecording() { 61 | audioRecorder.stop() 62 | recording = false 63 | 64 | fetchRecordings() 65 | } 66 | 67 | func fetchRecordings() { 68 | recordings.removeAll() 69 | 70 | let fileManager = FileManager.default 71 | let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] 72 | let directoryContents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil) 73 | for audio in directoryContents { 74 | let recording = Recording(fileURL: audio, createdAt: getCreationDate(for: audio)) 75 | recordings.append(recording) 76 | } 77 | 78 | recordings.sort(by: { $0.createdAt.compare($1.createdAt) == .orderedAscending}) 79 | 80 | objectWillChange.send(self) 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/ContentView.swift: -------------------------------------------------------------------------------- 1 | //ContentView.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import SwiftUI 7 | 8 | struct ContentView: View { 9 | 10 | @ObservedObject var audioRecorder: AudioRecorder 11 | 12 | var body: some View { 13 | NavigationView { 14 | VStack { 15 | RecordingsList(audioRecorder: audioRecorder) 16 | if audioRecorder.recording == false { 17 | Button(action: {print(self.audioRecorder.startRecording())}) { 18 | Image(systemName: "circle.fill") 19 | .resizable() 20 | .aspectRatio(contentMode: .fill) 21 | .frame(width: 100, height: 100) 22 | .clipped() 23 | .foregroundColor(.red) 24 | .padding(.bottom, 40) 25 | } 26 | } else { 27 | Button(action: {self.audioRecorder.stopRecording()}) { 28 | Image(systemName: "stop.fill") 29 | .resizable() 30 | .aspectRatio(contentMode: .fill) 31 | .frame(width: 100, height: 100) 32 | .clipped() 33 | .foregroundColor(.red) 34 | .padding(.bottom, 40) 35 | } 36 | } 37 | } 38 | .navigationBarTitle("Voice recorder") 39 | } 40 | } 41 | } 42 | 43 | struct ContentView_Previews: PreviewProvider { 44 | static var previews: some View { 45 | ContentView(audioRecorder: AudioRecorder()) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Extensions.swift: -------------------------------------------------------------------------------- 1 | //Extensions.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | 8 | extension Date 9 | { 10 | func toString( dateFormat format : String ) -> String 11 | { 12 | let dateFormatter = DateFormatter() 13 | dateFormatter.dateFormat = format 14 | return dateFormatter.string(from: self) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Helper.swift: -------------------------------------------------------------------------------- 1 | //Helper.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | 8 | func getCreationDate(for file: URL) -> Date { 9 | if let attributes = try? FileManager.default.attributesOfItem(atPath: file.path) as [FileAttributeKey: Any], 10 | let creationDate = attributes[FileAttributeKey.creationDate] as? Date { 11 | return creationDate 12 | } else { 13 | return Date() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSMicrophoneUsageDescription 6 | We need access to your microphone to conduct recording sessions. 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIApplicationSceneManifest 26 | 27 | UIApplicationSupportsMultipleScenes 28 | 29 | UISceneConfigurations 30 | 31 | UIWindowSceneSessionRoleApplication 32 | 33 | 34 | UISceneConfigurationName 35 | Default Configuration 36 | UISceneDelegateClassName 37 | $(PRODUCT_MODULE_NAME).SceneDelegate 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UISupportedInterfaceOrientations~ipad 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/RecordingDataModel.swift: -------------------------------------------------------------------------------- 1 | //RecordingDataModel.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import Foundation 7 | 8 | struct Recording { 9 | let fileURL: URL 10 | let createdAt: Date 11 | } 12 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/RecordingsList.swift: -------------------------------------------------------------------------------- 1 | //RecordingsList.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import SwiftUI 7 | 8 | struct RecordingsList: View { 9 | 10 | @ObservedObject var audioRecorder: AudioRecorder 11 | 12 | var body: some View { 13 | List { 14 | ForEach(audioRecorder.recordings, id: \.createdAt) { recording in 15 | RecordingRow(audioURL: recording.fileURL) 16 | } 17 | } 18 | } 19 | } 20 | 21 | struct RecordingRow: View { 22 | 23 | var audioURL: URL 24 | 25 | var body: some View { 26 | HStack { 27 | Text("\(audioURL.lastPathComponent)") 28 | Spacer() 29 | } 30 | } 31 | } 32 | 33 | struct RecordingsList_Previews: PreviewProvider { 34 | static var previews: some View { 35 | RecordingsList(audioRecorder: AudioRecorder()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | //SceneDelegate.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import UIKit 7 | import SwiftUI 8 | 9 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 10 | 11 | var window: UIWindow? 12 | 13 | 14 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 15 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 16 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 17 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 18 | 19 | // Create the SwiftUI view that provides the window contents. 20 | let contentView = ContentView(audioRecorder: AudioRecorder()) 21 | 22 | // Use a UIHostingController as window root view controller. 23 | if let windowScene = scene as? UIWindowScene { 24 | let window = UIWindow(windowScene: windowScene) 25 | window.rootViewController = UIHostingController(rootView: contentView) 26 | self.window = window 27 | window.makeKeyAndVisible() 28 | } 29 | } 30 | 31 | func sceneDidDisconnect(_ scene: UIScene) { 32 | // Called as the scene is being released by the system. 33 | // This occurs shortly after the scene enters the background, or when its session is discarded. 34 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 35 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 36 | } 37 | 38 | func sceneDidBecomeActive(_ scene: UIScene) { 39 | // Called when the scene has moved from an inactive state to an active state. 40 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 41 | } 42 | 43 | func sceneWillResignActive(_ scene: UIScene) { 44 | // Called when the scene will move from an active state to an inactive state. 45 | // This may occur due to temporary interruptions (ex. an incoming phone call). 46 | } 47 | 48 | func sceneWillEnterForeground(_ scene: UIScene) { 49 | // Called as the scene transitions from the background to the foreground. 50 | // Use this method to undo the changes made on entering the background. 51 | } 52 | 53 | func sceneDidEnterBackground(_ scene: UIScene) { 54 | // Called as the scene transitions from the foreground to the background. 55 | // Use this method to save data, release shared resources, and store enough scene-specific state information 56 | // to restore the scene back to its current state. 57 | } 58 | 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1Tests/VoiceRecorderPt_1Tests.swift: -------------------------------------------------------------------------------- 1 | //VoiceRecorderPt_1Tests.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import XCTest 7 | @testable import VoiceRecorderPt_1 8 | 9 | class VoiceRecorderPt_1Tests: XCTestCase { 10 | 11 | override func setUp() { 12 | // Put setup code here. This method is called before the invocation of each test method in the class. 13 | } 14 | 15 | override func tearDown() { 16 | // Put teardown code here. This method is called after the invocation of each test method in the class. 17 | } 18 | 19 | func testExample() { 20 | // This is an example of a functional test case. 21 | // Use XCTAssert and related functions to verify your tests produce the correct results. 22 | } 23 | 24 | func testPerformanceExample() { 25 | // This is an example of a performance test case. 26 | self.measure { 27 | // Put the code you want to measure the time of here. 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1UITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /VoiceRecorderPt.1/VoiceRecorderPt.1UITests/VoiceRecorderPt_1UITests.swift: -------------------------------------------------------------------------------- 1 | //VoiceRecorderPt_1UITests.swift 2 | 3 | //Created by BLCKBIRDS on 28.10.19. 4 | //Visit www.BLCKBIRDS.com for more. 5 | 6 | import XCTest 7 | 8 | class VoiceRecorderPt_1UITests: XCTestCase { 9 | 10 | override func setUp() { 11 | // Put setup code here. This method is called before the invocation of each test method in the class. 12 | 13 | // In UI tests it is usually best to stop immediately when a failure occurs. 14 | continueAfterFailure = false 15 | 16 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | } 22 | 23 | func testExample() { 24 | // UI tests must launch the application that they test. 25 | let app = XCUIApplication() 26 | app.launch() 27 | 28 | // Use recording to get started writing UI tests. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | func testLaunchPerformance() { 33 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { 34 | // This measures how long it takes to launch your application. 35 | measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) { 36 | XCUIApplication().launch() 37 | } 38 | } 39 | } 40 | } 41 | --------------------------------------------------------------------------------