Skip to content

Commit c82c5dd

Browse files
committed
add script class
1 parent c2e809d commit c82c5dd

File tree

4 files changed

+131
-39
lines changed

4 files changed

+131
-39
lines changed

json2Swift.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
95C6F59A1FB2A00F00667862 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 95C6F5981FB2A00F00667862 /* Main.storyboard */; };
1414
95C6F5A51FB2A05900667862 /* Parse.py in Resources */ = {isa = PBXBuildFile; fileRef = 95C6F5A31FB2A05900667862 /* Parse.py */; };
1515
95CFA2881FB2E361003561F2 /* Demo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CFA2871FB2E361003561F2 /* Demo.swift */; };
16+
95CFA28A1FB3ED3F003561F2 /* PyScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CFA2891FB3ED3F003561F2 /* PyScript.swift */; };
1617
/* End PBXBuildFile section */
1718

1819
/* Begin PBXFileReference section */
@@ -25,6 +26,7 @@
2526
95C6F59C1FB2A00F00667862 /* json2Swift.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = json2Swift.entitlements; sourceTree = "<group>"; };
2627
95C6F5A31FB2A05900667862 /* Parse.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = Parse.py; sourceTree = "<group>"; };
2728
95CFA2871FB2E361003561F2 /* Demo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Demo.swift; sourceTree = "<group>"; };
29+
95CFA2891FB3ED3F003561F2 /* PyScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PyScript.swift; sourceTree = "<group>"; };
2830
/* End PBXFileReference section */
2931

3032
/* Begin PBXFrameworksBuildPhase section */
@@ -60,6 +62,7 @@
6062
95C6F5A21FB2A01D00667862 /* script */,
6163
95C6F5921FB2A00F00667862 /* AppDelegate.swift */,
6264
95C6F5941FB2A00F00667862 /* ViewController.swift */,
65+
95CFA2891FB3ED3F003561F2 /* PyScript.swift */,
6366
95C6F5961FB2A00F00667862 /* Assets.xcassets */,
6467
95C6F5981FB2A00F00667862 /* Main.storyboard */,
6568
95C6F59B1FB2A00F00667862 /* Info.plist */,
@@ -152,6 +155,7 @@
152155
95C6F5951FB2A00F00667862 /* ViewController.swift in Sources */,
153156
95C6F5931FB2A00F00667862 /* AppDelegate.swift in Sources */,
154157
95CFA2881FB2E361003561F2 /* Demo.swift in Sources */,
158+
95CFA28A1FB3ED3F003561F2 /* PyScript.swift in Sources */,
155159
);
156160
runOnlyForDeploymentPostprocessing = 0;
157161
};

json2Swift/PyScript.swift

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//
2+
// PyScript.swift
3+
// json2Swift
4+
//
5+
// Created by Shi Jian on 2017/11/9.
6+
// Copyright © 2017年 HHMedic. All rights reserved.
7+
//
8+
9+
import Cocoa
10+
11+
public typealias completeBlock = ((_ results: [String], _ errors: String?)->Void)
12+
13+
public class PyScript {
14+
15+
let buildTask = Process()
16+
let outPip = Pipe()
17+
let errorPipe = Pipe()
18+
/// 完成回调
19+
var completed: completeBlock?
20+
21+
/// 是否异步执行回调,只在runAsync下生效
22+
var asyncComlete = false
23+
24+
/// 多个返回结果的分隔符
25+
public var splitPara: Character?
26+
27+
public init(scrPath: String, args: [String]? = nil, complete: completeBlock? = nil) {
28+
completed = complete
29+
30+
buildTask.launchPath = "/usr/bin/python"
31+
32+
var allArgs = [String]()
33+
allArgs.append(scrPath)
34+
if let aArg = args {
35+
allArgs.append(contentsOf: aArg)
36+
}
37+
buildTask.arguments = allArgs
38+
39+
buildTask.standardInput = Pipe()
40+
buildTask.standardOutput = outPip
41+
buildTask.standardError = errorPipe
42+
43+
// buildTask.terminationHandler = { p in
44+
// self.taskFinish()
45+
// }
46+
}
47+
48+
/// 同步执行
49+
public func runSync() {
50+
buildTask.launch()
51+
buildTask.waitUntilExit()
52+
53+
// 错误处理
54+
if let aError = fetchResult(errorPipe), aError != "" {
55+
runComlete(["-1"], aError)
56+
return
57+
}
58+
59+
// let result = fetchResult(outPip)?.split(separator: "\n").map(String.init) ?? [""]
60+
runComlete(processResult(), nil)
61+
}
62+
63+
/// 异步执行
64+
///
65+
/// - Parameter asyncComlete: 回调是否异步主线程执行
66+
public func runAsync(asyncComlete: Bool = true) {
67+
self.asyncComlete = asyncComlete
68+
DispatchQueue.global().async {
69+
self.runSync()
70+
}
71+
}
72+
73+
}
74+
75+
extension PyScript {
76+
77+
/// 执行block回调
78+
fileprivate func runComlete(_ result: [String], _ error: String?) {
79+
if asyncComlete {
80+
asyncComlete = false
81+
DispatchQueue.main.async {
82+
self.completed?(result, error)
83+
}
84+
} else {
85+
completed?(result, error)
86+
}
87+
}
88+
89+
// 获取返回数据的字符串形式
90+
fileprivate func fetchResult(_ pipe: Pipe) -> String? {
91+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
92+
return String(data: data, encoding: String.Encoding.utf8)
93+
}
94+
95+
fileprivate func processResult() -> [String] {
96+
let result = fetchResult(outPip) ?? ""
97+
guard let splt = splitPara else { return [result] }
98+
return result.split(separator: splt).map(String.init)
99+
}
100+
}
101+

