Skip to content

Commit a757526

Browse files
committed
Add logging and some structure
1 parent 2b2067a commit a757526

File tree

12 files changed

+226
-45
lines changed

12 files changed

+226
-45
lines changed

.swift-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5

.swiftlint.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
disabled_rules:
2+
- line_length
3+
- unused_closure_parameter
4+
- trailing_comma
5+
- type_body_length
6+
- file_length
7+
opt_in_rules:
8+
- switch_case_on_newline
9+
- implicitly_unwrapped_optional

Operator.xcodeproj/project.pbxproj

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 50;
6+
objectVersion = 51;
77
objects = {
88

99
/* Begin PBXBuildFile section */
1010
72352439246D006D00F58C61 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72352438246D006D00F58C61 /* String+Extensions.swift */; };
11+
726A21F124701C4800DBAB87 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 726A21F024701C4800DBAB87 /* Log.swift */; };
12+
726A21F324701C5D00DBAB87 /* LogFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 726A21F224701C5D00DBAB87 /* LogFormatter.swift */; };
1113
72704C6B2460EF10006F3E99 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72704C6A2460EF10006F3E99 /* AppDelegate.swift */; };
1214
72704C6D2460EF10006F3E99 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72704C6C2460EF10006F3E99 /* SceneDelegate.swift */; };
1315
72704C6F2460EF10006F3E99 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72704C6E2460EF10006F3E99 /* ContentView.swift */; };
@@ -37,6 +39,8 @@
3739
6761102642A44577E3E6499D /* Pods-Operator.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Operator.debug.xcconfig"; path = "Target Support Files/Pods-Operator/Pods-Operator.debug.xcconfig"; sourceTree = "<group>"; };
3840
722F0F2B246CE18800C857E9 /* sample-modified.aif */ = {isa = PBXFileReference; lastKnownFileType = file; path = "sample-modified.aif"; sourceTree = "<group>"; };
3941
72352438246D006D00F58C61 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
42+
726A21F024701C4800DBAB87 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
43+
726A21F224701C5D00DBAB87 /* LogFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogFormatter.swift; sourceTree = "<group>"; };
4044
72704C672460EF10006F3E99 /* Operator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Operator.app; sourceTree = BUILT_PRODUCTS_DIR; };
4145
72704C6A2460EF10006F3E99 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
4246
72704C6C2460EF10006F3E99 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@@ -90,6 +94,25 @@
9094
path = Extensions;
9195
sourceTree = "<group>";
9296
};
97+
726A21EF24701C2A00DBAB87 /* Logging */ = {
98+
isa = PBXGroup;
99+
children = (
100+
726A21F024701C4800DBAB87 /* Log.swift */,
101+
726A21F224701C5D00DBAB87 /* LogFormatter.swift */,
102+
);
103+
path = Logging;
104+
sourceTree = "<group>";
105+
};
106+
726A21F424701C9D00DBAB87 /* Sections */ = {
107+
isa = PBXGroup;
108+
children = (
109+
72704C6A2460EF10006F3E99 /* AppDelegate.swift */,
110+
72704C6C2460EF10006F3E99 /* SceneDelegate.swift */,
111+
72704C6E2460EF10006F3E99 /* ContentView.swift */,
112+
);
113+
path = Sections;
114+
sourceTree = "<group>";
115+
};
93116
72704C5E2460EF10006F3E99 = {
94117
isa = PBXGroup;
95118
children = (
@@ -113,13 +136,9 @@
113136
72704C692460EF10006F3E99 /* Operator */ = {
114137
isa = PBXGroup;
115138
children = (
139+
726A21F424701C9D00DBAB87 /* Sections */,
116140
72704C832460EF94006F3E99 /* Infrastructure */,
117141
72704C7F2460EF4A006F3E99 /* Resources */,
118-
72704C6A2460EF10006F3E99 /* AppDelegate.swift */,
119-
72704C6C2460EF10006F3E99 /* SceneDelegate.swift */,
120-
72704C6E2460EF10006F3E99 /* ContentView.swift */,
121-
72704C702460EF13006F3E99 /* Assets.xcassets */,
122-
72704C752460EF13006F3E99 /* LaunchScreen.storyboard */,
123142
72704C722460EF13006F3E99 /* Preview Content */,
124143
);
125144
path = Operator;
@@ -139,6 +158,8 @@
139158
72704C802460EF59006F3E99 /* Test Sound Files */,
140159
72704C782460EF13006F3E99 /* Info.plist */,
141160
72704C7E2460EF41006F3E99 /* Operator.entitlements */,
161+
72704C702460EF13006F3E99 /* Assets.xcassets */,
162+
72704C752460EF13006F3E99 /* LaunchScreen.storyboard */,
142163
);
143164
path = Resources;
144165
sourceTree = "<group>";
@@ -154,6 +175,7 @@
154175
72704C832460EF94006F3E99 /* Infrastructure */ = {
155176
isa = PBXGroup;
156177
children = (
178+
726A21EF24701C2A00DBAB87 /* Logging */,
157179
72352437246D006200F58C61 /* Extensions */,
158180
72704C842460EF9E006F3E99 /* Audio */,
159181
);
@@ -193,7 +215,6 @@
193215
6761102642A44577E3E6499D /* Pods-Operator.debug.xcconfig */,
194216
32F8E8113014F8384AD3C0D6 /* Pods-Operator.release.xcconfig */,
195217
);
196-
name = Pods;
197218
path = Pods;
198219
sourceTree = "<group>";
199220
};
@@ -209,6 +230,8 @@
209230
72704C642460EF10006F3E99 /* Frameworks */,
210231
72704C652460EF10006F3E99 /* Resources */,
211232
411B10740FB47AEB4D78E934 /* [CP] Embed Pods Frameworks */,
233+
726A21F5247023F900DBAB87 /* Run SwiftFormat */,
234+
726A21F62470242300DBAB87 /* Run SwiftLint */,
212235
);
213236
buildRules = (
214237
);
@@ -338,6 +361,42 @@
338361
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
339362
showEnvVarsInLog = 0;
340363
};
364+
726A21F5247023F900DBAB87 /* Run SwiftFormat */ = {
365+
isa = PBXShellScriptBuildPhase;
366+
buildActionMask = 2147483647;
367+
files = (
368+
);
369+
inputFileListPaths = (
370+
);
371+
inputPaths = (
372+
);
373+
name = "Run SwiftFormat";
374+
outputFileListPaths = (
375+
);
376+
outputPaths = (
377+
);
378+
runOnlyForDeploymentPostprocessing = 0;
379+
shellPath = /bin/sh;
380+
shellScript = "git diff HEAD --name-only --diff-filter=ACMRTU -- \"Operator/*.swift\" | while read filename; do\n${SRCROOT}/Pods/SwiftFormat/CommandLineTool/swiftformat \"$filename\";\ndone\n";
381+
};
382+
726A21F62470242300DBAB87 /* Run SwiftLint */ = {
383+
isa = PBXShellScriptBuildPhase;
384+
buildActionMask = 2147483647;
385+
files = (
386+
);
387+
inputFileListPaths = (
388+
);
389+
inputPaths = (
390+
);
391+
name = "Run SwiftLint";
392+
outputFileListPaths = (
393+
);
394+
outputPaths = (
395+
);
396+
runOnlyForDeploymentPostprocessing = 0;
397+
shellPath = /bin/sh;
398+
shellScript = "git diff HEAD --name-only --diff-filter=ACMRTU -- \"Operator/*.swift\" | while read filename; do\n${PODS_ROOT}/SwiftLint/swiftlint lint --path \"$filename\";\ndone\n";
399+
};
341400
/* End PBXShellScriptBuildPhase section */
342401

