質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

902閲覧

カスタムキーボードで取得したタッチ座標のCSVファイルを送信したい

yuki84

総合スコア23

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/06/21 08:36

開発環境 Xcode10.2.1 / Swift5/iOS

現在、カスタムキーボードを作成し、キーボード操作中のタッチ座標などを取得してCSVファイルとしてOneDriveに送信したいと考えています。

以前キーボード以外で行ったことを参考に(以前の質問)、カスタムキーボードのviewcontrollerにファイル送信キーを作り、UIDocumentInteractionControllerを利用して送ろうとしました。
しかし、送信先を選ぶ画面から送信先をタップするとポップアップが表示されず以下のエラーが出てしまいます。

”Feature not available in extensions of type com.apple.keyboard-service”

こちらを見るとiOSの仕様っぽいのですが、私がやろうと思っていることはやはり実現できないのでしょうか?

また、他にCSVファイルを送信する方法として何かいい解決策はないでしょうか?
ご教授お願いいたします。

OneDrive経由でなくとも、最終的に取得したデータをPCのエクセルで開くことができれば大丈夫です。

参考になるサイトやコードがあれば教えていただければ幸いです。

以下に現在のカスタムキーボードのコードを載せます。

swift

1import UIKit 2 3class KeyboardViewController: UIInputViewController { 4 5 @IBOutlet var nextKeyboardButton: UIButton! 6 7 let button1 = UIButton() 8 let button2 = UIButton() 9 var csvData=[[String]]() 10 var documentInteraction: UIDocumentInteractionController! 11 12 override func updateViewConstraints() { 13 super.updateViewConstraints() 14 15 // Add custom view sizing constraints here 16 } 17 18 // キーボードのサイズを変更するコード 19 override func viewWillAppear(_ animated: Bool) { 20 super.viewDidAppear(animated) 21 22 //constantで高さ変更 23 let heightConstraint = NSLayoutConstraint(item: view, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 500) 24 25 self.view.addConstraint(heightConstraint) 26 27 } 28 29 override func viewDidLoad() { 30 super.viewDidLoad() 31 32 // Perform custom UI setup here 33 self.nextKeyboardButton = UIButton(type: .system) 34 35 self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), for: []) 36 self.nextKeyboardButton.sizeToFit() 37 self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false 38 39 self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents) 40 41 self.view.addSubview(self.nextKeyboardButton) 42 43 self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true 44 self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true 45 46 csvData = ([["x座標","y座標","半径","面積"]]) 47 48 buttonHyozi1(x:100, y:100) 49 sousinButton(x:100, y:300) 50 51 } 52 53 override func viewWillLayoutSubviews() { 54 self.nextKeyboardButton.isHidden = !self.needsInputModeSwitchKey 55 super.viewWillLayoutSubviews() 56 } 57 58 override func textWillChange(_ textInput: UITextInput?) { 59 // The app is about to change the document's contents. Perform any preparation here. 60 } 61 62 override func textDidChange(_ textInput: UITextInput?) { 63 // The app has just changed the document's contents, the document context has been updated. 64 65 var textColor: UIColor 66 let proxy = self.textDocumentProxy 67 if proxy.keyboardAppearance == UIKeyboardAppearance.dark { 68 textColor = UIColor.white 69 } else { 70 textColor = UIColor.black 71 } 72 self.nextKeyboardButton.setTitleColor(textColor, for: []) 73 } 74 75 //ボタンを表示する関数 76 func buttonHyozi1(x:Int, y:Int){ 77 78 // ボタンの設置座標とサイズを設定する. 79 button1.frame = CGRect(x: x, y: y, width: 200, height: 100) 80 81 // buttonのbackgroundcolorを指定 82 button1.backgroundColor = UIColor.cyan 83 84 button1.setTitle("ボタン", for: .normal) 85 86 // buttonにイベントを追加 87 button1.addTarget(self, action: #selector(KeyboardViewController.onMyButton(_:forEvent:)), for: .touchDown) 88 89 // 実際にviewに表示する 90 view.addSubview(button1) 91 92 } 93 94 // button1のメソッド 95 @objc func onMyButton(_ sender: UIButton, forEvent event: UIEvent) { 96 button1.backgroundColor = UIColor.black 97 98 // タップ時刻を測定 99 let formatter = DateFormatter() 100 formatter.timeZone = TimeZone.ReferenceType.local 101 formatter.dateFormat = "HH:mm:ss.SSS" // *時*分**.***秒 102 print(formatter) 103 104 let locationX = event.touches(for: sender)!.first!.location(in: view).x 105 let locationY = event.touches(for: sender)!.first!.location(in: view).y 106 107 //タッチ半径を測定 108 let touches = event.touches(for: sender) 109 let radius = touches!.first!.majorRadius 110 //面積を計算 111 let area = round(radius*radius*3.14*100)/100 112 113 print(Float(locationX),Float(locationY),Float(radius),Float(area)) 114 csvData.append([String(Float(locationX)),String(Float(locationY)),String(Float(radius)),String(Float(area))]) 115 116 } 117 118 119 func toCSV(input: [[String]]) -> String { 120 return input.map { 121 $0.map { 122 $0.contains(",") || $0.contains("\"") 123 ? "\"" + $0.replacingOccurrences(of: "\"", with: "\"\"") + "\"" 124 : $0 125 }.joined(separator: ",") 126 }.joined(separator: "\r\n") 127 } 128 129 130 func sousinButton(x:Int, y:Int){ 131 132 // ボタンの設置座標とサイズを設定する. 133 button2.frame = CGRect(x: x, y: y, width: 200, height: 100) 134 135 // buttonのbackgroundcolorを指定 136 button2.backgroundColor = UIColor.cyan 137 138 button2.setTitle("送信", for: .normal) 139 140 // buttonにイベントを追加 141 button2.addTarget(self, action: #selector(KeyboardViewController.onMyButton2(_:forEvent:)), for: .touchDown) 142 143 // 実際にviewに表示する 144 view.addSubview(button2) 145 146 } 147 148 @objc func onMyButton2(_ sender: UIButton, forEvent event: UIEvent) { 149 150 button2.backgroundColor = UIColor.black 151 152 let fileName = "keyboardTapData.csv" 153 154 let a = toCSV(input: csvData) 155 156 // DocumentディレクトリのfileURLを取得 157 let documentDirectoryFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! 158 159 // ディレクトリのパスにファイル名をつなげてファイルのフルパスを作る 160 let FilePath = documentDirectoryFileURL.appendingPathComponent(fileName) 161 162 print("書き込むファイルのパス: (FilePath)") 163 164 165 do { 166 try a.write(to: FilePath, atomically: true, encoding: String.Encoding.shiftJIS) 167 168 } catch let error as NSError { 169 print("failed to write: (error)") 170 } 171 172 documentInteraction = UIDocumentInteractionController() 173 documentInteraction.url = FilePath 174 175 176 if !(documentInteraction?.presentOpenInMenu(from: self.view.frame, in: self.view, animated: true))! 177 { 178 // 送信できるアプリが見つからなかった時の処理 179 let alert = UIAlertController(title: "送信失敗", message: "ファイルを送れるアプリが見つかりません", preferredStyle: .alert) 180 alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 181 self.present(alert, animated: true, completion: nil) 182 } 183 184 185 } 186 187 188}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/06/21 08:56 編集

カスタムキーボード云々は質問に関係ないですかね? 質問は「CSVファイルをPCに送信したい」でいいでしょうか?
fuzzball

2019/06/21 09:07

キーボード閉じればいけそうな気がしますが‥。
yuki84

2019/06/21 09:27

PCに送信することが目的ですが、キーボードからやっているために実現できていないという状況です。 送信ボタンを押すとキーボードを閉じることも試したのですが、一緒に送信画面も閉じてしまいます。
yuki84

2019/06/21 09:35

送信ボタンもキーボード上に表示させています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問