json2Swift/ViewController.swift

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,55 +27,42 @@ class ViewController: NSViewController {
2727
}
2828

2929
@IBAction func doExcute(_ sender: NSButton) {
30+
runScript()
31+
}
32+
33+
func runScript() {
3034
guard let aPath = Bundle.main.path(forResource: "Parse", ofType: "py") else { return }
31-
var args = [aPath]
32-
// 参数
33-
args.append(inputView.string)
35+
36+
let script = PyScript(scrPath: aPath, args: fetchArgs()) { [weak self] in
37+
self?.scriptFinish(results: $0, error: $1)
38+
}
39+
40+
script.runAsync()
41+
}
3442

43+
// 执行完成的回调
44+
func scriptFinish(results: [String], error: String?) {
45+
if let aError = error {
46+
outputView.string = "解析错误\r\n" + aError
47+
return
48+
}
49+
50+
outputView.string = results[0]
51+
}
52+
53+
func fetchArgs() -> [String] {
54+
var args = [inputView.string]
3555
// mapper
3656
args.append(mapperCheck.state == .on ? "objectMapper" : "none")
37-
57+
3858
// name
3959
let name = nameText.stringValue == "" ? "Result" : nameText.stringValue
4060
args.append(name)
4161

4262
// prefix
4363
args.append(prefixText.stringValue)
4464

45-
runPython(args: args)
46-
}
47-
48-
func runPython(args: [String]?) {
49-
50-
let buildTask = Process()
51-
let outPip = Pipe()
52-
let errorPipe = Pipe()
53-
54-
buildTask.launchPath = "/usr/bin/python"
55-
buildTask.arguments = args
56-
buildTask.standardInput = Pipe()
57-
buildTask.standardOutput = outPip
58-
buildTask.standardError = errorPipe
59-
buildTask.terminationHandler = { p in
60-
self.taskFinish()
61-
}
62-
buildTask.launch()
63-
buildTask.waitUntilExit()
64-
65-
let data = outPip.fileHandleForReading.readDataToEndOfFile()
66-
let str = String(data: data, encoding: String.Encoding.utf8)
67-
outputView.string = str ?? "解析错误"
68-
69-
// 错误处理
70-
let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
71-
let errorStr = String(data: errorData, encoding: String.Encoding.utf8)
72-
if let aError = errorStr, aError != "" {
73-
outputView.string = "解析错误\r\n" + aError
74-
}
75-
}
76-
77-
func taskFinish() {
78-
print("执行完毕")
65+
return args
7966
}
8067

8168
@IBAction func runDemo(_ sender: NSButton) {
@@ -84,7 +71,7 @@ class ViewController: NSViewController {
8471
prefixText.stringValue = "SJ_"
8572

8673
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
87-
self.doExcute(sender)
74+
self.runScript()
8875
}
8976
}
9077

0 commit comments

Comments
 (0)