343402
/* Begin PBXSourcesBuildPhase section */
@@ -347,6 +406,8 @@
347406
files = (
348407
72352439246D006D00F58C61 /* String+Extensions.swift in Sources */,
349408
72704C862460EFB7006F3E99 /* AudioFile.swift in Sources */,
409+
726A21F124701C4800DBAB87 /* Log.swift in Sources */,
410+
726A21F324701C5D00DBAB87 /* LogFormatter.swift in Sources */,
350411
72704C6B2460EF10006F3E99 /* AppDelegate.swift in Sources */,
351412
72704C6D2460EF10006F3E99 /* SceneDelegate.swift in Sources */,
352413
72704C6F2460EF10006F3E99 /* ContentView.swift in Sources */,

Operator/Infrastructure/Audio/AudioFile.swift

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ extension FourCharCode {
2121
var code: FourCharCode = 0
2222
// Value has to consist of 4 printable ASCII characters, e.g. '420v'.
2323
// Note: This implementation does not enforce printable range (32-126)
24-
if value.count == 4 && value.utf8.count == 4 {
24+
if value.count == 4, value.utf8.count == 4 {
2525
for byte in value.utf8 {
2626
code = code << 8 + FourCharCode(byte)
2727
}
28-
}
29-
else {
30-
print("FourCharCode: Can't initialize with '\(value)', only printable ASCII allowed. Setting to '????'.")
31-
code = 0x3F3F3F3F // = '????'
28+
} else {
29+
Log.warn("FourCharCode: Can't initialize with '\(value)', only printable ASCII allowed. Setting to '????'.")
30+
code = 0x3F3F_3F3F // = '????'
3231
}
3332
self = code
3433
}
@@ -46,14 +45,14 @@ final class AudioFile {
4645

4746
let status = AudioFileCountUserData(fileId, code, &itemCount)
4847

49-
guard status == noErr else {
48+
guard status == noErr else {
5049
return 0
5150
}
5251

5352
var size: UInt32 = 0
5453
AudioFileGetUserDataSize(fileId, code, 0, &size)
5554

56-
guard let data: UnsafeMutablePointer<UInt8> = get(userDataPointer: code, index: 0, inputSize: size) else {
55+
guard let data: UnsafeMutablePointer<UInt8> = get(userDataPointer: code, index: 0, inputSize: size) else {
5756
return 0
5857
}
5958
defer {
@@ -64,13 +63,13 @@ final class AudioFile {
6463
let string: String? = String(cString: data)
6564
// Determine if we've reached the OP-1 JSON, and if so advance 4 bytes and strip control characters.
6665
if let almostJSON = string, almostJSON.starts(with: "op-1") {
67-
let strippedString = almostJSON[4..<almostJSON.count].trimmingCharacters(in: .controlCharacters)
66+
let strippedString = almostJSON[4 ..< almostJSON.count].trimmingCharacters(in: .controlCharacters)
6867

6968
do {
7069
let parsed = try JSONSerialization.jsonObject(with: strippedString.data(using: .utf8)!)
71-
print("Parsed: \(parsed)")
72-
} catch(let error) {
73-
print("Error Parsing String - \(error)")
70+
Log.debug("Parsed: \(parsed)")
71+
} catch {
72+
Log.error("Error Parsing String - \(error)")
7473
}
7574
}
7675

@@ -90,15 +89,15 @@ final class AudioFile {
9089

9190
let status = AudioFileOpenURL(url as CFURL, .readPermission, kAudioFileAIFFType, &audioFile)
9291

93-
print("status: \(status)")
92+
Log.debug("status: \(status)")
9493

9594
if let file = audioFile {
9695
fileId = file
9796
} else {
9897
return nil
9998
}
10099

101-
print("Data count: \(self.userDataCount)")
100+
Log.debug("Data count: \(userDataCount)")
102101
}
103102

104103
func get<T>(userData code: FourCharCode, index: UInt32, inputSize: UInt32 = UInt32(MemoryLayout<T>.size)) -> T? {
@@ -115,7 +114,7 @@ final class AudioFile {
115114
&size,
116115
propertyData)
117116

118-
if status == noErr && size > 0 {
117+
if status == noErr, size > 0 {
119118
return propertyData[0]
120119
}
121120

@@ -132,7 +131,7 @@ final class AudioFile {
132131
&size,
133132
propertyData)
134133

135-
if status == noErr && size > 0 {
134+
if status == noErr, size > 0 {
136135
return propertyData
137136
}
138137

@@ -168,9 +167,9 @@ final class AudioFile {
168167
&size,
169168
propertyData)
170169

171-
print("Got status \(status) when looking for property \(property)")
170+
Log.debug("Got status \(status) when looking for property \(property)")
172171

173-
if status == noErr && size > 0 {
172+
if status == noErr, size > 0 {
174173
return propertyData.pointee
175174
}
176175

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//
2+
// Log.swift
3+
// Operator
4+
//
5+
// Created by Brian Michel on 5/16/20.
6+
// Copyright © 2020 Brian Michel. All rights reserved.
7+
//
8+
9+
import CocoaLumberjack
10+
import Foundation
11+
12+
private var logLevel: DDLogLevel = .all
13+
14+
final class Log {
15+
private static let logger: DDLog = {
16+
DDLog.add(DDOSLogger.sharedInstance) // ASL = Apple System Logs
17+
18+
let logFormatter = LogFormatter()
19+
DDOSLogger.sharedInstance.logFormatter = logFormatter
20+
21+
let fileLogger: DDFileLogger = DDFileLogger() // File Logger
22+
fileLogger.rollingFrequency = TimeInterval(60 * 60 * 24) // 24 hours
23+
fileLogger.logFileManager.maximumNumberOfLogFiles = 7
24+
DDLog.add(fileLogger)
25+
26+
return DDLog.sharedInstance
27+
}()
28+
29+
class func info(_ message: @autoclosure () -> String,
30+
_ path: StaticString = #file,
31+
_ function: StaticString = #function,
32+
line: UInt = #line) {
33+
_DDLogMessage(message(),
34+
level: logLevel,
35+
flag: .info,
36+
context: 0,
37+
file: path,
38+
function: function,
39+
line: line,
40+
tag: nil,
41+
asynchronous: true,
42+
ddlog: logger)
43+
}
44+
45+
class func debug(_ message: @autoclosure () -> String,
46+
_ path: StaticString = #file,
47+
_ function: StaticString = #function,
48+
line: UInt = #line) {
49+
_DDLogMessage(message(),
50+
level: logLevel,
51+
flag: .debug,
52+
context: 0,
53+
file: path,
54+
function: function,
55+
line: line,
56+
tag: nil,
57+
asynchronous: true,
58+
ddlog: logger)
59+
}
60+
61+
class func warn(_ message: @autoclosure () -> String,
62+
_ path: StaticString = #file,
63+
_ function: StaticString = #function,
64+
line: UInt = #line) {
65+
_DDLogMessage(message(),
66+
level: logLevel,
67+
flag: .warning,
68+
context: 0,
69+
file: path,
70+
function: function,
71+
line: line,
72+
tag: nil,
73+
asynchronous: true,
74+
ddlog: logger)
75+
}
76+
77+
class func error(_ message: @autoclosure () -> String,
78+
_ path: StaticString = #file,
79+
_ function: StaticString = #function,
80+
line: UInt = #line) {
81+
_DDLogMessage(message(),
82+
level: logLevel,
83+
flag: .error,
84+
context: 0,
85+
file: path,
86+
function: function,
87+
line: line,
88+
tag: nil,
89+
asynchronous: true,
90+
ddlog: logger)
91+
}
92+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// LogFormatter.swift
3+
// Operator
4+
//
5+
// Created by Brian Michel on 5/16/20.
6+
// Copyright © 2020 Brian Michel. All rights reserved.
7+
//
8+
9+
import CocoaLumberjack
10+
11+
final class LogFormatter: NSObject, DDLogFormatter {
12+
func format(message logMessage: DDLogMessage) -> String? {
13+
return "\(logLevelName(from: logMessage)) \(Int(logMessage.timestamp.timeIntervalSince1970)) - \(logMessage.message)"
14+
}
15+
16+
private func logLevelName(from message: DDLogMessage) -> String {
17+
switch message.flag {
18+
case .error:
19+
return "❗️"
20+
case .warning:
21+
return "⚠️"
22+
case .info:
23+
return "ℹ️"
24+
case .debug:
25+
return "🛠"
26+
default:
27+
return "🤷‍♀️"
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)