- 投稿日:2019-10-26T21:06:12+09:00
[Swift] FirebaseStorageをフォルダの中身を全て削除する
FirebaseStorageはフォルダごと削除ができない
FirebaseStoregeはフォルダをまるごと削除ができない仕様らしいです。。。
なのでユーザーの削除などで複数あるプロフィール画像や投稿画像を削除する場合はループでフォルダにあるファイルを削除しなければいけないみたい、、、
この仕様制限だけでFirebaseStorageから離れる開発の人も多いんじゃ、、、(わからん)
いろいろ調べて見たけどやり方として2通りあるっぽい。
- FirebaseのCloudfunctionsを使う
- Swiftでループを回して、1つ1つファイルを削除する
僕はjsが得意でないので、Cloudfunctionsは諦めて
後者のループを回す方法選びました。参考記事がなく、自分でfirebaseStorageにいいメソッドないかな〜ってみたところ、、、ありました!!
SwiftでループをまわしFirebaseStorageをフォルダの中身を全て削除する方法
listAllを使い、フォルダにあるファイルを全てとってきて、それをループして削除します。
let storage = Storage.storage() let storageRef = storage.reference() storageRef .child("users") .child(self.uid) .listAll(completion: { (StorageListResult, error) in if let error = error { print("エラー\(error)") } else { for ref in StorageListResult.items { ref.delete { (error) in if let error = error { print("エラー\(error)") } else { print("storage削除成功!") } } } })もっといい方法あるって方はコメントください!!
フォルダ毎削除できるようにしてほしい?
- 投稿日:2019-10-26T19:50:07+09:00
ズンドコキヨシ with Combine
TL; DR
- 3年前に流行ったツイートとRxSwiftを使った記事を思い出したのでCombineで再現してみました
ズンドコキヨシをCombineで再現してしまった...
— mshrwtnb (@mshrwtnb_) October 25, 2019
- 元ネタはこちら
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも (@kumiromilk) March 9, 2016
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた0. ゴールの確認
- 「ずん」「どこ」「き・よ・し!」の出力はすべてreceiveValueで受け取る
Stringとする(= assignしようと思えばできる状態を目指す)。記事ではinput:○○○の○○○で表現する。- Publisherの
print(_:to:)はデバグ用に使う(回答としてカウントしない)- 一度「き・よ・し!」を出力したら処理を終了する
1. ずんどこ川の水源を作る
まずは「ずん」または「どこ」が湧き出る水源を作っていく。
勢いよく湧き出て欲しいので、0.1秒間隔で出力していこう。iOS 13から追加された
Timer.publish(every:tolerance:on:in:options:)を使っていく。let ずんどこ水源 = Timer.publish(every: 0.1, on: .main, in: .default) .autoconnect() .map { _ in Int.random(in:0..<2) == 0 ? "ずん" : "どこ" } .share() self.cancellable = ずんどこ水源 .sink(receiveCompletion: { _ in print("===完===") }, receiveValue: { print("input: \($0)") })良い。すごく良い。勢いある湧出量だ。
2. センサー付きの水門づくり
上述のとおり、ずんどこ水源からは「ずん」または「どこ」が1語ずつ流れてくる。
検知したいのは「ずん、ずん、ずん、ずん、どこ」の5要素なので、FIFO方式でずんどこが5つだけたまる溜池を作る。
そして、溜まった要素がお目当てのパターンか判定するセンサーを作る。
もしパターンを検知できたら水門を閉じる。
いたずらにずんどこを溜めない。let センサー付き水門 = ずんどこ水源 .scan([], { (reservoir: [String], element: String) -> [String] in // 溜池 var newReservoir = Array(reservoir + [element]) if newReservoir.count > 5 { newReservoir.removeFirst() } return newReservoir.prefix(5).map { $0 } }) .allSatisfy { $0 != ["ずん", "ずん", "ずん", "ずん", "どこ"] } .map { _ in } .share()3. 検知後「き・よ・し!」を知らせる
()が流れてくる仕組みを活用し、「き・よ・し!」と流れるスピーカーを作ろう。let スピーカー = センサー付き水門.map { _ in "き・よ・し!" }これでも悪くはない。
しかし、贅沢を言えば「どこ」と「き・よ・し!」の間には"ため"が欲しい。
そこで1秒くらい"ため"を作ろう。
結果には影響を与えない形で"ため"を確認できるようprintしておこう。let スピーカー = センサー付き水門.map { _ in "き・よ・し!" } .handleEvents(receiveOutput: { _ in print("(せーの...!)") }) .delay(for: .seconds(1.0), scheduler: RunLoop.main)4. 整備されたずんどこ川の全貌
野川状態だった、ずんどこ川にも必要な設備が揃った。
あとはこれらをうまく組み合わせていく。
これで、河川管理もバッチリだ。let ずんどこ水源 = Timer.publish(every: 0.1, on: .main, in: .default) .autoconnect() .map { _ in Int.random(in:0..<2) == 0 ? "ずん" : "どこ" } .share() let センサー付き水門 = ずんどこ水源 .scan([], { (reservoir: [String], element: String) -> [String] in // 溜池 var newReservoir = Array(reservoir + [element]) if newReservoir.count > 5 { newReservoir.removeFirst() } return newReservoir.prefix(5).map { $0 } }) .allSatisfy { $0 != ["ずん", "ずん", "ずん", "ずん", "どこ"] } .map { _ in } .share() let スピーカー = センサー付き水門.map { _ in "き・よ・し!" } .handleEvents(receiveOutput: { _ in print("(せーの...!)") }) .delay(for: .seconds(1.0), scheduler: RunLoop.main) self.cancellable = ずんどこ水源 .prefix(untilOutputFrom: センサー付き水門) // センサーが検知するまで、ずんどこを流す .merge(with: スピーカー) // 検知したら、き・よ・し!を流す .sink(receiveCompletion: { _ in print("===完===") }, receiveValue: { print("input: \($0)") })よし、最後にこれを動かしてみよう。
...
....
.....???????????????
あとがき
ふざけているようですが、トライしてみるとオペレーターの挙動に詳しくなります
もっと良い実装例があったら@mshrwtnbまで教えていただけると勉強になります
https://github.com/mshrwtnb/zundoko-combine にソースを置きました。以上
- 投稿日:2019-10-26T17:17:28+09:00
【コードでAutoLayout】関連付けた2つのUIViewのtranslatesAutoresizingMaskIntoConstraintsがtrueとfalseの組み合わせの場合の挙動
AutoLayoutを始めたのが最近なので3周遅れぐらいでいろいろ調べている。暖かく見守っていただきたい。
2つのViewに関連をつけるときにtranslatesAutoresizingMaskIntoConstraintsの設定が片方だけtrueのときの挙動はどうなるか。前提
ソースで書く。Storyboardは使わない。
UIViewとUIViewの組み合わせ
viewA : AutoLayoutがオフ
viewB : AutoLayoutがオン
とする。viewAが何かの方法でframeが確定したとき、関連付けられているviewBは意図する設定がされるのか?結論
viewAもAnchorの値は有効。
viewAのAnchorが決定するので、関連付けられたviewBのAnchorを決定することができる。コード
//testView1.translatesAutoresizingMaskIntoConstraints = false testView1.frame = CGRect(x: 30.0, y: 50.0, width: 50.0, height: 50.0) testView2.translatesAutoresizingMaskIntoConstraints = false testView2.topAnchor.constraint(equalTo: testView1.topAnchor).isActive = true testView2.leadingAnchor.constraint(equalTo: testView1.trailingAnchor, constant: 30.0).isActive = true testView2.heightAnchor.constraint(equalTo: testView1.heightAnchor).isActive = true testView2.widthAnchor.constraint(equalTo: testView1.widthAnchor).isActive = trueUIScrollViewとUIViewの組み合わせ
今回のメインイベントである。UIScrollViewとその中に入れたUIViewはどうなるか?
UIScrollViewがAutoLayoutオフ、UIViewがオンのとき
結論
意図したとおりになる。まあ、意図というのは私自身にしかわからない表現かもしれない。
UIScrollViewのcontentSizeは、中にあるUIViewのサイズに関連してAutoLayoutで指令可能ということである。UIScrollView自身はAutoLayoutオフなのであるが。コード
//scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.frame = CGRect(x: 30.0, y: 200.0, width: 200.0, height: 200.0) testView3.translatesAutoresizingMaskIntoConstraints = false testView3.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 10.0).isActive = true testView3.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 10.0).isActive = true testView3.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -10.0).isActive = true testView3.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -10.0).isActive = true testView3.heightAnchor.constraint(equalToConstant: 400.0).isActive = true testView3.widthAnchor.constraint(equalToConstant: 400.0).isActive = trueUIScrollViewがAutoLayoutオン、UIViewがオフのとき
結論
UIScrollViewの外枠はAutoLayoutで指令できるが、contentSizeはAutoLayoutを使えなかった。中のUIViewのサイズが決定すればAutoLayoutでcontentSizeが設定可能かなと思ったのだが。古典的に指定することになる。
コード
scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200.0).isActive = true scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30.0).isActive = true scrollView.heightAnchor.constraint(equalToConstant: 200.0).isActive = true scrollView.widthAnchor.constraint(equalToConstant: 200.0).isActive = true //testView3.translatesAutoresizingMaskIntoConstraints = false testView3.frame = CGRect(x: 10.0, y: 10.0, width: 400.0, height: 400.0) scrollView.contentSize = CGSize(width: 420.0, height: 420.0)何か間違いや、表現の中途半端さがあれば指摘してください。
追記
少し問題に遭遇したのでこの方法を検討しましたが、問題は別の方法で対応することにしたので、この方法は結局使いませんでした。
- 投稿日:2019-10-26T17:09:45+09:00
XcodeのカラーテーマをSublimeText風「Monokai」に変更する方法
はじめに
ロボカッケー皆さんコンバトラー†[□ □]■━
「Monokai」大好きお兄さんの王国騎士?ロボットVTuber⚔Koshiだ?️
Xcodeを使ってから、どうしてもデフォルトのカラーテーマに馴染めず、どうしてもコードが読みにくい。今までも元祖SublimeText3やDreamWeaver、TeraPad、TexEditor、Coda、CotEditor、Atom、VisualStudio、VisualStudioCode、Brackets、 etc...と「Monokai」を愛して止まない。だからこそXcodeでもお気に入りの「Monokai」のカラーテーマで開発したい。デフォルトのままで良いという方も、ぜひこの記事を読んで素敵な「Monokai」ライフを送っていただければ幸いです。
VisualStudioCommunity
はこちら→Visual Studio CommunityでSublimeText風「Monokai 」テーマを使用する方法じゃあ早速教えていこうか!!
環境
MacOS Mojave
Xcode Version 11.1 (11A1027)1.「Monokai」のテーマをダウンロードする
ダウンロード方法
簡単なダウンロードはzipでダウンロードすること。
「○○.xccolortheme」がXcodeのカラーテーマのファイル。
Download ZIPではなく、直接ファイル単体をダウンロードしても、gitでCloneしてもOK。インストール方法
zipフォルダを展開し、「○○xccolortheme」を以下のパスの下にコピーする。
「FontAndColorThemes」フォルダは自分で新規作成する。
~/Library/Developer/Xcode/UserData/FontAndColorThemes/
次のようになっていればOK。
Xcodeでカラーテーマを選択する
Xcodeを(再)起動し、
Xcode > Preference>Fonts & Colorsで、テーマを選択することで反映される。
おすすめSublime風「Monokai」カラーテーマ一覧
Xcode(version 11)で使用可能なカラーテーマのダウンロード先一覧。
Monokaiでも製作者によって、様々な配色がある。MonokaiXcode
https://github.com/benmarten/MonokaiXcode
私はこれが一番、SublimeText3に近いテーマだと思う。
水色○、黄色○Monokai Revisited Xcode Theme
https://github.com/b0ti/xcode-monokai-revisited
カラフルめ。
Xcode 11 Monokai Theme (Alt付き)
https://gist.github.com/a-voronov/f99782561021e17537db82aaf1e55d97
色落ち。
Altはフォントサイズが1大きい。通常 フォントサイズ11→Alt フォントサイズ12以上、Unityゲーム王国騎士ロボットVTuber Koshiがお送りしました!
私のステータスだ⚔共にこの世界を救おう
Twitter⚔ twitter.com/Koshi_Vtuber
YouTube⚔ t.co/I9eMMgpS8P?amp=1
niconico⚔ nicovideo.jp/user/90553212
bilibili⚔ space.bilibili.com/476988586
公式HP⚔ koshi-4092b.firebaseapp.com【参考】
Xcodeのカラーテーマをデフォルトから卒業する
https://qiita.com/shiba1014/items/dec0faa46163ef9a2c5f
- 投稿日:2019-10-26T03:30:03+09:00
This application’s application-identifier entitlement does not match that of the installed application. These values must match for an upgrade to be allowedf
スクリーンショット 2019-10-08 13.34.50.png
下記エラーの対応
This application’s application-identifier entitlement does not match that of the installed application. These values must match for an upgrade to be allowed
1、window → devicesのタブからデバイス情報を開く
2、左のタブから実機を選択する
3、右のリストのInstalled Apps から問題のアプリを(-)にて選択削除
4、再度インストール
- 投稿日:2019-10-26T03:16:10+09:00
swift segueの基本
画面遷移でsegueを使用する場合元のView(ViewController)から
- 投稿日:2019-10-26T00:55:57+09:00
【Swift】シミュレータのキーボード表示
シミュレーターの設定を確認する
Xcodeのシミュレーターにキーボードが表示されない場合は、次の設定を確認します。
シミュレーターのメニューから、
1) Hardware → Keyboard を選択する。
2) Connect Hardware Keyboardのチェックを外す。
これでキーボードが表示されるはずです。
Connect Hardware Keyboardのチェックが外れていると、Macのキーボードからの
入力はできません。
Connect Hardware Keyboardにチェックを入れると、Macのキーボードからの入力が
できるようになります。ちなみにこの方法で試してみてダメだった場合は、諦めずに何回かチェックをつけたり
外したりを繰り返すとキーボードが出るようになることがあります。
どうしてもキーボードが出ないという方は、こちらの方法も併せてお試し下さい!参考資料









