Macで再生中の最強のバンドの曲をTwitterに投稿する


はじめに

普段は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使ってない)
1. アーティスト名を取得(Apple script)
2. 楽曲のURLを取得(iThunesAPI)
3. 文字の整形
4. ツイートする(NSWorkspace)

ハマった点など書いていきます。

アーティスト名の取得(Apple script)

iTunesで聴いている曲をSlackに通知するアプリをswiftで書いた
再生中の楽曲を取るのはこちらがとてもしっかり書かれています。
(ここにたどり着いたということは参照した人も多いのでは)
しかし、現在の環境(swift5, Catalina)ではうまく動作しないようです。

AppleScriptでの楽曲情報の取得

逆に記事中では

この中を調べても、やっぱり Apple Music の情報は取れなさそうだ とわかります。

とありましたが、現在は取れるようです。やったね。

getMusicInfo.swift
    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向けのの文献は少なかった印象があります。

getMusicInfo.swift
import Cocoa
getMusicInfo.swift
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はエンコードしてあげましょう。

getMusicInfo.swift
        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の部分は割と雑に作りました。
ご指摘点あればぜひ。

文字の整形

getMusicInfo.swift
class EditText{

    class func editTextToSaikyo(band_name: String, url: String)-> String{

        return ("やっぱり最強のバンドは" + band_name + "なんだよなあ\n" + url)
    }

}

好きな雛形に変えても構いません。
bloodthirsty butchersはいいぞ。

ツイートする(NSWorkspace)

getMusicInfo.swift
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など

  1. URLの検索はなかなかにアホです。聞いているの曲ではない可能性があります。直したい。
  2. ハッシュタグをつけて最強のバンドランキングとかができれば...

最後に

やっぱり最強のバンドは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