| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

差分

ナビゲーションに移動 検索に移動
7,889 バイト追加 、 2022年3月19日 (土) 01:48
==[[Swift]] Sample==
===Network===----====データ取得====
----
<pre>
task.resume()
</pre>
=====[[MacOS]]でエラーの場合=====
<code>Error Domain=NSURLErrorDomain Code=-1003</code>
*https://www.poly-rhythm.com/hostname-could-not-be-found/
[[File:swift_macos_net_error.png|600px]]
==File=UI====JSONにシリアライズしてドキュメントディレクトリへ書き出し===*データ(Codableを適用する)<pre>struct Host : Codable { var host: String = "" var ip: String = "" var macaddr: String = ""}</pre>*読み込み、コレクションに追加、書き出し処理<pre> func addHostListDocument(host: WoL.Host) { let docPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let filePath = URL(fileURLWithPath: "hosts.json", relativeTo:docPath) var hostList: [WoL.Host] = [] let decoder = JSONDecoder() do { let rawData = try Data(contentsOf: filePath) print(rawData) let tmpHostList = try decoder.decode([WoL.Host].self, from: rawData) for tmpHost in tmpHostList { hostList.append(tmpHost) } } catch { print(error) } hostList.append(host) let encoder = JSONEncoder() do { let line = try encoder.encode(hostList) try line.write(to: filePath) } catch { print(error) } }</pre>[[File:swift_json_encode.png|300px]]=====書式を指定=====<pre> let encoder = JSONEncoder() encoder.outputFormatting = [.prettyPrinted, .sortedKeys]</pre>=====Stringに変換=====<pre> let json = try encoder.encode(hosts.hosts) let jsonString = String(data: json, encoding: .utf8)! print(jsonString)</pre>=====画面とオブジェクトを共有する=====*struct -> class*ObservableObject を適用*@Published *上記を適用すると、Codable に適合させるには、明示的に処理を記述する必要がある<pre>class Host : Codable, ObservableObject { @Published var host: String = "" @Published var ip: String = "" @Published var macaddr: String = "" @Published var comment: String = ""  init(host: String, ip: String, macaddr: String, comment: String) { self.host = host self.ip = ip self.macaddr = macaddr self.comment = comment } init() {}  /// 変換対象プロパティ enum CodingKeys: CodingKey { case host case ip case macaddr case comment }  required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) host = try container.decode(String.self, forKey: .host) ip = try container.decode(String.self, forKey: .ip) macaddr = try container.decode(String.self, forKey: .macaddr) comment = try container.decode(String.self, forKey: .comment) }  func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(host, forKey: .host) try container.encode(ip, forKey: .ip) try container.encode(macaddr, forKey: .macaddr) try container.encode(comment, forKey: .comment) }</pre> ===ディレクトリ判定===
----
<pre>private static let fm =FileManager.defaultstatic func isDirectory(path: String) -> Bool { var isDir = ObjCBool(false) fm.fileExists(atPath: path, isDirectory: &isDir) return isDir.boolValue}</pre> ==UI=====バックグラウンドからUIを操作する====
----
*observableobj が、ObservableObject の派生クラス
DispatchQueue.main.sync {
observableobj.content = text
}
</pre>
===ディレクトリを選択===
----
<pre>
static func chooseDir() -> String {
let dialog = NSOpenPanel();
 
dialog.title = "Choose a root directory"
dialog.showsResizeIndicator = true
dialog.showsHiddenFiles = false
dialog.allowsMultipleSelection = false
dialog.canChooseDirectories = true
dialog.canChooseFiles = false
 
if (dialog.runModal() == NSApplication.ModalResponse.OK) {
let result = dialog.url
 
if (result != nil) {
let path: String = result!.path
return path
}
}
return "";
}
</pre>
 
==処理==
===サブプロセスを起動===
----
*プロセスを起動し、arp -a を呼び出し、出力
<pre>
func arp() {
let outputPipe = Pipe()
 
func shell(path:String ,args: String...) -> Int32 {
let task = Process()
task.launchPath = path
task.arguments = args
task.standardOutput = outputPipe
task.standardError = outputPipe
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
let _ = shell(path:"/usr/sbin/arp",args: "-a")
let theTaskData = outputPipe.fileHandleForReading.readDataToEndOfFile()
let stringResult = String(data: theTaskData, encoding: .utf8)
print(stringResult!)
}
</pre>
 
===非同期処理===
----
<pre>
let c = {
(ip:String) -> String in
let hostName = getHostName(ip: ip) // 時間がかかる処理
return hostName
}
 
let que = DispatchQueue.global(qos: .default)
for host in hosts.hosts {
print("CALL-\(host.ip)")
que.async { // 非同期処理
let hostname = c(host.ip) // 時間がかかる処理
DispatchQueue.main.async { // 画面に反映
host.host = hostname
}
}
}
</pre>
 
==[[正規表現]]==
===arp -a の結果からIPアドレスを抜きだす===
----
<pre>
func parseArp(arpResult: String?) {
if let input = arpResult {
do {
let pattern = #"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"#
let regex = try NSRegularExpression(pattern: pattern, options:[])
for subinput in input.split(separator: "\r\n") {
let line = String(subinput)
let maches = regex.matches(in: line, options: [], range: _NSRange(0..<line.count))
print(line)
for mach in maches {
for i in 0 ..< mach.numberOfRanges {
let start = line.index(line.startIndex, offsetBy: mach.range(at: i).location)
let end = line.index(start, offsetBy: mach.range(at: i).length)
let text = String(line[start..<end])
print(text)
}
}
}
} catch {
print("RegEx fail.")
}
} else {
print("arp -a result : error")
}
</pre>
===digを経由してBonjourでIPアドレスをホスト名に解決===
*コマンドをswiftで呼び出し dig +short -x 192.168.0.45 @224.0.0.251 -p 5353
<pre>
let outputPipe = Pipe()
let _ = shell(outputPipe,
path:"/usr/bin/dig",
args: "+short",
"-x", ip,
"@224.0.0.251", "-p","5353") // Bonjour IPアドレス
let theTaskData = outputPipe.fileHandleForReading.readDataToEndOfFile()
let stringResult = String(data: theTaskData, encoding: .utf8)
</pre>
 
===名前を付与してキャプチャ===
----
<pre>
func parseArp(arpResult: String?) {
if let input = arpResult {
do {
let pattern = #".*?(?<ip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*(?<mac>[0-9a-z]{1,2}:[0-9a-z]{1,2}:[0-9a-z]{1,2}:[0-9a-z]{1,2}:[0-9a-z]{1,2}:[0-9a-z]{1,2})"#
let regex = try NSRegularExpression(pattern: pattern, options:[])
for subinput in input.split(separator: "\r\n") {
let line = String(subinput)
let matches = regex.matches(in: line, options: [], range: _NSRange(0..<line.count))
print(line)
for match in matches {
for name in ["ip", "mac"] {
let matchRange = match.range(withName: name)
if let substrRanget = Range(matchRange, in:line) {
let ip = String(line[substrRanget])
print("\(name):\(ip)")
}
}
}
}
} catch {
print("RegEx fail.")
}
} else {
print("arp -a result : error")
}
}
</pre>

案内メニュー