はじめに
普段はPMとか組み込みとかをやっていますが、あまりにもバンドへの衝動が抑えきれなかったので作りました。
swiftとかも初めてですが、あまりにもswift5で動かない文献が多く苦しかったので記事を書きました。
作ったもの
最強のバンドへの衝動を解き放ちます
使い方はここを参照しましょう
https://github.com/thrillingdream/saikyo-band
Macで再生中のアーティストの曲の情報を取得して、Twitter上にUploadします。
こんな感じ
やっぱり最強のバンドは+[artist名]+なんだよなあ+[iThunes URL]
動作確認環境
macOS Catalina 10.15.6
swift 5.2.4
処理の流れ&使ったもの
Swift Console appです。(UI使ってない)
- アーティスト名を取得(Apple script)
- 楽曲のURLを取得(iThunesAPI)
- 文字の整形
- ツイートする(NSWorkspace)
ハマった点など書いていきます。
##アーティスト名の取得(Apple script)
iTunesで聴いている曲をSlackに通知するアプリをswiftで書いた
再生中の楽曲を取るのはこちらがとてもしっかり書かれています。
(ここにたどり着いたということは参照した人も多いのでは)
しかし、現在の環境(swift5, Catalina)ではうまく動作しないようです。
AppleScriptでの楽曲情報の取得
逆に記事中では
この中を調べても、やっぱり Apple Music の情報は取れなさそうだ とわかります。
とありましたが、現在は取れるようです。やったね。
class func getMusicInfoName()-> (String){
let appleScript = "tell application \"Music\"\n"
+ "set trackName to name of current track\n"
+ "return trackName\n"
+ "end tell"
var error: NSDictionary?
let scriptObject = NSAppleScript(source: appleScript)
if let output: NSAppleEventDescriptor = scriptObject?.executeAndReturnError(&error){
return (output.stringValue ?? "まだないお")
}
return("[存在しないトラックを追い求めて行け]")
}
これで大丈夫。
記事の中で通知センターを使う方法が取られていたけど、これはダメっぽい。
引っかかった点は
"com.apple.iTunes.playerInfo" のオブザーバを登録することで Apple Music の音楽も曲情報が取得できます
これは今、"com.apple.Music.playerInfo"になっているっぽい。
ただし、自分でこのIdで発行したら情報が取れたのですが、AppleMusicからは通知が飛んでないようでした。
Gitでブランチ切ってるので検討したい方はぜひ。
私は断念しました。
##楽曲のURLを取得(iThunesAPI)
iOS用の物が多くMacOS向けのの文献は少なかった印象があります。
import Cocoa
let artist = getMusicInfoArtist()
let name = getMusicInfoName()
let searchWord = artist + " " + name
let urlString:String = "http://itunes.apple.com/search?term=\(searchWord)&country=JP&lang=ja_jp&media=music&entity=song&limit=30"
let encodeUrlString: String = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let url = URL(string: encodeUrlString)!
検索のロジックはこんなかんじ。
ithunesAPIのURLに検索のワードを入れてあげてください。
あと、URLはエンコードしてあげましょう。
var trackUrl = ""
let task = URLSession.shared.dataTask(with: url) {(data:Data?, response:URLResponse?, error:Error?) in
if let error = error {
trackUrl = "client error: \(error.localizedDescription)"
return
}
guard let data = data, let response = response as? HTTPURLResponse else {
trackUrl = "no data or no response"
return
}
if response.statusCode == 200 {
let items = try! JSONSerialization.jsonObject(with: data) as! Dictionary<String, Any>
let result = items["results"] as! NSArray //JSONから結果の部分を取り出す。JSONの中を見るとわかる。
let trackUrlNSArray = result.value(forKey: "trackViewUrl")as! NSArray //楽曲のURL情報
let trackUrlArray = trackUrlNSArray as NSArray as? [String] ?? [""]
//iTunesの検索ロジックで出た結果の一番最初の要素を取り出す(たまにミスる)
trackUrl = trackUrlArray.first ?? ""
} else {
trackUrl = "server error: \(response.statusCode)"
}
}
task.resume()
//Console appなのでsleepを入れないとThreadが処理を終わる前に抜けてしまう
sleep(1)
return(trackUrl)
}
JSONの部分は割と雑に作りました。
ご指摘点あればぜひ。
##文字の整形
class EditText{
class func editTextToSaikyo(band_name: String, url: String)-> String{
return ("やっぱり最強のバンドは" + band_name + "なんだよなあ\n" + url)
}
}
好きな雛形に変えても構いません。
bloodthirsty butchersはいいぞ。
##ツイートする(NSWorkspace)
import Cocoa
class TweetService{
class func start(text: String){
let encodedText = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
if let encodedText = encodedText,
let url = URL(string: "https://twitter.com/intent/tweet?text=\(encodedText)") {
if NSWorkspace.shared.open(url) {
print("最強のバンド")
}
}
}
}
Mac OSなのでNSWorkspace使ってます。
iOSだとUIAppricationっていうのを使うみたいですね。
制約及び今後のUpdateなど
- URLの検索はなかなかにアホです。聞いているの曲ではない可能性があります。直したい。
- ハッシュタグをつけて最強のバンドランキングとかができれば...
#最後に
やっぱり最強のバンドはeastern youthなんだよなあ
eastern youthの「心ノ底ニ灯火トモセ」
参考にしたサイト
ストリーミングされている曲情報の取り方
https://qiita.com/ayasuda/items/3773858e5e93ba94da48
Twitterへの連携のやつ
https://qiita.com/kumamotone/items/c1fe3dd5718d29cc94d0
swiftでAppleScriptを使うやつ
https://qiita.com/Eiryyy/items/4925e7d420519814176a
JSON系
https://qiita.com/satoshi-iwaki/items/708fac8f24ec26068455
URLの使い方
https://qiita.com/shiz/items/09523baf7d1cd37f6dee
iThunes APIの使い方
https://qiita.com/kenchan1837/items/a9e1de18c7eab75c4145