class Runtime {
public static let shared = Runtime()
var context: JSContext!
let preface = [
"Generated with quicktype",
"For more options, try https://app.quicktype.io"
]
private init() {
}
var isInitialized: Bool {
return nil != context
}
var _quicktypeJavaScript: String?
var quicktypeJavaScript: String? {
if nil == _quicktypeJavaScript {
guard let javascriptPath = Bundle.main.url(forResource: "quicktype", withExtension: "js") else { return nil }
guard let data = try? Data(contentsOf: javascriptPath) else { return nil }
_quicktypeJavaScript = String(data: data, encoding: .utf8)
}
return _quicktypeJavaScript
}
func initialize() -> Bool {
guard let context = JSContext() else { return false }
context.exceptionHandler = { context, exception in
print("JS Error: \(exception?.description ?? "unknown error")")
}
context.evaluateScript("""
var window = {};
var setTimeout = function(f) { f(); };
var clearTimeout = function() {};
var console = {};
""")
let consoleLog: @convention(block) (Any) -> Void = { print($0) }
context.objectForKeyedSubscript("console").setObject(consoleLog, forKeyedSubscript: "log" as NSString)
guard let javascript = quicktypeJavaScript else { return false }
context.evaluateScript(javascript)
self.context = context
return true
}
private func resolve(resolve: @escaping ([String]) -> Void) {
let resolveBlock: @convention(block) ([String]) -> Void = { resolve($0) }
context.setObject(resolveBlock, forKeyedSubscript: "resolve" as NSString)
}
private func reject(reject: @escaping (String) -> Void) {
let rejectBlock: @convention(block) (String) -> Void = { reject($0) }
context.setObject(rejectBlock, forKeyedSubscript: "reject" as NSString)
}
func renderOptionsToJavaScriptObject(_ options: [String: Any]) -> String {
return "{ " + options.map { key, value in
var javaScriptValue = "\(value)"
switch value {
case is String: javaScriptValue = "\"\(value)\""
default: break
}
return "\"\(key)\": \(javaScriptValue)"
}.joined(separator: ", ") + " }"
}
func quicktype(_ json: String, topLevel: String, language: Language, options: [String: Any], fail: @escaping (String) -> Void, success: @escaping ([String]) -> Void) {
// .header (C header files) are assumed to be Objective-C headers
if language == .objcHeader {
return quicktype(json, topLevel: topLevel, language:.objc, options: options, fail: fail, success: success)
}
resolve { lines in success(lines) }
reject { errorMessage in fail(errorMessage) }
let comments = preface.map { "\"\($0)\"" }.joined(separator: ",")
context.evaluateScript("""
function swifttype(json) {
window.quicktype.quicktype({
lang: "\(language.rawValue)",
sources: [{
kind: "json",
name: "\(topLevel)",
samples: [json]
}],
leadingComments: [\(comments)],
rendererOptions: \(renderOptionsToJavaScriptObject(options)),
}).then(function(result) {
resolve(result.lines);
}).catch(function(e) {
reject(e.toString());
});
}
""")
let swifttype = context.objectForKeyedSubscript("swifttype")!
swifttype.call(withArguments: [json])
}
}
quicktype代码
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 先父类后子类 从上面代码可得:父类静态代码块>main函数(处于父类)>子类静态代码块>main函数(处于子类)>...
- 如何在Swift的代码中使用OC的代码, 在OC的代码中使用Swift的代码? 一、OC的代码中使用Swift代码...
- 所有工具已升级,请使用CC系列工具,旧版已不现维护,目前已无法使用 进入 CC官网 前往 [ 官网下载] Cod...
- 所有工具已升级,请使用CC系列工具,旧版已不现维护,目前已无法使用 进入 CC官网 前往 [ 官网下载] Cod...
- 普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般的语句执行顺序由他们在代码中出现的次序决定-...