はじめに
ふとモールス信号の仕組みってどうなっているんだ?と思ったのでモールス信号を発光するアプリを作ってみた
途中からめんどくさくなってかなりソースコードが汚くなっていますがご了承ください
ソースコード
EnumEnumerable.swift
import Foundation
public protocol EnumEnumerable {
associatedtype Case = Self
static var dict: [String:String] {get}
}
public extension EnumEnumerable where Case: Hashable {
private static var iterator: AnyIterator<Case> {
var n = 0
return AnyIterator {
defer { n += 1 }
let next = withUnsafePointer(to: &n) {
UnsafeRawPointer($0).assumingMemoryBound(to: Case.self).pointee
}
return next.hashValue == n ? next : nil
}
}
public static func enumerate() -> EnumeratedSequence<AnySequence<Case>> {
return AnySequence(self.iterator).enumerated()
}
public static var cases: [Case] {
return Array(self.iterator)
}
public static var count: Int {
return self.cases.count
}
}
Morse.swift
protocol Morse {
static func patern(original: String) -> String
}
WesternMorse.swift
enum WesternMorse: String, Morse, EnumEnumerable {
case A = "・-"
case B = "-・・・"
case C = "-・-・"
case D = "-・・"
case E = "・"
case F = "・・-・"
case G = "--・"
case H = "・・・・"
case I = "・・"
case J = "・---"
case K = "-・-"
case L = "・-・・"
case M = "--"
case N = "-・"
case O = "---"
case P = "・--・"
case Q = "--・-"
case R = "・-・"
case S = "・・・"
case T = "-"
case U = "・・-"
case V = "・・・-"
case W = "・--"
case X = "-・・-"
case Y = "-・--"
case Z = "--・・"
//数字
case one = "・----"
case two = "・・---"
case three = "・・・--"
case four = "・・・・-"
case five = "・・・・・"
case six = "-・・・・"
case seven = "--・・・"
case eight = "---・・"
case nine = "----・"
case zero = "-----"
//記号
case question = "・・--・・"
case exclamation = "-・-・--"
case period = "・-・-・-"
case comma = "--・・--"
case hyphen = "-・・・・-"
case blank = "____"
case delimiter = "___"
public static var dict: [String:String] {
var value = [String: String]()
for var k in self.cases{
value["\(k)"] = "\(k.rawValue)"
}
return value
}
static func patern(original: String) -> String {
var returnValue = ""
for char in original.characters {
let charStr = transformation((String(char).uppercased()))
returnValue += self.dict["\(charStr)"]! + self.dict["delimiter"]!
}
return returnValue
}
private static func transformation(_ char: String) -> String {
let numArray = ["zero","one","two","three","four","five","six","seven","eight","nine"]
if char.isNumber() {
return numArray[Int(char)!]
}
switch char {
case "!":
return "exclamation"
case "?":
return "question"
case ",":
return "comma"
case ".":
return "period"
case "-":
return "hyphen"
case " "," ":
return "blank"
default:
return char
}
}
}
MorseSignalDevice.swift
protocol MorseSignalDevice {
func device() -> AVCaptureDevice
}
enum morseSignalDevice : MorseSignalDevice{
case torch
func device() -> AVCaptureDevice {
switch self {
case .torch:
let avDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
guard let device = avDevice else {
return AVCaptureDevice()
}
return device
}
}
}
MorseSignal.swift
import Foundation
import AVFoundation
protocol MorseSignal {
static func outSignal(signal: String, device: AVCaptureDevice)
}
public enum torchHandler: MorseSignal{
public static func outSignal(signal: String, device: AVCaptureDevice){
do {
try device.lockForConfiguration()
} catch {
return
}
let sleepTime: useconds_t = 100000
for char in signal.characters {
switch String(char) {
case "・":
device.torchMode = .on
usleep(sleepTime)
device.torchMode = .off
case "-":
device.torchMode = .on
usleep(sleepTime*3)
device.torchMode = .off
case "_":
device.torchMode = .off
usleep(sleepTime)
default:
usleep(0)
}
}
device.unlockForConfiguration()
}
}
ViewController.swift
使うときは以下のようにするとできます
@IBAction func pushMorseSignal(_ sender: Any) {
let signal = WesternMorse.patern(original: textField.text!)
let device = morseSignalDevice.torch.device()
if device.hasTorch {
torchHandler.outSignal(signal: signal, device: device)
}
}
String+.swift
import Foundation
extension String {
func isNumber() -> Bool {
let predicate = NSPredicate(format: "SELF MATCHES '\\\\d+'")
return predicate.evaluate(with: self)
}
}
作ってみて
和文モールスもcaseだけは書いたんですが力尽きました
ただひたすらcase文とモールス信号パターンを打つのがめんどくさかったです
参考
iPhoneのLEDライトをLピカさせよう!
Swift3.0版、Enumのcaseを配列で返すProtocol Extension