[cocoa][swift][Kotlin]Tweeting

<p>システム側でのSNS共有のサポートが終了したり、公式のTwitter Kit SDKのサポートが停止するなどで、スマートフォン・アプリケーションにTweet機能を組み込む方法が変わってきているので、今時点のTweet機能を組み込む方法を調べてみた。</p>

<ul>
<li>ios
	<ul>
	<li>Social.framework<br />iOS11から廃止。</li>
	<li>Twitter Kit SDK<br />2018年10月末でサポート終了。</li>
	</ul>
</li>
<li>Android
	<ul>
	<li>Twitter Kit SDK<br />2018年10月末でサポート終了。</li>
	</ul>
</li>
</ul>

<p>方向としては、ネイティブ・コード向けライブラリの提供はやめて、Web技術を利用して欲しいということのようだ。</p>

iOS
<p>Universal Linksを利用した方法。Twitterアプリケーションがインストールされていない場合はWebブラウザで、インストールされている場合は、Twitterアプリケーションでの投稿となる。</p>

<ul>
<li><a href="https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview">Web Intent</a></li>
</ul>

<pre><code>@IBAction func intentTweet(_ sender : Any) {
    let text = "Web Intentの例"
    let encodedText = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
    if let encodedText = encodedText,
        let url = URL(string: "https://twitter.com/intent/tweet?text=\(encodedText)") {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
}
</code></pre>

<p>具体的な仕様は以下で説明されている。</p>

<ul>
<li><a href="https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent">https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent</a>
</ul>

<p>このURLに文言をパラメータとして設定してオープンするという仕組みだ。</p>

<p>Twitterアプリケーションがインストールされていない</p>
<img width="122" alt="Web Intent - Twitterアプリなし.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/b403ae13-e9b0-a46b-272e-f799ce74d41b.png">

<p>Twitterアプリケーションがインストールされている</p>
![Web Intent - Twitterアプリあり.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/1cdc7d9a-e854-8159-1e28-7925d4a2d482.png)

<p>iOSの共有機能を提供するUIActivityViewControllerを利用する方法。Twitterアプリがインストールされていないと候補に現れないだとか、SNS共有っぽくはない。でも、テキストに加え、画像も直に共有できる。</p>

<pre><code>@IBAction func activityTweet(_ sender : Any) {
    let text = "共有機能を利用する"
    let bundlePath = Bundle.main.path(forResource: "brownout", ofType: "jpg")
    let image = UIImage(contentsOfFile: bundlePath!)
    let shareItems = [image, text] as [Any]
    let controller = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
    present(controller, animated: true, completion: nil)
}
</code></pre>

<p>共有先を選ぶ</p>
![共有機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/b7f9466c-645c-9dce-b7f6-26f71005bdcf.png)

<p>Twitterを選ぶと、Twitterアプリの投稿画面。画像も扱える。</p>
![共有機能 Twitter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/591af5d1-787f-bcf9-2464-0bbcf32c5edb.png)

Android
<p>ボタンと配置する。最近のAndroid Studioは向上している。Xcode並みに開発しやすくなっている。</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"&gt;

    &lt;Button
        android:id="@+id/intentTweetButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:text="intent tweet"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" /&gt;

    &lt;Button
        android:id="@+id/shareCompatButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:text="ShareCompat"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/intentTweetButton" /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
</code></pre>

<p>インテントを利用する方法。TwitterアプリがインストールされていないとWebブラウザで、インストールされているとTwitterアプリが利用される。</p>

<pre><code>override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
 
    val intentTweetButton: Button = findViewById(R.id.intentTweetButton)
    intentTweetButton.setOnClickListener {
        shareTwitter()
    }
}
 
fun shareTwitter() {
    val message = "shareTwitter intent tweet"
    try {
        val sharingIntent = Intent(Intent.ACTION_SEND)
        sharingIntent.setClassName("com.twitter.android", "com.twitter.android.PostActivity")
        sharingIntent.putExtra(Intent.EXTRA_TEXT, message)
        startActivity(sharingIntent)
    }
    catch (e: Exception) {
        Log.e("In Exception", "Comes here")
        val i = Intent()
        i.putExtra(Intent.EXTRA_TEXT, message)
        i.action = Intent.ACTION_VIEW
        i.data = Uri.parse("https://mobile.twitter.com/compose/tweet")
        startActivity(i)
    }
}
</code></pre>

<p>OSのWeb Intentと同様な仕組みだ。</p>

<img width="109" alt="intent tweet.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/e18e6cd5-b745-8e57-d85f-9a55189c45f2.png">

<p>共有機能を利用する方法。TwitterアプリがインストールされていないとTweetできない。</p>

<pre><code>override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
 
    val shareCompatButton: Button = findViewById(R.id.shareCompatButton)
    shareCompatButton.setOnClickListener {
        shareCompat()
    }
}
 
fun shareCompat() {
    val message = "shareCompat"
    val builder = ShareCompat.IntentBuilder.from(this)
    builder.setChooserTitle("Choose App")
    builder.setText(message)
    builder.setType("text/plain")
    builder.startChooser()
}
</code></pre>

<p>共有先を選ぶ</p>
<img width="109" alt="ShareCompat.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/1d230afc-c4ff-d938-4c6f-28913c7c9785.png">

<p>Twitterを選ぶと、Twitterアプリの投稿画面。画像も扱えるはずだが、自分はうまくいかなかった。</p>
<img width="109" alt="ShareCompat tweet.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12540/a08a0c05-1624-1ce2-ab34-aa36ba90e6c3.png">

ソースコード
GitHubからどうぞ。<br />
<a href="https://github.com/murakami/workbook/tree/master/ios/Tweets">https://github.com/murakami/workbook/tree/master/ios/Tweets</a> - GitHub<br />
<a href="https://github.com/murakami/workbook/tree/master/android/Tweets">https://github.com/murakami/workbook/tree/master/android/Tweets</a> - GitHub<br />

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/145138/">Cocoa.swift 2019-09</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />