-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from andrea-prearo/data-writer
Create DataWriter as a base class for JSONWriter
- Loading branch information
Showing
9 changed files
with
276 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// | ||
// DataWriter.swift | ||
// Clue | ||
// | ||
// Created by Andrea Prearo on 4/29/17. | ||
// Copyright © 2017 Ahmed Sulaiman. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/// The `DataWriter` class encapsulates the details of writing data to a stream. | ||
public class DataWriter: NSObject { | ||
let outputStream: OutputStream | ||
var currentError: DataWriterError? | ||
|
||
/// The current error. | ||
public var error: DataWriterError? { | ||
if let currentError = currentError { | ||
return currentError | ||
} | ||
guard let streamError = outputStream.streamError else { | ||
return nil | ||
} | ||
return DataWriterError.error(streamError) | ||
} | ||
|
||
/// Initializes an output stream. | ||
/// | ||
/// - Parameter outputURL: The URL for the output stream. | ||
/// - Returns: An initialized output stream for writing to a specified URL. | ||
public init?(outputURL: URL) { | ||
guard let outputStream = OutputStream(url: outputURL, append: true) else { | ||
return nil | ||
} | ||
self.outputStream = outputStream | ||
super.init() | ||
self.outputStream.delegate = self | ||
} | ||
|
||
deinit { | ||
finishWriting() | ||
} | ||
|
||
/// Appends data to the stream. | ||
/// | ||
/// - Parameter data: The data to be written. | ||
/// - Returns: The number of bytes that were written. In case the return value | ||
/// is zero, the `error` property will contain the current error. | ||
@discardableResult | ||
public func append(data: Data) -> Int { | ||
if !isReadyForWriting() { | ||
startWriting() | ||
} | ||
let bytes = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) } | ||
guard bytes > 0 else { | ||
handleStreamError() | ||
return bytes | ||
} | ||
|
||
return bytes | ||
} | ||
} | ||
|
||
// MARK: - DataWriter + StreamDelegate | ||
extension DataWriter: StreamDelegate { | ||
public func stream(_ aStream: Stream, handle eventCode: Stream.Event) { | ||
switch eventCode { | ||
case Stream.Event.errorOccurred: | ||
handleStreamError() | ||
default: | ||
return | ||
} | ||
} | ||
} | ||
|
||
// MARK: - DataWriter + CLUWritable | ||
extension DataWriter: CLUWritable { | ||
public func isReadyForWriting() -> Bool { | ||
return outputStream.streamStatus == .open | ||
} | ||
|
||
public func startWriting() { | ||
if outputStream.streamStatus != .open { | ||
outputStream.open() | ||
} | ||
} | ||
|
||
public func finishWriting() { | ||
if outputStream.streamStatus != .closed { | ||
outputStream.close() | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Internal Methods | ||
extension DataWriter { | ||
func handleStreamError() { | ||
let error = outputStream.streamError ?? currentError | ||
print("Stream error: \(String(describing: error?.localizedDescription))") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// | ||
// DataWriterError.swift | ||
// Clue | ||
// | ||
// Created by Andrea Prearo on 4/25/17. | ||
// Copyright © 2017 Ahmed Sulaiman. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/// An error that can be returned from a `DataWriter` instance. | ||
/// | ||
/// - error: Internal error. | ||
/// - failure: Internal failure. | ||
/// - invalidData: Invalid data. | ||
/// - invalidJSON: Invalid JSON content. | ||
/// - unknown: Unknown error. | ||
public enum DataWriterError: Error { | ||
case error(Error) | ||
case failure(NSError) | ||
case invalidData(Data) | ||
case invalidJSON(Any) | ||
case unknown | ||
} | ||
|
||
extension DataWriterError: Equatable {} | ||
|
||
public func == (lhs: DataWriterError, rhs: DataWriterError) -> Bool { | ||
switch lhs { | ||
case .error(let error): | ||
switch rhs { | ||
case .error(let error2): | ||
return String(describing: error) == String(describing: error2) | ||
default: | ||
return false | ||
} | ||
case .failure(let error): | ||
switch rhs { | ||
case .failure(let error2): | ||
return error == error2 | ||
default: | ||
return false | ||
} | ||
case .invalidData(let data): | ||
switch rhs { | ||
case .invalidData(let data2): | ||
return data == data2 | ||
default: | ||
return false | ||
} | ||
case .invalidJSON(let json): | ||
switch rhs { | ||
case .invalidJSON(let json2): | ||
return String(describing: json) == String(describing: json2) | ||
default: | ||
return false | ||
} | ||
case .unknown: | ||
switch rhs { | ||
case .unknown: | ||
return true | ||
default: | ||
return false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.