Protocol-Oriented Programming in Swift
import Foundation
// ErrorType
public enum OSAScriptError: ErrorType {
case InitializingFromSource(source: String?)
case InitializingFromContents(error: NSDictionary)
case Executing(error: NSDictionary)
case Unknown
}
// Protocol
public protocol OSAScriptProperty {
var script : NSAppleScript { get set }
}
public protocol OSAScriptInitialize: OSAScriptProperty {
init()
init(contentsOfPath: String) throws
}
public protocol OSAScriptFunction: OSAScriptProperty {
func run() throws -> NSAppleEventDescriptor
}
public protocol OSAScriptProtocol: OSAScriptInitialize, OSAScriptFunction {}
// Protocol Extension
extension OSAScriptInitialize {
init(contentsOfPath path: String) throws {
self.init()
let url = NSURL(fileURLWithPath: path)
var err : NSDictionary?
guard let script = NSAppleScript(contentsOfURL: url, error: &err) else {
if let err = err {
throw OSAScriptError.InitializingFromContents(error: err)
} else {
throw OSAScriptError.Unknown
}
}
self.script = script
}
}
extension OSAScriptFunction {
func run() throws -> NSAppleEventDescriptor {
var err : NSDictionary?
let result = self.script.executeAndReturnError(&err)
if let err = err {
throw OSAScriptError.Executing(error: err)
}
return result
}
}
// ValueType
struct JavaScript: OSAScriptProtocol {
var script = NSAppleScript()
}
struct AppleScript: OSAScriptProtocol {
var script = NSAppleScript()
}
extension AppleScript {
init(source: String) throws {
guard let script = NSAppleScript(source: source) else {
throw OSAScriptError.InitializingFromSource(source: source)
}
self.script = script
}
}
// Main
_ = try? JavaScript(contentsOfPath: "/path/to/script/javascript.scptd").run()
_ = try? AppleScript(source: "say \"hello again\"").run()