Guild icon
swift-developers-japan
archived / beginner-help_archived
初心者が質問をして誰かが助ける部屋 質問テンプレ [発生環境] Xcode 13.5 iOS 15.5 iPhone 13 Pro Simulator [解決したい問題] xxxが表示されない xxxが表示されるようにしたい [発生手順] 1. Aボタンをタップする 2. Bボタンをタップする [コード] コードを見せても問題ない人はリンクは貼ったり、記述したり 最小限で発生するコードだと尚望ましい
Avatar
ぼっちなう
Avatar
Deleted User 3/14/2017 2:17 PM
🤔
Avatar
Deleted User 3/14/2017 3:43 PM
🐶
Avatar
Deleted User 3/16/2017 2:23 AM
Avatar
🐍
🐳 1
Avatar
☔
🌈 1
Avatar
Deleted User 3/26/2017 7:58 AM
🐤
🐔 1
Avatar
beginner 🤗
Avatar
😽
😇 2
Avatar
omochimetaru 4/27/2017 4:04 AM
ちょっと趣旨変えてみた
👍 1
😀 1
Avatar
今UIWebviewを敢えて使うメリットって何かありますかね?単純に疑問に、思ったんですけど
Avatar
omochimetaru 4/27/2017 4:16 AM
UIWebView / WKWebView / SFSafariViewController の選択肢があるんだっけ。
Avatar
僕の専門だ
4:16 AM
お答えします。
👀 4
😆 1
4:17 AM
SFSafariViewController、こいつは要はSafariです。SafariExtensionsが使える他、Safariとクッキーキャッシュ共有している、プロセスも別という優れもの。
4:18 AM
しかし、任意のJavaScriptを実行できない、一度インスタンスを生成したら外からURLを差し込めないなど
4:18 AM
カスタマイズ性に乏しい。
4:19 AM
次WKWebView、こいつはJavaScriptが速いWebViewです(雑) APIも比較的ナウな感じでヤングなんですが、幾つかの機能(JavaScriptからTextAreaをアクティブにしてOKのプロパティ)が未実装だったり、通信フックができないのでProxy指したりアレヤコレヤは出来ません。
4:19 AM
なので
4:20 AM
纏めると、UIWebViewを使うメリット、通信フックしたい、JavaScriptからTextAreaをアクティブにしたい、等の、穿った需要がある場合に使います。どうしようもないから。
😯 2
😲 5
💯 1
Avatar
なるほど。 普通に使うぶんには使うことなさそうですねー。 ありがとうございます‼️ 🤗
😁 1
Avatar
Interface Builderで未だWKWebViewがない理由って何かあるんですか🙄
Avatar
import WebKitが必要だからだと思いますよ
Avatar
あー…Interface BuilderはUIKitで扱えるものだけなんですねー…。 なるほろ…
Avatar
あれ?GLKViewとか普通にあるな
4:52 AM
なんでだろ
Avatar
omochimetaru 4/27/2017 4:53 AM
SpriteKitのSKViewとかも置けるんだっけ
Avatar
designated initializer に以降変更不可の configuration 渡さなきゃいけないからだと思ってた。
💡 2
👏 1
Avatar
キーボードの上にToolbarを表示しようとしているんですが、IMEの予測補完周りの挙動がおかしくて困っています
8:23 AM
通常時は
8:23 AM
8:23 AM
こうなるのですが
8:24 AM
予測変換が消えると予測変換のスペース分下に下がらなかったり
8:24 AM
予測変換が消えた後予測変換がもう一回出ると
8:24 AM
8:24 AM
このように予測変換に隠れてしまったりして困っています
Avatar
UITextViewのinputAccessoryViewにUIToolbarを入れてやると良いですよ
Avatar
Notification.Name.UIKeyboardWillChangeFrame これが足りてないですね。
Avatar
UITextViewのinputAccessoryViewに何も考えずにUIToolBarを入れたらクラッシュしてしまいました(親viewを変えないといけない?) Notification.Name.UIKeyboardWillChangeFrameを足しても変わらないですね... コールバックはUIKeyboardWillShowと同じにしてますが、これがいけないんでしょうか
Avatar
うーん、ぱっと見ただけだとよくわからない、
8:46 AM
えっと、notification.userInfoの中にアニメーションの指定があるはずなので、それは参照した方が良いです
8:48 AM
もう一つ、keyboardのrectは、画面に対する相対位置になっているので、heightは見た目の高さと必ず等しくなるわけでは無いです
8:48 AM
でもこの2つは今の問題とは直接関係なさそう
8:53 AM
UIKeyboardFrameBeginUserInfoKey
8:53 AM
これ、変化前の高さですね
8:53 AM
UIKeyboardFrameEndUserInfoKeyがあるはず
Avatar
あ、動きました
8:55 AM
ありがとうございます!
😁 2
Avatar
普段はStoryboardを使わずにコードでアプリを開発しているのですが、Storyboardも使いこなさないといけないと思い今回はStoryboardで開発しています。そこでStoryboard上でのローカライズの質問なんですが、UILabelのAttributedTextがstringsでローカライズされないことに悩んでまして、これはコード上で解決するしかないのでしょうか?
Avatar
omochimetaru 4/30/2017 4:43 AM
無いと思っています・・・ ストーリーボード自体をローカライズできるけど、それやるとビュー自体を共通に保つのが大変すぎるし 方法があれば知りたい
Avatar
返信ありがとうございます。やっぱりそうですか。
4:47 AM
となると、viewDidLoadなりで、textやtitleに文字列を入れるときにNSLocalizedStringでローカライズするのがいいのかな。
4:47 AM
悩ましい。
Avatar
swiftなら、@IBOutletのdidSetに書くのが良いですね
4:49 AM
StoryboardにIBInspectableとか使って機能追加するのも出来るんですが、コード側でやった方が楽だなと言う印象があります。
Avatar
なるほど、ありがとうございます
Avatar
こんな感じでやれば出来ましたので一応共有
Avatar
NSLocalizedStringの引数のCommentの必要性が未だわからないです😩
Avatar
omochimetaru 4/30/2017 6:15 AM
""にしてる
Avatar
ですよね〜defaultで""にしていてほしい・・・
Avatar
omochimetaru 4/30/2017 6:25 AM
自分で func LSTR()を定義するとか?
Avatar
やはりそれですねー
Avatar
NSLocalizedString、素で使うの辛すぎてSwiftGenに頼ってます
Avatar
omochimetaru 4/30/2017 6:37 AM

SwiftGen とは

SwiftGen は、iOS / macOS アプリ開発の補助ツールです。リソース(アプリ内の画像やテキストなど)の扱...
6:37 AM
リソース定義をコードにしてくれるやつか
Avatar
ほぉ〜いいですね
Avatar
Safariの<input type="file">をタップすると出てくるファイルソースアプリ(?)一覧ってWebkit使わず出せますか?
10:15 AM
これです
🤔 2
Avatar
omochimetaru 5/1/2017 4:17 AM
iOSでリソースに静的型付けする系のプリプロセッサってどれがいいんですか? とりあえずSwiftGenとR.swiftが人気なのかなと思っていますが https://github.com/SwiftGen/SwiftGen https://github.com/mac-cain13/R.swift
SwiftGen - The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!
R.swift - Get strong typed, autocompleted resources like images, fonts and segues in Swift projects
Avatar
R.swiftは、全部Rから始まるのがなんか微妙ですねー。なので個人的にはSwiftGen一択になりそう・・・ (edited)
3:54 PM
Pods嫌いな自分としては、Carthageに対応して欲しいです😭
Avatar
@tarunon これですね、ありがとうございます!
Avatar
@ありぜ ( SwiftGen については知りませんが普通は)Carthage 対応は簡単なんで、 fork して対応しちゃうといいかもですね。依存ライブラリが Carthage 対応してないと面倒ですが・・・。
Avatar
@koher そうなんですねー。ありがとうございます。試してみます。
Avatar
↓です。 "Archive prebuilt frameworks into one zip file" と "Declare your compatibility" はやらなくてもいいですし、タグもつけなくても Carthage でブランチ直指定できるので、依存ライブラリがなければ実質 Xcode で scheme の Shared にチェックを入れるだけですね。 https://github.com/Carthage/Carthage/blob/master/README.md#supporting-carthage-for-your-framework
Carthage - A simple, decentralized dependency manager for Cocoa
Avatar
swiftgenのcocoapodsって
4:57 AM
コードじゃなくてバイナリが降ってきてますよね、carthageでその仕組み出来るのかな
Avatar
"Archive prebuilt frameworks into one zip file" をやればできますね。
4:58 AM
ただ、僕は SwiftGen を使ってないので、あくまで Carthage 一般論のことしかわかりません。
Avatar
swift testで走らせないテストの指定ってできないですか? Xcodeだとdisableできるので重宝するのですが
Avatar
僕は知らないですが、 swift package generate-xcodeproj して Xcode 上で実行はダメですか?
Avatar
基本はそっちなんですがswift testもやらないで良いわけじゃないですよね? パフォーマンステスト等機能に直結しないものは走らせたくないという状況です。
Avatar
うーん、パフォーマンステストも走るのが正しい状態なんじゃないでしょうか?何かミスって計算量がおかしくなってて組み合わせ爆発したりするとダメなわけですし。
Avatar
機能改修によるパフォーマンスの向上を測るために設置してるので計算量的な問題は考えてないんですよね。
9:41 AM
とりあえずはswift testを極力しないという方針で回避が良いか。
Avatar
#if とかでできないかな?
Avatar
norio_nomura 5/2/2017 9:43 AM
一時的に走らせない?それとも SwiftPM では常に走らせない?
Avatar
常にですね
Avatar
norio_nomura 5/2/2017 9:44 AM
ならばテストメソッド定義自体を #if !SWIFT_PACKAGE で囲ってしまうのが良いのでは。 (edited)
👍 1
Avatar
お、それは良さそうですね
9:45 AM
SWIFT_PACKAGEの存在自体知らなかったです。
Avatar
norio_nomura 5/2/2017 9:46 AM
generate-xcodeproj で生成されたプロジェクトには何故か SWIFT_PACKAGE 定義が含まれているので、それを消した方が良いです。
Avatar
いいかんじになりました。ありがとうございます。
🙂 1
Avatar
omochimetaru 5/2/2017 12:09 PM
@ありぜ なるほど〜ありがとうございます
😀 1
Avatar

これはなに

  • 独自の拡張メソッドを認識しやすく、かつ名前が被らないようにするため、ex をもつプロトコロルを作成してそれに準拠させるという実装スタイルがある
  • その実装をするときにハマったので共有
# モダンなSwif...
12:34 PM
こんな記事書いたのですが、原因がよく分かっておらず、もし詳しく分かる方がいたら嬉しい
Avatar
norio_nomura 5/20/2017 1:22 PM
@sutokuro NonError_1_Contents.swiftNonError_2_Contents.swiftassociatedtype CompatibleTypeassociatedtype CompatibleTyp になっていますよ。
1:23 PM
でtypoを直すとError_Contents.swiftと同じ状態になります。
Avatar
なんと、ありがとうございます
3:38 PM
確かに、NonError_1_Contents.swiftはtypoを直すと、Error_Contents.swiftと同じエラーになりました
3:38 PM
NonError_2_Contents.swift はtypoを直すと正常に動作しました。
Avatar
Error_Contents.swift において、 extension String: ACompatible { } から推測される String. associatedtype の型はAExample<Self> extension String: BCompatible { }から推測される String. associatedtype の型はBExample<Self> で、型が一致していないのでエラーになりますね。 (edited)
11:46 PM
Playgroundのコンソール Playground execution failed: error: 20170520-221301.xcplaygroundpage:42:1: error: type 'String' does not conform to protocol 'BCompatible' extension String: BCompatible { } // ここで error: type 'String' does not conform to protocol 'BCompatible' が出る 20170520-221301.xcplaygroundpage:24:9: note: protocol requires property 'bEx' with type 'String.CompatibleType' (aka 'AExample<String>'); do you want to add a stub? var bEx: CompatibleType { get } ^ 20170520-221301.xcplaygroundpage:36:9: note: candidate has non-matching type 'BExample<Self>' [with CompatibleType = String.CompatibleType] var bEx: BExample<Self> { ^
Avatar
ありがとうございます。エラーの意味は理解できました。まだちょっと自分のなかで腑に落ちない部分が残っていますが、いったん置いておきます。
5:19 AM
ありがとうございました。
Avatar
今更見たんですが、SwiftGenのCarthage対応というのはナンセンスというかできないですね。tarunonさんが言っているようにCocoaPodsではCLIツールのバイナリを配布してて、Carthageが対応してるのはあくまでビルド済みのframeworkのバイナリなので、CLIツール用の仕組みではないです。
12:26 PM
なんかそういうissueが上がってるのを見た気がする。
Avatar
SwiftLintだけどこんなの https://github.com/realm/SwiftLint/issues/1481
Goals I would like to install a specific version of Swiftlint as a dependency to my iOS project using Carthage. Currently, this works perfectly with Cocoapods: pod 'SwiftLint', '0.18.1' As result, ...
12:52 PM
CocoaPodsやらBundlerやらnpmとか考えれば機能としてはおかしくはなさそう
12:53 PM
けどそこまでやるリソースはないのが現状
Avatar
SwiftPM対応すれば https://github.com/vknabel/Rock とか https://github.com/JohnSundell/Marathon こんなのもある
With Rock you can easily install CLIs built with Swift Package Manager.
Marathon makes it easy to write, run and manage your Swift scripts 🏃
Avatar
やっぱSwiftGenのCarthage対応むりなんですねぇ・・🙄残念
Avatar
Kotlin派からこれできないのかと質問を投げかけられ、確かにできないぐぬぬとなりました class Digest { let str: String init() { str = makeString() } private func makeString() -> String { return "hoge" } } error: use of 'self' in method call 'makeString' before all stored properties are initialized
Avatar
これは出来ないほうが安全です
8:04 AM
あーprivateか
Avatar
ただ、 private とはいえ、そこから public 呼べますからね。
Avatar
ですね
Avatar
仰る通りでまずこの使い方が微妙なのはありつつも
Avatar
funcは全てのフィールドと全てのfuncにアクセス可能
8:05 AM
そもそもそのfuncはinstance methodである必要が無いので
8:05 AM
staticで宣言したほうが良さそう
Avatar
omochimetaru 5/26/2017 8:06 AM

kotlinで本物のヌルポを出す方法

kotlinではnull安全ですからヌルポとは出会えません。でも、kotlinのnull安全機構においてクラッシュするケースがあります。 !! 演算子で明示的にクラッシュケースを書いた場...
👍 1
8:06 AM
これなげつけといて
Avatar
Kotlin版 class Digest() { val str: String init { str = makeString() } private fun makeString(): String { return "hoge" } }
Avatar
代理戦争で草
Avatar
omochimetaru 5/26/2017 8:08 AM
僕もはじめKotlinの経験があったんで、swiftの仕様はつらいなあと思ったんですけど、詳しく調べてみたら、それが原因でkotlinはヌルセーフじゃなくなってたんです
8:08 AM
今はSwiftのほうがマシだと思っています
Avatar
initとstatic funcの中では、static funcが型省略して書けるようになれば
8:09 AM
まあ良さそう、でもinitは完了後と完了前とで意味が変わってくるのは微妙かなー
8:10 AM
static funcはそもそも省略可能だった
Avatar
僕、最近 Kotlin の人化してますけどねw < 代理戦争で草
Avatar
omochimetaru 5/26/2017 8:10 AM
さりげなくdisりつつ解説しているので良い感じ @koher
Avatar
トロイの木馬じゃないか
Avatar
omochimetaru 5/26/2017 8:11 AM
www
Avatar
誠実であろう
Avatar
そんな dis ってたかな。検査例外がないのとか?
Avatar
omochimetaru 5/26/2017 8:12 AM
僕は、この点については List を実装した ImmutableList クラスを別に作って、 Scala のように厳密に区別すべきだったと思います。
8:12 AM
僕は、検査例外に関してはこちらのような考えなので、検査例外をなくしてしまったこと Kotlin の言語仕様の中で一番イケてないところだと考えています。
8:13 AM
前者は Scala 方式もまだイマイチで、 letvar でゼロコストでミュータビリティを変えられる Swift 最強
Avatar
omochimetaru 5/26/2017 8:13 AM
ですね
Avatar
let var, 一番最初のArray壊れてたときはどうなるかと思ったけどめちゃくちゃ良くなってるの感慨深い
Avatar
最初の壊れ方はひどかったですね。
Avatar
関数型界隈からすごい突っ込まれてましたね
Avatar
omochimetaru 5/26/2017 8:18 AM
その関数型界隈からのツッコミというのは知らなかったです これの事かと思った http://qiita.com/koher/items/6f54eafac59793e7c364
(2015.11.18に追記) __「Swift List」 で検索するとこの投稿にたどり着いてしまいますが、関数型言語でいうところのリストをお求めの方は ["Swiftでhead、tailにパターンマッチできる遅延リスト"]...
Avatar
あったなあ…
Avatar
昔の投稿が晒されると恥ずかしい・・・
Avatar
omochimetaru 5/26/2017 8:20 AM
冒頭でもう治ったって書いてあるしまあ
Avatar
以下の、Appleが最近発表したSwiftという言語の、面白い(?)仕様が話題になってますが、 twitter:476310789..
開発者アカウントに金が出せない貧乏人の方々が、次の Apple の Swift のコードの挙動がわからない、という..
Avatar
omochimetaru 5/26/2017 8:22 AM
古いパラダイムだなw
8:23 AM
8:23 AM
let a = [1,2] // a = [1,2] var b = a; // b = [1,2] b[1] = 3; // a = [1,3] b = [1,3] b.append(5); // a = [1,3] b = [1,3,5] b[1] = 4; // a = [1,3] b = [1,4,5]
8:23 AM
これは完全に壊れてたやつだ
Avatar
www
Avatar
omochimetaru 5/26/2017 8:23 AM
Avatar
Swift でもできた! class Digest { let str: String init(item: Digest) { str = item.makeString() } func makeString() -> String { return "test" } convenience init() { self.init(item: self) } } print(Digest().str) 完全にだめなやつw
Avatar
ンヒィ
Avatar
omochimetaru 5/26/2017 8:25 AM
んごwww
Avatar
おもちくん待望の本物のぬるぽかな?
Avatar
omochimetaru 5/26/2017 8:25 AM
お、これ利用すればヌルセーフ破壊dけいそう
8:25 AM
きたか
Avatar
ぜんぜんいけますよw
Avatar
omochimetaru 5/26/2017 8:25 AM
ヌルポじゃないよ、Swiftはunmanagedだから EXC_BAD_ACCESSが来るぞ
Avatar
画面越しに超喜んでるのが想像出来て草
Avatar
omochimetaru 5/26/2017 8:26 AM
www
Avatar
すごい、↓こんなの思いつかないw convenience init() { self.init(item: self) }
Avatar
self.initselfが渡せるのがもうおかしい気が
Avatar
それ通っちゃうんか...
Avatar
omochimetaru 5/26/2017 8:26 AM
この前のvar self書き換えに通じるテクニックですね
Avatar
バグですねー
Avatar
class Digest { let str: String let hello: String init(item: Digest) { str = item.makeString() hello = "test" } func makeString() -> String { return hello } convenience init() { self.init(item: self) } } print(Digest().str) // "" <- ?
8:26 AM
ん?
8:27 AM
Stringは、あれかw
8:27 AM
真にnullだったら""に化ける
8:27 AM
@ezura がこの辺は詳しかったはず
8:32 AM
できた。
8:33 AM
多分Stringの場合はそれ自体が値型で、メモリはゼロクリアされているんで、内部バッファへのポインタがnilとかサイズとか0とかいろいろ、ゼロ値でうまくうごく
8:33 AM
参照型のフィールドを初期化済み扱いで受け取れば壊せる
Avatar
オレオレStructでも落ちた Foo() 1(75709,0x70000aac2000) malloc: *** error for object 0x6180000129ec: Invalid pointer dequeued from free list *** set a breakpoint in malloc_error_break to debug
8:33 AM
見たことのないエラーだw
Avatar
omochimetaru 5/26/2017 8:33 AM
やばそうw
Avatar
not nullsafe より null unsafe の方がいいかも
Avatar
omochimetaru 5/26/2017 8:34 AM
かえといた
Avatar
Foo()はnilからうまいこと推測されて出てきたは良いものの、その後の諸々でぶっ壊れてる
8:40 AM
この間の @rintaro  のself書き換えでNib/Stroyboardのinstantiateが書けたけど
8:40 AM
やっぱりpropertyとしてletを置けないので価値はそこまで高くない感じ
8:40 AM
こうなる
Avatar
やばい、チャネルの内容が #beginner-help_archived じゃなくていつもの #swift モードになってるw
Avatar
あっ
Avatar
omochimetaru 5/26/2017 8:40 AM
あ、まちがえた
Avatar
#swiftじゃなかった
8:41 AM
気がついてなかった、すみません
Avatar
話が弾んじゃいましたねw
Avatar
では話題を戻して モダンなSwiftのExtension ですけど、 UIColor.hogeview.backgroundColor = .hoge できるけど UIColor.ex.hogeview.backgroundColor = .ex.hoge できないってどうなんですかね?
Avatar
omochimetaru 5/26/2017 6:24 PM
そのパターンって 1段しか推論できないんですっけ
6:25 PM
左辺値の型に対して探索する事は決まってるはずだから、右辺の式が多段になっててもできていい気がする(言語仕様の改善として
6:25 PM
両辺が不定のまま推論でガッチャンコするようなパターンもあるんだろうか、あまり書かなくてわからない
Avatar
それ#beginner-help_archivedの話題でいいの?
Avatar
むむ どこまでbigginerなのか悩ましいですね
Avatar
omochimetaru 5/27/2017 8:40 AM
質問する人が「広く答えが知られた問題であろうが自分が詳しくないためわからない」と感じるのが初心者質問のイメージ。
8:42 AM
ただ、本人がそう思っていても、高度なトピックだと思われる場合、そういうのが頻発すると、本当の初心者にとっては「ここは自分のような本当の初心者が発言するには場違いだ」と萎縮してしまうのは本意ではないので
8:42 AM
回答しようとした時に回答者がチャンネルを移動するのが良いかも?
8:43 AM
他にも、UIKitチャンネルとか、内容に即したチャンネルに移動するなり。
8:43 AM
ちょっとしたことでも以外とピンポイントだと知らない人も多かったりすることがあるんでトピックチャンネルのほうが知見が集約できて良いと思います
8:45 AM
話題を投稿する時点で「どこが適切だろう?」というのを気にしすぎてめんどくさくなるのは残念なので、まあ気軽に書き込んでもらって、
8:45 AM
回答する人が交通整理していくのが良さそう。
👍 5
Avatar
func mockFetch() -> Observable<Bool> { return Observable.create { observer in observer.on(.next(true)) observer.on(.completed) return Disposables.create() } }
2:41 AM
mockFetch().subscribe(onNext: { _ in print("done") }).disposed(by: disposeBag)
2:41 AM
↑の返り値が必要ない時に使えるSubject?とかコードの書き方とかってあるのでしょうか?
Avatar
返り値はこの場合何を指してますか?
Avatar
終了したことを教えたいだけです
2:44 AM
Emits zero elements Emits a completion event, or an error Doesn't share side effects
2:44 AM
CompletableならNext0個で、.subscribe(onComplete: {}) で拾うという手があるかも?
Avatar
もともとのモチベーションがcompletionHandlerをRxで書き換えたいという感じです
Avatar
completeが欲しいだけなら、ignoreElementsが使えそう
Avatar
ありがとうございますm( )m
Avatar
omochimetaru 5/29/2017 2:45 AM
それならSingleのほうが良い気も?Nextの型パラは <Void> にして気にしないとか
Avatar
たしかに、Voidで大丈夫ですね、、、
Avatar
今はcompleteだけで良いかもしれないけど、他でそうかという問題があるので、
2:47 AM
Single<Bool>にして値は適当に無視するのが良さそう。
👌 1
2:48 AM
さっきのmockみたいにnext, completeしたいだけなら create で書かずに .just でもかけますよ。下請けに本当の非同期処理がある場合は create ですね
Avatar
了解です!
Avatar
cocoapods(1.2.1)を使って開発してるんですが、写真のエラー出てしまい、解決できなくて困ってます。このエラーに出会った方とかいらっしゃいますか?再起動とかpod install とか Podsフォルダとか消していろいろ試しても無理でして。
12:08 PM
[CP] Check Pods Manifest.lock の内容は下記のとおり
12:08 PM
diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null if [ $? != 0 ] ; then # print error to STDERR echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 exit 1 fi
Avatar
I'm currently working on an objective c project where we are trying to now incorporate swift into the project. When I add a Swift unit test to the project I get the following prompt: I create the
2:00 PM
差し支えなければPodfileとPodfile.lockの内容は上げれますか?
Avatar
platform :ios, '9.0' target 'XXXXX' do pod 'CorePlot', '2.2' pod 'Google-Mobile-Ads-SDK', '7.20.0' pod 'FBSDKCoreKit', '4.23.0' pod 'FBSDKLoginKit', '4.23.0' pod 'FBSDKShareKit', '4.23.0' pod 'Flurry-iOS-SDK/FlurrySDK', '8.1.0' pod 'Fabric', '1.6.11' pod 'TwitterKit', '2.8.1' pod 'TwitterCore', '2.8.0' pod 'Crashlytics', '3.8.4' pod 'SVProgressHUD', '2.1.2' pod 'Realm', '2.7.0' pod 'Repro', '2.4.0' pod 'SwiftLint', '0.19.0' end post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['CLANG_WARN_DOCUMENTATION_COMMENTS'] = 'NO' end end end
4:25 PM
PODS: - Bolts (1.8.4): - Bolts/AppLinks (= 1.8.4) - Bolts/Tasks (= 1.8.4) - Bolts/AppLinks (1.8.4): - Bolts/Tasks - Bolts/Tasks (1.8.4) - CorePlot (2.2) - Crashlytics (3.8.4): - Fabric (~> 1.6.3) - Fabric (1.6.11) - FBSDKCoreKit (4.23.0): - Bolts (~> 1.7) - FBSDKLoginKit (4.23.0): - FBSDKCoreKit - FBSDKShareKit (4.23.0): - FBSDKCoreKit - Flurry-iOS-SDK/FlurrySDK (8.1.0) - Google-Mobile-Ads-SDK (7.20.0) - Realm (2.7.0): - Realm/Headers (= 2.7.0) - Realm/Headers (2.7.0) - Repro (2.4.0) - SVProgressHUD (2.1.2) - SwiftLint (0.19.0) - TwitterCore (2.8.0): - Fabric - TwitterKit (2.8.1): - TwitterCore (>= 2.8) DEPENDENCIES: - CorePlot (= 2.2) - Crashlytics (= 3.8.4) - Fabric (= 1.6.11) - FBSDKCoreKit (= 4.23.0) - FBSDKLoginKit (= 4.23.0) - FBSDKShareKit (= 4.23.0) - Flurry-iOS-SDK/FlurrySDK (= 8.1.0) - Google-Mobile-Ads-SDK (= 7.20.0) - Realm (= 2.7.0) - Repro (= 2.4.0) - SVProgressHUD (= 2.1.2) - SwiftLint (= 0.19.0) - TwitterCore (= 2.8.0) - TwitterKit (= 2.8.1)
4:26 PM
SPEC CHECKSUMS: Bolts: 8a7995239dbe724f9cba2248b766d48b7ebdd322 CorePlot: cbe0c6e14220705e32e06a89c7d6a5a908b7d7d8 Crashlytics: 79e236942ca1e7fc641df1feb9a275360a78ab6a Fabric: 5911403591946b8228ab1c51d98f1d7137e863c6 FBSDKCoreKit: d7829f5a69901cd7296105328e4c3c3fc7da6518 FBSDKLoginKit: 6b92bd65f319d669d2b0730e49db495ef1660566 FBSDKShareKit: 65751c3b9937ab9d594e6c37611ecc115ceeb448 Flurry-iOS-SDK: 51065be4436f3e21fc8d3d7bb0b7d6869df6333d Google-Mobile-Ads-SDK: 168312cdc167fa22746d4ea8e839fc4825dd2966 Realm: 07e5d3a9e0e41d65fd5f9f05150ed6295d0f093b Repro: e69274efa79b1e8f25ec14177356968d9a8e8224 SVProgressHUD: c404a55d78acbeb7ebb78b76d3faf986475a6994 SwiftLint: 3537a05b34060e78e7510f04fb7537d738247803 TwitterCore: e959987be23c767004d29eb7fab8d85d8585a2e5 TwitterKit: 3b6044a7320340326a4098f3e37aa1dbaeb94942 PODFILE CHECKSUM: 47c07dc78a6793f29d1576ffa394f4c5e5b5076e COCOAPODS: 1.2.1
4:26 PM
ありがとうございます。Podfile.lockはDiscordの文字数制限でエラーになったので分割しました。
Avatar
上記の件、再起動して、Derived Dataをけしてクリーンしてビルドしたら正常に動作しました。金曜日にも同じ手順でやっても駄目だったんですが、今日やるとできました。
Avatar
おっ、再現できなくて参っていました、お力添えできずすみません。
Avatar
いえ、反応していただいただけでも、とても嬉しかったです。ありがとうございます。これで安心してWWDC見れます。
🎉 1
Avatar
くっ、ビルドはできたけど、アーカイブが同じエラーで止まってしまった
4:38 AM
辛い
Avatar
omochimetaru 6/5/2017 4:39 AM
~/Library/Developer/Xcode/Archivesも消してみては?
4:40 AM
Xcodeを Cmd + Q で終了してから以下を削除 ~/Library/Developer/Xcode/Derived Data ~/Library/Developer/Xcode/Archives
Avatar
~/Library/Developer/Xcode/Archivesも消して空です
Avatar
omochimetaru 6/5/2017 4:41 AM
むむむ
4:42 AM
そもそもCocoapodsの利用をやめることは難しいですか?
4:42 AM
僕はCocoaPodsもCarthegoも、オレオレビルドプロセスを取るのが嫌いで、使ってないんですよね こういう問題が起こった時に困る
Avatar
検討してますが、上記のPodfileを見るとおわかりかと思うのですが、coreplotを切ってから全てをCarthageに移行しようかと思ってまして。
Avatar
omochimetaru 6/5/2017 4:43 AM
なるほど
Avatar
あ、Cartheageもですか、では、自分でプロジェクトに手動で追加してると
Avatar
omochimetaru 6/5/2017 4:43 AM
はい。
4:43 AM
xcworkspaceで作業場を作って、ライブラリはxcodeprojをそれに追加する形にして、
4:44 AM
embedded libraryの依存を組んでビルド
4:44 AM
基本的にgit submoduleでやってます
4:44 AM
でも、kuroさんのケースだと使用数が多いから、carthageでcheckoutだけやって、ビルドだけxcodeに登録するのが良さそうな気もします
Avatar
embedded libraryの依存を組んでビルドして git submoduleでビルドする構成をやったことがないので知識が乏しいですが、その方法も考えて今後対応してみます。
4:48 AM
実は今回のエラーは、ビルド用、アーカイブ用のiMacでのみエラーが起きてて、普段開発で利用しているMBPでは特にエラーが発生せずにビルドできています。今回は、MBPの方でアーカイブ作成して申請することにしました。
4:48 AM
でも、今までとくにエラーもなくiMacでもビルドできていたので、なんでエラーが出てるのか正直よくわからなくて困っています。
Avatar
omochimetaru 6/5/2017 4:48 AM
なるほど・・・
Avatar
iMacとMBPのOSバージョンやXcodeのバージョンはもちろん同じなので
4:49 AM
cocoapodsも同じ
4:49 AM
なので、どこが問題の原因になっているのか特定できずうーんて感じです。
Avatar
omochimetaru 6/5/2017 4:50 AM
diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null if [ $? != 0 ] ; then # print error to STDERR echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 exit 1 fi
4:50 AM
このエラーメッセージが出てるってことは、 ${PODS_PODFILE_DIR_PATH}/Podfile.lock と ${PODS_ROOT}/Manifest.lock の間に diff があるということですけど
4:50 AM
どんな差分だったんですか?
Avatar
あ、いや echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. このメッセージは出て無くて、差分はないと思います。
Avatar
omochimetaru 6/5/2017 4:52 AM
ああ、なるほど
4:52 AM
[CP] Check Pods Manifest.lock < これは 緑のアイコンだった。
Avatar
このエラー
4:52 AM
なので、unknown reasons なのでわからんいんです。
4:53 AM
うーん、やっぱりomochimetaruさんのビルド方法を検討するほうが、無駄な問題に悩むずに済むような気がしてきました。
Avatar
omochimetaru 6/5/2017 4:53 AM
console.app に関係ありそうなログは出てませんか?
4:54 AM
individual build tasks 達が内部で抱えたエラーについての情報が集められないと厳しそう (edited)
Avatar
ほう、console.appですか、見てみます。
Avatar
omochimetaru 6/5/2017 4:55 AM
はい、一部のプロセスやデーモンはここにエラー吐いてる事があります。
4:58 AM
ビルド方法
1. xcworkspaceを作る。(これ自体はただのxcodeprojの配列のようなもの) 2. ライブラリとアプリのxcodeprojをxcworkspaceに追加する 3. アプリの ターゲット の General / Embedded Frameworks and Libraries の一覧の「+」を押してダイアログを出す。 4. ダイアログの中に、xcworkspaceに入れてあるxcodeprojのライブラリターゲットが並んでるので、それを選ぶ 5. アプリをビルドすると依存ビルドされる という感じ
5:00 AM
デメリットとしては ・ライブラリのバージョン合わせについては手動でがんばる(か、carthageをそのチェックアウトだけに使うなど) 工夫が必要 ・xcodeの schema リストに、入れてある全てのxcodeprojのターゲットが突っ込まれるので、めちゃくちゃターゲット数が多くなって気持ち悪い。これは心の目で無視する。 ・普段はキャッシュされるのでアプリ部分だけのリビルドで済むけど、何かが壊れた時にはクリーンする必要があって、その場合ライブラリ全部リビルドになるので待ち時間が長い。
Avatar
ありがとうございます。涙が出ます。
5:01 AM
console.app を開けながら
5:02 AM
再度Xcodeでアーカイブして失敗したのですが、どこにエラーらしきログが出ているのか
5:02 AM
把握するのが難しい。
Avatar
omochimetaru 6/5/2017 5:03 AM
macOS Sierraだとして、デバイスのとこでマシン名出てるの選んで、上部のバーで「エラーと失敗」のタブを開いておく
Avatar
ああ、デバイスを選ぶと「エラーと失敗」のタブが選択できるんですね。できた。
Avatar
コンソールのエラータブに出てたエラー
5:14 AM
Xcodeでアーカイブしているときに出たエラーは、これだけでした。
5:15 AM
でも、あまり関係なさそうな。
Avatar
エラーの詳細
5:24 AM
skylight framework ? 初めて聞く名前
Avatar
omochimetaru 6/5/2017 5:57 AM
Skylight.frameworkでググるとSierraにしたらクラッシュするようになった、みたいなイシュー報告と共に出てきますね
5:58 AM
いまいちわからないですねえ
Avatar
ぐぐると、でますね。もう少し色々ためして様子を見ます。omochimetaruさん色々反応してくださりありがとうございます。
Avatar
omochimetaru 6/5/2017 6:05 AM
はいー
Avatar
Alamofire(HTTPリクエストを簡単にするラッパーのライブラリ)でAPIにリクエストした結果を、どうしてもストレージにキャッシュさせたくないんですが、いい方法はないでしょうか。 https://stackoverflow.com/questions/32199494/how-to-disable-caching-in-alamofire を参考にしてみたのですが、どうやらこれは「現在のリクエストについて、キャッシュされていたデータを利用するかしないか」という設定なのか(これは勝手な推測です)、iPhone SimulatorのLibrary/Cachesの中にはAPIリクエストの結果が保存されてしまいます。 (edited)
When I send a GET request twice with Alamofire I get the same response but I'm expecting a different one. I was wondering if it was because of the cache, and if so I'd like to know how to disable it.
Avatar
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil) で解決しました(この方法だとアプリ全体でキャッシュが効かなくなりますが、画像周りは独自のキャッシュを実装していたので今回は影響がなかった
🙂 2
🙃 1
Avatar
HTMLから変換したNSAttributedStringで、リンクをタップした際の挙動をSafariを開く挙動から自分で定義した挙動に変更するにはどうしたらいいのでしょう
Avatar
delegate実装すれば拾えますよ
Avatar
なるほどdelegate
12:32 AM
ありがとうございます
3:37 AM
上記のエラーに悩まされていまして,
3:37 AM
Xcodeビルドできない状態が続いています。
3:37 AM
Clean Clean build folder Quit Xcode Open Finder then go to ~/Library/Developer/Xcode/DerivedData then deleated everything inside Open Xcode Build
3:37 AM
一通り試したのですが、エラーが解消できず。
3:38 AM
同じエラーに遭遇した方いらっしゃいますか?
3:38 AM
ちなみにobjcのファイルをswiftにリファクタリングしているときに起こります。
3:38 AM
Xcodeは8.3.3です。
Avatar
上記の件、一応解消できたので報告。Macの初期化までして色々試してもだめでしたが、cocoapodsやfastlaneを管理するGemfileやvendor/bundleフォルダを削除すると正常にビルドできるようになりました。fastlaneをつかったモダンなデプロイ環境は一旦諦めることになってしまいました。なぜ、Gemfileやvendor/bundleフォルダがあると、上記のエラーが頻発する(エラーがでないときもある)のかはわからなかったです。いつもswiftのコンパイルが始まると上記のエラーになるので、もしかするとswiftのコンパイラーと私のGemfile等の設定の相性が悪いのかもしれません。どこかのブログでobjcとswiftの混合プロジェクトにおいて、swiftファイル数が多くなるとビルドに失敗することが多くなるといった記事を見かけたので、それも原因の一つかもしれません。ちなみに、エラーの起きていたプロジェクトの構成は objc (1194ファイル)でswift(378ファイル)あります。全てswiftにするまでの道のりは結構険しい。
4:56 AM
長文失礼しました!
Avatar
omochimetaru 6/21/2017 4:56 AM
お疲れ様です・・ 長文気にしなくて大丈夫です
Avatar
そう言っていただけるとありがたいです
😀 2
4:57 AM
なんか質問しかしてないアカウントになりつつあるので、ちゃんと何かしらの形で貢献しないと!(できるのか笑)
Avatar
omochimetaru 6/21/2017 4:59 AM
質問をすると他の人が質問をする心理的ハードルが下がるという貢献があります
😀 4
Avatar
rbenv, rbenv-gemset, bundler併用するとどうなるでしょう、環境汚さないでgemの管理ができるようになるので何か変わるかもしれません
Avatar
rbenvでrubyのバージョンを固定して bundle install --path vendor/bundle して bundle exec fastlane ios staging とか bundle exec pod install とかしてました。 rbenv-gemset (edited)
5:04 AM
は知らなかったので今度試します。
Avatar
なるほど...問題なさそうな構成ですね 手元でcocoapods、fastlane動いてるGemfileになります、お役に立つか分からないですが # frozen_string_literal: true # A sample Gemfile source "https://rubygems.org" gem "fastlane" gem 'cocoapods' gem 'cocoapods-keys'
Avatar
ありがとうございます。ほぼ一緒ですね
5:08 AM
source "https://rubygems.org" gem "cocoapods", '1.2.1' gem "fastlane", '2.11.0'
🤔 1
5:08 AM
fastlaneのバージョンが古いのは
5:08 AM
New Issue Checklist Updated fastlane to the latest version I have read the Contribution Guidelines Issue Description I updated fastlane(2.11.0) to the latest version(2.23.0) by bundle update fa...
5:09 AM
このエラーに悩まされて、fastlaneにissueを投げた当時から固定してたからです。
5:09 AM
当時の構成とはまたcocoapodsとかコードの構成が変わっているのでまたやると同じかどうかわからないですが。
Avatar
これから取り急ぎiOSアプリ開発を始める人に向けて、本を2冊だけ紹介しようとしてます。 1冊は言語周りということでSwift実践入門を薦めようと思ってます。 ただ、もう1冊どうしようかなと悩んでます。 内容的にはUI周りを含めた現段階でのプラクティス本を薦めたいのですが、心当たりある方いらっしゃいませんか? 昔でいうとtokoromさんのiPhoneプログラミングUIKit詳解リファレンスみたいなのの現代版があるとウレシィのですが。。
Avatar
プログラミングの経験はどのぐらいある方ですか?
Avatar
4年目Androidエンジニアです。 職場のコードがレガシーMVCだらけな中、自分からRxJavaとMVVMに挑戦中のモチベーション高めなエンジニアですー
Avatar
そういった本がSwiftになってからでてないのがほんとに寂しいんですけど、僕が前新卒に課題図書として出した本の中から1冊だけ紹介しておきます。2冊出したんですけど、もう一冊はプログラミングの初歩から書いてある本で、4年目の方だとつまんなく感じてしまうと思うので。 本気ではじめるiPhoneアプリ作り Xcode 8.x+Swift 3.x対応 (ヤフー黒帯シリーズ) 西 磨翁 https://www.amazon.co.jp/dp/4797389826/ref=cm_sw_r_tw_dp_x_FBivzbQ7Z4187
😊 1
Avatar
おお、ありがとうございます。良さそうですね!
5:20 AM
ボソッ (アフィ付きでいただければそこからポチりますよ〜)
Avatar
(クッソそういうの持ってない😇
😇 2
Avatar
ではこのままポチらせていただきますw d_dateさんありがとうー
Avatar
omochimetaru 7/7/2017 2:15 AM
あれ?
2:15 AM
なんか今ファントム投稿あった?
Avatar
ファントム投稿w
2:15 AM
読んでたら消滅した
Avatar
ファントムしましたw 途中でなげてしまったので、今やりなおしてますw
Avatar
omochimetaru 7/7/2017 2:15 AM
「幻影だ」
Avatar
Enter で投稿するシステム、人権侵害なので国連で規制議論されてほしい
Avatar
iPhone版なら改行は改行だよ
Avatar
あー、モバイル版は人権守られてますね
Avatar
omochimetaru 7/7/2017 2:17 AM
Enter押すな
Avatar
Shift + Enter できないから
2:17 AM
SKK 過激派か?
Avatar
iPadはEnterで飛んでいきますね
2:17 AM
どこに投げていいかわからないトピックなので、とりあえずここに投げてみます。 VCのViewDidLoadで、あるメソッドを通過していないときにエラーを吐かせたいと思ってるんですけど、assertを書くことにすると、そもそもassertを書く人はそのメソッドを呼ぶのが必要だと認知しているので、assertはいらないことになります。 具体的には、Clean Architectureで、画面遷移前にpresenterをinjectするようなケースです。presenterはIUOで定義しているので、セットしていないpresenterにアクセスした時点でクラッシュするのでランタイムでは検知できますが、ビルドエラーで検知できたらベストだと思っています。このあたりみなさんどんなふうにやってますか?
Avatar
VCにカスタムinit定義するのがはやいんじゃ
Avatar
omochimetaru 7/7/2017 2:19 AM
同じような悩みを抱えたことがある気がする
2:19 AM
コンストラクタが使えれば解決するけどXIBとの兼ね合いでできず
Avatar
こういう便利なものがありまして(ステマ) https://github.com/tarunon/Instantiate
Instantiate - Type-safe and constructor injectable InterfaceBuilder protocols.
Avatar
omochimetaru 7/7/2017 2:19 AM
このViewControllerはこのプロパティを埋めてからpresentしろってなる
2:20 AM
injectって言ってるからこの場合はプロパティを埋めるんじゃなくて初期設定メソッドを呼ぶみたいな感じだろうけどまあsetter呼び出しもメソッドと考えると同じ
2:20 AM

as is

let storyboard = UIStoryboard(name: "ViewController", bundle: Bundle.main) let vc = storyboard.instantiateInitialViewController() as! ViewController vc.inject([1, 2, 3])

to be

import Instantiate import InstantiateStandard extension ViewController: StoryboardInstantiatable {} let vc = ViewController(with: [1, 2, 3])
Avatar
そのまま使うとviewを先にloadしちゃうけど、ちょっと拡張すればview後にloadも出来るから多分大丈夫じゃないかな
Avatar
omochimetaru 7/7/2017 2:22 AM
これってこの ViewController.init(with:) を 呼ぶことを忘れなければうまくいくけど
2:22 AM
それを呼ぶのを忘れない仮定をおけるのであれば
2:22 AM
規定の初期化処理をするのを忘れないと言えそうな気が。
2:23 AM
もちろん、忘れない前提において、tarunonのやつのほうがスッキリするところは旨味だけど
2:23 AM
相談内容の前提は解決してない気がする。
Avatar
他のinitをunavailableすればオッケーですね
Avatar
omochimetaru 7/7/2017 2:23 AM
お、なるほど・・・
Avatar
overrideでunavailableできますよ
Avatar
omochimetaru 7/7/2017 2:24 AM
Instantiateの内部で他のinit呼んでてそこでunavaiable警告出たりしないの?
Avatar
nib/sbから取り出してるからinitは存在しない
Avatar
omochimetaru 7/7/2017 2:24 AM
確かに!!!!!
2:24 AM
そうですね。
Avatar
そもそもassertを書く人はそのメソッドを呼ぶのが必要だと認知しているので、assertはいらないことになります。
これって VC を実装する人目線ですか?使う人目線ですか?↑の @omochimetaruinject みたいに「あるメソッドを通過」が外から呼び出すことを意図しているなら、 assert を書く人と呼び出す人が別な気がするので「assertはいらない」ことにならない気がするんですが・・・。
(edited)
Avatar
自分は遷移処理を抽象化してVrewController用のRouter書いてしまってます requestに対してrouterがviewControllerのインスタンスを返す、みたいな
Avatar
inject関数が型として抽象化されていて、viewControllerのタスクも同様に抽象化されていれば
2:30 AM
injectの引数からviewControllerのタスクの結果を取り出すRouterみたいなのも普通に出来ますね
Avatar
omochimetaru 7/7/2017 2:31 AM
@moaible ナマのstoryboardメソッドや生のコンストラクタは触らない規約でやっていくってことですか?
Avatar
@omochimetaru ViewControllerにrouterに適合させるためのstaticな関数を置いて、そこに問い合わせるのでその中なら生のコンストラクタを使ってもいいですし、storyboardから生成してもいいしって感じにしてます
Avatar
omochimetaru 7/7/2017 2:33 AM
なるほど
Avatar
案の定だけど議論の中身が #swift みてきた
Avatar
omochimetaru 7/7/2017 2:35 AM
@unavailable をある特定の呼び出しにおいてだけ警告抑制できれば
2:35 AM
staticメソッドおいておいて他のファクトリ経由を矯正することがある程度できそうですね
Avatar
ちょっと話かけられて離れてる間にすごい進んでました😇 ありがたいです
Avatar
omochimetaru 7/7/2017 2:35 AM
@moaible のRouter や @tarunon のInstantiateと同じように
Avatar
Instantiateはinitアレするので、alloc/deallocが一回ずつ余分に発生するけどね。
2:36 AM
@rintaro 先生ソース
Avatar
omochimetaru 7/7/2017 2:36 AM
storyboardから取り出すメソッドを利用禁止するのは無理かなあ
Avatar
スコープ対象の unavailable が欲しい時がある。 @available(*, unavailable, scope: public) 的な (edited)
Avatar
あるある
2:37 AM
storyboard自体は禁止しなくても流石にinitとかfactoryメソッド生えてたら間違えないとは思うけど
2:43 AM
overrideせずにprotocol生えてたらこのメソッド禁止!トかやりたいけど出来ない。
Avatar
みなさんありがとうございます。どれも良さそうなんですけど、tauronさんのInstantiateを採用するのが今のソースコードには合ってそうな感じがしました。 (にしてもこのあたりもうちょっと簡単にできたらいいなー…)
Avatar
norio_nomura 7/7/2017 12:26 PM
githubのリポジトリへのアクセスにsshをあえて使う理由って何があるのでしょう?
Avatar
二段階認証してると、HTTPSでpushするときにgithubのアカウントのパスワードが使えないとかですかね
Avatar
トークンで良いはず
12:53 PM
何もかもが面倒臭くてhttpsを使いがち。
Avatar
あーたしかに
12:53 PM
あとはgithubのパスワードをローカルのストレージに保存しなくていいとかですかね
12:54 PM
(それもtoken使えばいいか)
Avatar
omochimetaru 7/7/2017 1:22 PM
@norio_nomura pushするために自分のリポジトリはそうしてます。認証機構としてssh-agentなのも安心感がある。
1:22 PM
httpsだとコンソールでuseridとpassword聞かれるけどそれはどうなるんだろ
1:23 PM
githubにかぎらず普通にssh先のサーバーにリポジトリ設置したりした場合も
1:23 PM
httpsよりそっちのほうが素直に構築できるし。
1:24 PM
僕も push するリポジトリは ssh です。
Avatar
norio_nomura 7/7/2017 1:24 PM
パーソナルトークンをそれでkeychainへ入れてますね。
Avatar
omochimetaru 7/7/2017 1:26 PM
なんかすでにそれもセットアップしてあった
1:26 PM
たしかgithubってHTTPSでリードしかしてなくても
1:26 PM
たくさんやってるとブロックされた気がする
1:27 PM
このマニュアル見る限りあそこでコンソールでパスワードいれたら保存されるのか・・・?
Avatar
norio_nomura 7/7/2017 1:27 PM
パーソナルトークン使ってるとその制限は緩くなったはずです。>アクセス権限 (edited)
Avatar
omochimetaru 7/7/2017 1:28 PM
はい。リードでブロックされて、調べて、これをセットアップしたような記憶がありまsj
1:31 PM
うーんそうするとhttpsでもいいのかなあ。
Avatar
norio_nomura 7/7/2017 1:31 PM
このマニュアル見る限りあそこでコンソールでパスワードいれたら保存されるのか・・・?
キーチェーンに保存されます。
Avatar
omochimetaru 7/7/2017 1:31 PM
gitプロトコルについてよくしらないんですけど
1:31 PM
sshでパイプで相互IOつないで
1:31 PM
差分計算とかいろいろやってるけど
1:31 PM
httpsのときも
1:31 PM
トランスポートが違うだけで同等なことができているのか
1:32 PM
httpsだと簡易的な(効率の悪い)プロトコルになるのか
1:32 PM
そういうのが気になる。
1:32 PM
思い出してきた、昔読んだ何かにそんな話題があったようななかったような
Avatar
norio_nomura 7/7/2017 1:33 PM
sshの場合、ちゃんと設定しないとhttpsより遅かったはずです。
1:33 PM
>SSH : 最後に、HTTP/S、Git、Local プロトコルと同程度に効率的です。転送するデータを可能な限りコンパクトにすることができます。
1:34 PM
しかしバージョン 1.6.6 でより高機能なプロトコルが導入されました。これは、SSH の場合と同じように、HTTP でのデータのやりとりも Git が賢く処理できるようにするためのものでした。 ここ数年で、新しいほうの HTTP プロトコル はとても多く使われるようになりました。ユーザーからすればこちらのほうがシンプルですし、通信方法としても優れているからです。 新しいほうは “smart” HTTP プロトコルと呼ばれていて、古いほうは「ダム」(dumb)HTTP プロトコルと呼ばれています。 まずは “smart” HTTP プロトコルのほうから説明しましょう。
1:34 PM
HTTPS上のgitに2種類あって、1.6から smart HTTP というのができて
1:34 PM
これが効率的らしい
1:35 PM
自分がgit勉強したときこの記述なかった気がするし知識が古かったのか
1:36 PM
1.6が 2010年9月だしそんなこともなさそう・・・
1:42 PM
Username for 'https://github.com': omochi Password for 'https://omochi@github.com': remote: Invalid username or password.
1:42 PM
パスワード通らない・・・
1:43 PM
ああ、2FAの場合の設定は別口からやるのか
Avatar
norio_nomura 7/7/2017 1:56 PM
If you have enabled two-factor authentication, or if you are accessing an organization that uses SAML single sign-on, you must provide a personal access token instead of entering your password for HTTPS Git.
https://help.github.com/articles/which-remote-url-should-i-use/
Avatar
omochimetaru 7/7/2017 1:56 PM
セットアップできました。
Avatar
omochimetaru 7/11/2017 2:14 AM
Via HTTPS For those checking out sources as read-only, HTTPS works best: git clone https://github.com/apple/swift.git ./swift/utils/update-checkout --clone Via SSH For those who plan on regularly making direct commits, cloning over SSH may provide a better experience (which requires uploading SSH keys to GitHub): git clone git@github.com:apple/swift.git ./swift/utils/update-checkout --clone-with-ssh
2:14 AM
swiftのリポジトリにも、sshのほうが may provide a better experience って書いてあるけど
2:15 AM
この前のからするとそうでもなさそう
Avatar
import UIKitしてるファイルで、UI系のクラスを使っていなくて、import Foundationで事足りる場合、Foundationに変更した方がいいですよね? UIKitのままにしておくメリットってないですよね?
Avatar
僕の知る限りはないように思います。
Avatar
ありがとうございます!
Avatar
import UIKit let numbers = (1...5).map(String.init) print(numbers) // ["1", "2", "3", "4", "5"] var a: [String] = [] // No Error a = Array(numbers.prefix(3)).map { $0 } print(a) // ["1", "2", "3"] // No Error let arraySlice: ArraySlice<String> = numbers.prefix(3) a = arraySlice.map { $0 } print(a) // ["1", "2", "3"] // Error(error: ambiguous use of 'prefix')→ なぜエラーに? // a = numbers.prefix(3).map { $0 }
4:27 AM
最後の numbers.prefix(3).map { $0 } ambiguous use of 'prefix' になる理由がわからず。
Avatar
前に #swift 部屋で話題になったやつだ
Avatar
あ、既出ですか
4:28 AM
出遅れた
Avatar
要約するとたしか、prefixはoverloadになっていて、その両方Sequence型でmapを持っているため
4:29 AM
だったかな
Avatar
#swift 部屋を遡ってみます
Avatar
prefixで検索すると見つかります
Avatar
ありがとうございます。
Avatar
5月23日ですね
4:31 AM
パーマリンクほしいなぁw
Avatar
(同じく検索してパーマリンク取ろうとしたけどできなかった)
Avatar
ジャンプボタンが存在するんで、内部的にはありそう(作れそう)なんですけどね
Avatar
t.aeさんの話ですね
Avatar
ArraySliceにおいてprefixはAnySequenceとArraySliceのoverloadで、これのどちらであるかを判別できなくなるのが原因ですね。
😃 1
4:34 AM
evolutionにはSequenceのassociatedtypeにSubSequence型を追加して解決しようよという提案があった記憶があります、どうなったかは追いかけれていない。
4:35 AM
あれ、入ってるな
4:35 AM
何かと勘違いしていたみたいです、すみません。
Avatar
ArraySliceにおいてprefixはAnySequenceとArraySliceのoverloadで、これのどちらであるかを判別できなくなるのが原因ですね
👍 1
4:36 AM
納得しました!ありがとうございます。
Avatar
RGBA のピクセル列から NSImage を生成して tiffRepresentation を呼ぶと nil が返ってきてしまうんですが、解決策をご存知の方はいませんか? 今やっているのは↓で、 let image = NSImage(cgImage: cgImage, size: NSSize.zero) image.tiffRepresentation // nil この cgImage は↓のように生成されています。 extension Image where Pixel == RGBA { public var cgImage: CGImage { let length = count * 4 // count == width * height var data = Data(capacity: length) data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in // 略 } let provider: CGDataProvider = CGDataProvider(data: data as CFData)! return CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: width * 4, space: Image.colorSpace, bitmapInfo: Image.bitmapInfo, provider: provider, decode: nil, shouldInterpolate: false, intent: CGColorRenderingIntent.defaultIntent)! } fileprivate static var colorSpace: CGColorSpace { return CGColorSpaceCreateDeviceRGB() } fileprivate static var bitmapInfo: CGBitmapInfo { return CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue) } } tiffRepresentation のドキュメントには↓のようにありますが、特に PDF や EPS のようなベクター形式の representation にはなっていないと思います。 "if the TIFF data cannot be created" の原因がわからず・・・。 If one of the receiver's image representations does not support the creation of TIFF data natively (PDF and EPS images, for example), this property creates the TIFF data from that representation's cached content. This property contains nil if the TIFF data cannot be created. https://developer.apple.com/documentation/appkit/nsimage/1519841-tiffrepresentation なお、同様の手法↓で生成されたグレースケールの CGImage から作られた NSImage や、 PNG ファイルを読み込んで生成された NSImagetiffRepresentation は正しく動作します。 https://github.com/koher/EasyImagy/blob/05db8c28d034a36cef3a8271d2daa214c8ad5ee4/EasyImagy/ImageCoreGraphics.swift#L133-L147
EasyImagy - Makes it easy to deal with images in Swift
8:44 AM
Avatar
@koher まずいのはここだと思います。
10:55 AM
var data = Data(length: length) で初期化しないと、capacity あっても直接イニシャライズすると length は 0 のままなので。 (edited)
10:57 AM
それか、init(capacity:) で生成して、 data.length = length で拡張するか。← データ突っ込んだ後にやると 0 で初期化されるので注意 (edited)
😲 2
11:01 AM
あ、Data.init(count:) だ。 issue からリンクされているプロジェクトでは NSMutableData だった。
Avatar
NSMutableData(length:)で正常に取得できることを確認しました。
12:31 AM
僕もソースは読んでたんですがcapacitylength/countは盲点でした…… ポインタと合わせる場合は特に要注意ですね
Avatar
おおお、そんなところをミスってるとは・・・。完全に盲点でした・・・。ありがとうございます!!
1:06 AM
CoreGraphics と AppKit の方ばっかり調べて Data の使い方を間違えている可能性をまったく考えませんでした・・・。
Avatar
@rintaro おかげで fix できました!ありがとうございました。 https://github.com/koher/EasyImagy/pull/16
👍 1
Avatar
SwiftLintを0.22.0に上げるとデフォルトで2つ目のクロージャー引数に警告が出るようになりました。新しいルールの詳細はこのissueのようです。https://github.com/realm/SwiftLint/issues/1801
New Issue Checklist Updated SwiftLint to the latest version I searched for existing GitHub issues Rule Request In many cases, the trailing closure syntax can make code clearer by reducing boile...
7:25 AM
UIView.animate(withDuration: 1.0, animations: { someView.alpha = 0.0 }) { _ in someView.removeFromSuperview() }
7:26 AM
これを警告を出さずに同じことを0.22.0でも書こうとすると、どのように書くべきなのかわからず。
7:28 AM
アニメーションが完了した後の処理を2つ目のクロージャーで処理したいのに警告が出て困る。issueの作成者が言う、2つめのクロージャーの処理が曖昧だというのはラベルが省略されているからまだ理解できますが、多くの場合は不要と言っている意味がよくわからず。 (edited)
7:30 AM
なぜこのルールがデフォルトで警告になったのか…。 (edited)
Avatar
Deleted User 9/3/2017 7:49 AM
クロージャを2つ以上引数に渡す場合はTrailing Closuresを使わずに、分かりやすくちゃんとラベルを付けましょうってことですよね? UIView.animate( withDuration: 1.0, animations: { someView.alpha = 0.0 }, completion: { _ in someView.removeFromSuperview() } )
🙏 1
Avatar
ありがとうございます。2つ目のラベル名をいつも省略して書いてたので、ラベル名を付けたまま書くスタイルがわからず困ってました。ありがとうございました! (edited)
👍 3
Avatar
もう少しで iOS 11 の GM 版がリリースされそうですが、 GM 版でアプリを申請して審査に通った場合、 App Store から配信されるのはどの時点になるのでしょうか? 正式版がリリースされるタイミングですか?それとも GM 版 iOS が入った端末であれば審査に通った時点からインストールできるようになるのでしょうか? Deplayment Target は新しくリリースされるバージョン(今回であれば iOS 11 )を想定しています。 これまでに GM 版で申請した経験がないためよくわからず、ご存知の方がいれば教えていただけると助かります🙏
Avatar
@koher 過去のバージョンでiOSxx対応みたいなのがリリース前に出ていたのは覚えていて、それに習うなら配信されるのはリリース前も有り得ると思います。
👏 1
Avatar
なるほど。ありがとうございます!
Avatar
var dict1 = ["May 21": [1,2], "May 22": [3,4]] var dict2 = ["May 22": [5,6], "May 23": [7,8]] dict1.merge(dict2, uniquingKeysWith: +) print(dict1) // ["May 22": [3, 4, 5, 6], "May 23": [7, 8], "May 21": [1, 2]]
6:13 AM
uniquingKeysWith に + を書くことてswift4で可能ですか? (edited)
6:14 AM
Xcode9でやるとエラーになるのですが。
6:16 AM
あ、わかりました。valueの型が一致してないと駄目なのか、失礼しました。
Avatar
Pythonの基本がわかってDjangoを使っている程度の中学生がiOS+Swiftプログラミングに入門するにはまず何から始めたらいいでしょう。おすすめの書籍などあれば教えて欲しいです。Playgroundで学んでいける課題でも良いかなと思ってます。私は一応SwiftでiOSアプリの開発はできるので教えることはできると思うのですが、やはり教材があると教えやすいかなと感じてます。
Avatar
最初のGettingStartedなかなか良いですね。中2なので英語だとちょっと時間がかかるかもしれませんが。
Avatar
おっさんでも英語だと時間掛かる人いるし問題ないですよ
😅 1
Avatar
うーん、さすがに中2だと英語はきつそうな気もしますけどね〜。
Avatar
逆に学習の動機づけとしてはよいのでは
1:57 AM
目的が倒錯した
Avatar
塾講師してたとき高校入試の英語長文読みましたが、中学生当時難しいと思ってた英文が簡単すぎて
1:58 AM
日本語のように読めておどろいたので、中学のときの英語力って今の僕らの感覚からすると相当低いかと。
1:59 AM
動機づけとしては良いとしても、階段のステップが大きすぎると壁になって登れずに挫折してしまうので、日本語でカバーできる範囲はまず日本語がいいような気がします。
Avatar
中学校英語とは全く語彙が違うので最初は難しく感じそうですね
Avatar
Pythonは日本語の資料を参照した感じですか? @rizumita
Avatar
Pythonは日本語の資料ですね。
2:01 AM
Djangoの情報は日本語の情報が少なかったのですが、英語の資料を読むのは中1だったのもあって無理でした。
2:02 AM
@tarunon
Avatar
英語問題は結構難しいと思っていて、ドキュメントが日本語だとしてもクラス名、メソッド名とかが英語なので小中学生くらいだとそこに辛さがありそうです。僕が小4でプログラミングを始めたときは、変数名は a とか b とか付けてたので。概念自体は理解できると思いますが、(自然)言語の壁がありそうです・・・。
Avatar
僕が中学生の時はコンパイラと戯れて理解してたな、ドキュメント参照しようにもダイヤルアップだからそれすら難しかった
2:07 AM
自然言語による理解を諦めてコンパイラと戯れよう
Avatar
前に小3にSwift教えようとしたら、アルファベットの大文字は読めるけど小文字が読めないという事案が発生しました。
Avatar
ゴールとしてはiOSアプリ自体の開発ですか?
Avatar
なかなかiOSのアプリ開発を初級者向けに抑えた日本語の本って聞かないな あるのかもしれんけど
Avatar
Udemyとかだとそういうのもあるのかなぁ?
2:10 AM
↑ここにもいっぱいありそう 英語だけど
Avatar
あ、日本語初心者向けコンテンツが、ね。 (edited)
Avatar
@tarunon ゴールはiOSアプリの開発だと思います。
Avatar
やっぱり早く SWIFT QUEST を作らねば・・・。
Avatar
Swift QuestはiOSアプリなんですか?
Avatar
基本は iOS 関係なく純粋 Swift だけど、発展系として Playground + UIKit もできないかなぁとは思ってる。
Avatar
なるほど。
Avatar
おじさんたちはSwiftの楽しさに触れて欲しいけど本人の希望ではなさそう
2:13 AM
GithubあさってサンプルコードやらOSSやらこねくり回してスパゲッティでもいいから動くもの出来ると楽しいのかな
Avatar
手っ取り早く楽しさを体験できる環境としては、 Playgrounds はいい気がしますけどね。
Avatar
私もSwift学習始めたばかりなので、この話題はとても気になります。 Swift Playgroundsって日本語対応していたかと思うのですが、これって他言語経験者も学習対象になっている感じなのでしょうか。 私はあいにくiPadを所持していないのでやったことがないのですが、これが完全初心者でなくてもかなり参考になるようなら、ここから始めてみるのもありなような気がします。
Avatar
Swiftにも興味はあるみたいです。Python以外の言語もやってみたいという動機もあるみたいなので。
Avatar
やっぱりビジュアルだと楽しいし。
Avatar
iPadのSwift Playgroundsはどっちかというと ノンプログラマー向けに プログラミングの楽しさを伝えるって感じで
2:15 AM
開発者が言語学習目的でやるとダレるかもしれない?
Avatar
初めて FLASH + ActionScript 触ったとき、楽しすぎて大学にも行かず 3 日くらいずっとそれやってました。 < ビジュアルだと楽しい
Avatar
参考書として http://gihyo.jp/book/2017/978-4-7741-8730-3 この書籍は良さそうな気がしますね。これ進めるだけだと中学生には退屈そうかも?なので、補助として。
本書は,Swiftの言語仕様と実践的な利用方法を解説した入門書です。 Swiftは簡潔な言語ですが,その言語仕様を理解し,正しく使うことはけっして容易ではありません。Appleの公式ドキュメントをはじめとして,どんな言語仕様があり,それらをどのように使うかに関しては豊富な情報源があります。しかし,それらがなぜ存在し,いつ使うべきかについてまとまった情報があるとは言えません。本書は,読者のみなさんの「なぜ」や「いつ」を解消することにも主眼を置いています。 本書では,はじめにSwiftの標準的な機能を一通り解説し,続いて型の設計指針や非同期処理,エラー処理などの実装パターンを説明します。最後に,実践的なSwiftアプリケーションの開発を通じて,それまでに説明した機能と実装パターンの具体的な活用方法を示します。
Avatar
Playgrounds は、 Mac の方の意図でした。
Avatar
ああそこ紛らわしいんですよね さっき僕が言ったのは iPadアプリの「Swift Playgrounds」は、プログラミング学習ゲームの事です
Avatar
二つは違うもののようで、 Mac の Playgrounds と同じような機能を iOS アプリの方も備えているからさらにややこしい・・・。
2:18 AM
↓のゲームみたいなのは、 Swift Playgrounds のコンテンツの一形態である Playground Book の、 "Learn to Code" というコンテンツです。 https://www.apple.com/jp/swift/playgrounds/
Swift Playgroundsは、楽しくインタラクティブな方法でSwiftのコードの書き方を学べるiPad用のアプリケーションです。アプリケーション上で直接ロボットやドローンを動かすプログラムを作れます。
Avatar
息子が第1回try! Swiftと一緒にあった子供向けワークショップに参加した時に、MacのPlaygroundsで教材が作ってあって楽しく学べたみたいなので、ああいう教材でより深く学べたらいいなぁと思いました。
🙂 1
Avatar
あ、そうか、Swift Playgroundsの中の、あくまで1つのコンテンツだった。
Avatar
何歳くらいのときですか?結構小さくてもできるものですか?
Avatar
@koher 小6の時ですね。
2:21 AM
もっと小さい子もいました。スーパー小学生だったので、その子は参考にならなそうですがw
Avatar
iPadの方のPlaygroundsで実際のアプリのコーディングをやっているという人もいて、実際にやっている人から気軽にやれておすすめとも聞いているので、ちょっと気になっています。
Avatar
なるほど。小6くらいならできるかもですね😃 天才児は参考にならないですねw (edited)
2:23 AM
iPadは入力が苦行なので個人的にはオススメできないです。。。
Avatar
ソンソンさんはキーボード並用してましたね。iPadと。 (edited)
Avatar
iPadは持ってないので…
Avatar
MacがあるならMacでやるのが楽だと思います。
2:25 AM
Swiftの勉強なら、英語さえ読めれば公式の↓を読むのが早いと思います。 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html
2:25 AM
(iBooks版もあります)
2:26 AM
Read a free sample or buy The Swift Programming Language (Swift 4) by Apple Inc.. You can read this book with iBooks on your iPhone, iPad, iPod touch, or Mac.
Avatar
Mac向けにもああいうのを出してくれたらなやってみたいところです。 公式サイト見ながら、Playgroundでやっていけば良いのだとは思うのですが。 ちなみにiPadの方のPlaygroundsは入力補助が優秀で、あまりキーボードで打たなくてもいけるそうです。
Avatar
うーん、その辺りは感じ方に個人差があるかもです。僕は結構 iPad 版の入力補助がストレスフルでした・・・。
Avatar
やはり実際に触ってみないと分からないものですね。 日本語版の書籍と言うことなら、11月にSwift4の本がいくつか出るみたいですが、同シリーズのSwift3までの本を見てよさそうなのを見繕っておくというのもありでしょうか。
Avatar
たしかに、もうすぐ発売みたいですね。
Avatar
書籍は読んだことがないからわからないです😅
Avatar
私も読んだことがないので、書籍がいくつか出た頃に息子を書店に連れていくのが良いのかも?
Avatar
プログラミング初心者向けというのでなければ、↑で @masaichi さんが挙げていた「 Swift実践入門」はいいんじゃないでしょうか。
Avatar
僕は中学生の時ヨドバシカメラの技術書コーナーに行くのが好きで
2:41 AM
お小遣いが貯まると買ってた
Avatar
Swift実践入門は手元にあるので、Swiftに関してはそれを渡せばいいかもしれませんね。あとはiOSアプリの作り方の書籍を入手すれば。
Avatar
ドットインストールのiPhoneアプリ開発入門は、Xcodeの使い方を手っ取り早く知るには便利でした。 https://dotinstall.com/lessons/basic_iphoneapp_v3
iOSアプリの統合開発環境であるXcodeについて解説しつつ、簡単なアプリ開発の流れを見ていきます。
Avatar
@Puramu Xcodeだけじゃなく簡単なアプリの作成まで解説があるんですね。
Avatar
@rizumita Xcode上からプロジェクトを作ってシミュレータ上で動かすところまでの解説が動画であるので、個人的にはアプリ開発のイメージはつかみやすいなと思いました。
Avatar
問題はすぐに古くなってしまうことですねぇ☹
Avatar
古いのは残念なところ。
Avatar
一応 Xcode 9 で Swift 3.2 なら似たような環境で動かせる?
3:01 AM
ただ、問題が起きたときに初心者だと解決不能になりそうですね。
Avatar
私の場合、あえてXcode9でSwift4で同じように動かしてみましたが、問題なく動かせました。 バージョンが上がって暫くすると、最新バージョンに対応した講座がいつの間にか作られていたりするので、ちょこちょこ見てみるのも良いのかもしれません。
Avatar
なるほど。メンテされていて追従してくれるならいい感じそうですね。
Avatar
@Puramu それは良い情報。ありがとうございます!
Avatar
@rizumita 有料会員になると、もっと他の講座も見られるんですが、そちらだと実際にちょっと遊べそうなアプリ作成の例が結構あります。 有料講座も最初の数回は無料になっているやつもあるので、良さそうなのがあるのか先に見てみると良いと思います。
Avatar
@Puramu 見てみます!
Avatar
iBooksのApple Educationに日本語の教材があるみたいですよ。 https://itunes.apple.com/jp/author/apple-education/id939801385?mt=11
「教育者のためのリサーチアイデア集」、「Swiftによるアプリケーション開発:入門編」、「Swift Playgrounds: コードを学ぼう1&2」を含む、Apple Educationのブックをプレビュー、ダウンロード。
Avatar
おお、すごい。
Avatar
Apple Educationの「Swiftによるアプリケーション開発:入門編」の無料サンプルを閲覧または購入。このブックは iPhone、iPad、iPod touch、または Mac 上で iBooks を使って読むことができます。
Apple Educationの「Swiftによるアプリケーション開発:入門編」の無料サンプルを閲覧または購入。このブックは iPhone、iPad、iPod touch、または Mac 上で iBooks を使って読むことができます。
Avatar
@norio_nomura おぉそんなものが。ありがとうございます!早速ダウンロードしてみます。
Avatar
凄いです。私も後で見てみたいと思います。
Avatar
@tarunon #swift でちょいちょい話題に上がるboxingってなんすか
Avatar
えーっと、Swift2以前でstructをNotificationCenterに流せなかったときに
9:19 AM
class Box<T>って使いませんでした?まさにアレです (edited)
9:20 AM
これはコンパイラの中でboxingやってますよねということか
Avatar
そうそう
Avatar
わかり++
Avatar
値型はそのままだとメモリレイアウトも違うのでクラス型としての互換性はないので、AnyObjectへのキャスト時にラップするオブジェクトがいる。Swift3からコンパイラ側が勝手にBoxingしてくれるようになりました。
Avatar
omochimetaru 11/1/2017 9:20 AM
値型のオブジェクトを参照型のオブジェクトに包む事で、 JavaのListは、参照型しか格納できないので、 int とかが class Integer に包まれたりする ObjectiveC でも、 NSArray は参照型しか格納できないから、 NSValue で包む
Avatar
Java で intInteger
9:21 AM
って書いてたら @omochimetaru が。
Avatar
互換性のあるものだと、NSString, NSArray, NSDictionary, NSNumber, NSValue(もかな?)へ変換されて
9:21 AM
そうじゃないものは一括で、、SwiftValueなんすかね @omochimetaru @rintaro
Avatar
omochimetaru 11/1/2017 9:22 AM
ObjectiveCでは昔は [NSValue valueWithInt: 3] とかやってたけど、 iOS5ぐらいから @(5) って、アット丸括弧構文でboxingできるようになったとか、昔はあった
Avatar
昔の Java では↓みたいなことをしてて、 // Java List<Integer> list = new ArrayList<Integer>(); list.add(new Integer(42)); // boxing
Avatar
ははん
Avatar
omochimetaru 11/1/2017 9:22 AM
@tarunon これまでに見てきた感じだとSwiftの都合で必要になるやつは SwiftValueっぽいね
Avatar
今の Java はこれを自動でやってくれるから↓のように書けるけど( auto boxing )、あくまで自動なだけで boxing 自体は行われてます。 // Java List<Integer> list = new ArrayList<Integer>(); list.add(42); // auto boxing
9:23 AM
int に対して Integer をラッパークラスと言います。
Avatar
SwiftValueはObjcからは見えないSwiftに閉じた型の値?
Avatar
で、 Swift でも裏側で似たようなことをしているはずの部分を boxing と呼んでるけど、それが Java 由来なのか一般的な用語なのかは知りません。
👌 1
Avatar
SwiftValue、愚直に考えるならSwiftObjectのサブクラス
9:27 AM
SwiftObjectはNSObject互換で、動きを見る限りはサブクラスじゃないと思うけどObjective-C界から見たらNSObjectに見えそう。 (edited)
Avatar
SwiftValueとSwiftObjectは値型と参照型ってことではないのか、な
9:29 AM
サブクラスとのことだし
Avatar
さっきの C.self is AnyObject 問題があったから、 Swift の型システムとして表現したい世界と、 ObjC 互換のために現実的にどうなってるかとを区別して考えないといけないかも?
9:29 AM
おや、、、
Avatar
omochimetaru 11/1/2017 9:29 AM
struct S{} var s = S() print(type(of: s as AnyObject)) // _SwiftValue var f: () -> Int = { 33 } print(type(of: f as AnyObject)) // _SwiftValue ↑SwiftValueの例
9:30 AM
普段は見えないけど型名を動的に取得してprintすると出て来る。
Avatar
#if __OBJC__ @class _SwiftValue; #else typedef struct _SwiftValue _SwiftValue; #endif
Avatar
あー なんか見たことあると思ったらそれか
9:30 AM
こっちのほうが良さそう
9:30 AM
というか_SwiftValueはNSObjectのサブクラスじゃん
Avatar
なるほどー、 #if SWIFT_OBJC_INTEROP@interface _SwiftValue : NSObject <NSCopying> だから is AnyObject が Mac だと true になるんだ。 (edited)
9:33 AM
ん??
9:33 AM
それだと S.self でもそのはず?
Avatar
#swift じみてきた
Avatar
またわからんことがあったらここに書くのでまた教えてください
🙋 2
9:34 AM
ドラゴンは巣#swiftにおかえり
🍀 1
Avatar
少し話は戻りますが、JavaのListに参照型しか格納できないのってなんでですかね?
Avatar
omochimetaru 11/1/2017 9:36 AM
Genericsが型ごとに異なる実装を持てないからですね
Avatar
全部Objectとして持つのが前提じゃないかな
Avatar
omochimetaru 11/1/2017 9:37 AM
そうそう。List内部のストレージの実体が、ルートクラスのObjectの配列になってる。 (edited)
Avatar
つまり、Swiftっぽく示すと class List<T: AnyObject> {} これがJavaのListの定義
9:37 AM
本当はアブストラクトクラスだけど…
9:38 AM
後は型システムの制約とかあるはずだけど、そこは明るくないです。
Avatar
元々ジェネリクスもなくて、 class ArrayList { private Object[] elements; } こんな風になってたのを
9:38 AM
ジェネリクスを使って class ArrayList<E> { private E[] elements; } と書いているだけなので、
Avatar
omochimetaru 11/1/2017 9:39 AM
言語仕様としては、 int[] とか float[] みたいな、値型の配列も作れるんだけど、 List<int> のときにそれを内部で使わせる記法も仕組みもない あと、これは鶏卵だけど、ジェネリクスの型パラメータのところに値型が書けない・・・
Avatar
そもそも Java のジェネリクスが Object で持ってるのと同じです。コンパイル時に型チェックできるようになっただけで、実行時の挙動はジェネリクス以前と同じで Object です。
Avatar
Erasure ですからねぇ
Avatar
ジェネリクス以前の実装は参照型なら任意の型が入りうる感じですか?
Avatar
確か Java でも値型とか List<int> を導入する話が出てたような?
Avatar
なんか出来るようにするけどいつになるだろうみたいなのを聞きましたね
Avatar
@Yuta Saito そうです。 < ジェネリクス以前の実装は参照型なら任意の型が入りうる感じですか?
Avatar
危険だ。。。
Avatar
ListList<Object> と書いてるのと同じですね。
Avatar
omochimetaru 11/1/2017 9:42 AM
Javaコンパイラのその振る舞いをするモジュールが type erasure って名前 https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
Avatar
omochimetaru 11/1/2017 9:42 AM
To implement generics, the Java compiler applies type erasure to:
Avatar
Javaのジェネリクスは後付け仕様で、コンパイル時のエラーチェックしかできないから、ジェネリクス使ってたとしても、明示的にキャストすれば任意の参照型が入った気がします。
Avatar
Obj-C はつい最近までそういう状態でした。 < 危険だ。。。
Avatar
omochimetaru 11/1/2017 9:43 AM
危険だ。。。
AndroidがJava6を書いているころ、iOSでは NSMutableArray に ジェネリクスも何もなくやってたね
Avatar
全部 id 型
Avatar
@hironytic
明示的にキャストすれば任意の参照型が入った気がします。
そんな気もしたんですが、キャストでエラーになるような気もして自信が持てず・・・。
Avatar
omochimetaru 11/1/2017 9:44 AM
明示的にキャストすれば任意の参照型が入った気がします。
List<Integer> a = new ArrayList<Integer>(); List<String> s = (List<String>)(List<Object>)a;
😩 1
9:44 AM
たしかこんな感じのダブルキャストするとコンパイルできる
Avatar
さてここで
Avatar
omochimetaru 11/1/2017 9:45 AM
実行時に add した瞬間に runtime exception だった気がする。
Avatar
僕が [Int]() as? [String] これを嫌がる理由が
9:45 AM
runtime exceptionではないけどじゃばみを感じる
Avatar
Java だと↓のようなオーバーロードもできなかったはず。 int foo(List<Integer> list) { ... } int foo(List<Double> list) { ... }
Avatar
#java
Avatar
どちらも List なので。
Avatar
omochimetaru 11/1/2017 9:47 AM
できないですね、それがtype erasureの仕事・・・
Avatar
Kotlin とかもその制約を受けてて辛い。
Avatar
omochimetaru 11/1/2017 9:48 AM
コンパイル時にジェネリックパラメータについての型チェックができる、はそうなんだけど、型システムのかなり前段で行われちゃうんですよね (edited)
9:48 AM
Java5からJava4に型検査+ダウントランスパイルしてから実際のコンパイルするような感じ。
Avatar
うん、そんなイメージ。
Avatar
そうですね
Avatar
たしかにキャストでエラーになりますね。。。
Avatar
@omochimetaru ownershipっていつ入るんですか Swift5?
Avatar
omochimetaru 11/2/2017 5:02 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
5:02 AM
Swift5でやりたい事がここにかいてあって
Avatar
5.0か
5:03 AM
1年後か
Avatar
omochimetaru 11/2/2017 5:03 AM
Swift5の大きなテーマがABIなので、Ownershipもそれに引っ張られてABIに関するやつはやるぞって書いてある
5:03 AM
Memory ownership model. An (opt-in) Cyclone/Rust-inspired memory ownership model is strongly desirable for systems programming and for other high-performance applications that require predictable and deterministic performance. Part of this model was introduced in Swift 4 when we began to enforce exclusive access to memory. In Swift 5 our goal is to tackle the pieces of the ownership model that are key to ABI stability.
5:03 AM
pieces of the ownership model that are key to ABI stability.
5:04 AM
ABI安定性のカギとなるオーナーシップの一部分
Avatar
ABIの規格にownershipも含めとかないとってことか
Avatar
omochimetaru 11/2/2017 5:04 AM
ですね ABIは関数呼び出し仕様も絡むので
5:04 AM
shared引数ってどういう呼び出しになるのか、とか芋づる式に決めないといけない
Avatar
ふむふむ
5:05 AM
Rust-inspiredってことは今のうちにRustのownershipと戯れておくのは無意味じゃないってことでいいんでしょうか
Avatar
omochimetaru 11/2/2017 5:06 AM
むしろRustやっておくと楽勝だと思う
Avatar
ナルホディウス
Avatar
omochimetaru 11/2/2017 5:06 AM
Rustよりちょっと小さい仕様で入れようぜって感じだから。
5:06 AM
Rustの機能全部パクると使いにくくなっちゃうからSwiftでは使いやすさと安全性の両立できるラインにとどめようという方針
Avatar
Rust、ドキュメント一通り読んでサンプル動かして脳内インデックス作ったつもりだったけど全然難解すぎて脳が育たない
Avatar
ジェネリクスと関連型が同時に存在するところわからない
Avatar
Genericsと associatedType
Avatar
rustのGenerics protocolなら前に議論があった (edited)
Avatar
rust の type と Generics の話ですね @lovee
Avatar
失礼しました🙃
👌 1
Avatar
UITableViewCellを再利用するとき、styleがdefault以外の場合、皆さんどうしてますか? ① UITableViewCellのサブクラスをつくって、UITableViewにregisterする ② iOS6以前の方式で書く let cell = tableView.dequeueReusableCell(withIdentifier: "hogeCell", for: indexPath) ?? UITableViewCell(style: .subtitle, reuseIdentifier: "hogeCell") ③ その他 ただstyleが違うだけなのにイニシャライザだけ定義した、UITableViewCellのサブクラスつくるのが面倒なので良い方法があったりしないかな…と思った感じです。 (edited)
Avatar
Kishikawa Katsumi 11/7/2017 3:25 AM
よほどのことがなければ1がテッパンですね。
Avatar
やっぱりそうですか。
Avatar
omochimetaru 11/7/2017 3:26 AM
サブクラス作るのが面倒な時、サブクラス作るのが面倒な言語仕様がおかしいんだ!って気持ちを高めて頑張ってサブクラス書いてます。(そこで楽しようとすると型的に面倒な事があとあと起きてきがち (edited)
Avatar
Kishikawa Katsumi 11/7/2017 3:27 AM
ただstyleが違うだけなのにイニシャライザだけ定義した、UITableViewCellのサブクラス という気持ちはわかりますが、それで済むのはほんの最初のうちなので、結局セルの種類ごとにクラスで名前をつけるのがわかりやすいです。
3:27 AM
同じスタイルでも違う種類のセルなら違う名前のクラスにしたほうがいいです。
Avatar
納得、ありがとうございます!
Avatar
Kishikawa Katsumi 11/7/2017 3:30 AM
ちなみに indexPath を2番目の引数に取る dequeueReusableCell() はnilを返さないので、2の書き方はindexPath を取らない方のメソッドを呼ぶ必要があります。細かいツッコミですけど。
😱 1
Avatar
あ、そうですね、適当すぎました
Avatar
前のxcodeだとlinked frameworkで入ったフレームワークを左ペインでグループにまとめるとかしてましたけど 今のバージョンだとグループ作ってD&Dで移動すると実体が移動してしまう気がしてます。(New Group, New Group without Folder問わず) 何か方法あるんでしょうか?
Avatar
omochimetaru 11/9/2017 8:15 AM
わかる・・・俺諦めた。しまいたい。
😢 1
Avatar
norio_nomura 11/9/2017 8:38 AM
プロジェクトの直下に入ってしまう件?
Avatar
omochimetaru 11/9/2017 8:38 AM
直下に入ってしまって、それを、グループを作ってグループの中に隠そうとしても
8:38 AM
うまくいかない。
Avatar
norio_nomura 11/9/2017 8:40 AM
Embedded Binariesにいきなり入れると直下に置かれるけど、Linked Frameworks and Librariesに入れるとFrameworksの下に参照が作られるから、それをEmbedded~へ入れる様にしてる。
Avatar
omochimetaru 11/9/2017 8:41 AM
今度試してみます。
Avatar
Linked Frameworks and Librariesの+からやるとFrameworksってグループができてその下に入るんですね。これで耐えられそうです。ありがとうございます。
🎉 1
Avatar
Dictionaryのキーを変換して [Int: Any][String: Any] にしたいみたいなときってどう書くのが一番綺麗なんでしょう
Avatar
let source = [1: "1", 2: "2", 3: "3"] Dictionary(uniqueKeysWithValues: source.map { ("\($0.key)", $0.value) }) こう?
Avatar
おっ ためしてみる
Avatar
おそらく初歩な内容だと思われるのですが、質問させていただきます。 1. ボタンを押す 2. 「ダウンロード中」というUILabelをつけたUIViewを表示させる 3. ダウンロードタスクが始まる 4. そのダウンロードタスクが終了したときにUIViewを削除する という処理を行う場合、どのように書けばよいのでしょうか? 現在、以下のように書いているのですが、 @IBAction func tapDownloadButton(){ let uiView = UIView(frame: CGRect(x:0,y:0, width:100, height:100)) uiView.backgroundColor = UIColor.white self.view.addSubview(uiView) //このタイミングでビューを表示したいができない download() uiView.removeFromSuperView() } ボタンに紐づけられた関数tapDownloadButton()の処理が全て終わったタイミングでUIの処理が始まるためか、見た目上、UIViewが表示されずにダウンロードが終わってしまいます・・・
Avatar
Kishikawa Katsumi 11/18/2017 9:25 AM
@TetsuFe 期待した通りに動かない理由はお書きになった通りです。UIが更新されるためにはイベントループに処理を戻す必要があるので、一連のメソッドの間でaddSubview(_:)removeFromSuperView()をしてしまうと、結果としてビューが外された最後の状態でUIが更新されます。
9:27 AM
download()は同期的な処理ですか?最も望ましいと思われる解決はdownload()メソッドを非同期処理にして完了時点でコールバックを受け取れるようにして、addSubview(_:) を呼んでからdownload()、ここまでは同じで、removeFromSuperView()をダウンロード完了のコールバック内で呼ぶことです。
9:28 AM
それが難しければ、addSubview(_:)の直後に一度イベントループに処理を戻してUIを更新して、download()removeFromSuperView()を呼びます。
9:32 AM
view.addSubview(uiView) DispatchQueue.main.async { self.download() uiView.removeFromSuperView() }
9:33 AM
後者の方法はこんな感じですね。簡単ですけど良いコードではないのでオススメしませんが、元のコードがなぜ期待した通りに動かなかったのかはよくわかると思います。
Avatar
ありがとうございます。 丁寧な説明でとても助かりました。 downloadを非同期的な処理に変えてコールバックでremoveFromSuperViewを実行することで、期待通りの挙動になりました。 後者の方法は、なぜかうまくいきませんでしたが、これはダウンロードを行う関数が同期処理になっているためでしょうか?
Avatar
download関数がダウンロード処理を実行し即座にVoidを返すためだと思います
12:54 AM
処理の進捗や結果如何に関わらず、実行の次にreturn Voidですね
Avatar
@tarunon ありがとうございます。 なるほど、そういうことだとすると、納得できます。 まだ理解が追いついていないですが、結果的にどういう流れになっているかは分かりました。もっと勉強しないといけないですね。
Avatar
それぞれ別のassociatedtypeを持つprotocol A, B に適合したprotocol Cを作成した場合についての質問です。 protocol A, BそれぞれのassociatedtypeのTypeは同一なので、 struct適合時にはどちらか一つのみtypealiasを定義したいです。 しかし、protocol Cにてwhereで条件を書いても どちらか一方のprotocolに適合していないとコンパイルエラーが出てしまいます。。 この場合、何か策はあるのでしょうか? protocol A { associatedtype TypeA } protocol B { associatedtype TypeB } protocol C: A, B where TypeA == TypeB { } struct Hoge: C { // error: type 'Hoge' does not conform to protocol 'A' typealias Type2 = String }
Avatar
struct Hoge: C { typealias TypeA = String typealias TypeB = String } これなら通りますね。TypeAとTypeBが別々だと通らなくなるので同一チェックもされてるようです。
Avatar
そうですね、ただTypeAとTypeBを毎度同じ型を定義するのがしんどいので protocol Cを定義してTypeA == TypeBであることを担保しておき、C適合時にはどちらかのみ書けばいい状態にしたいです
Avatar
うーん、両方書かないと通らないですね。一応、実用的には↓のように何らかのメソッドがあると思うので、明示的に typealias を書かなくてもコンパイルは通ります。 protocol A { associatedtype TypeA func foo() -> TypeA } protocol B { associatedtype TypeB func bar() -> TypeB } protocol C: A, B where TypeA == TypeB { } struct Hoge: C { func foo() -> Int { return 2 } func bar() -> Int { return 3 } }
Avatar
protocol A { associatedtype TypeA } protocol B { associatedtype TypeB } protocol C: A, B { associatedtype TypeB = TypeA } struct Hoge: C { typealias TypeA = String }
Avatar
assoctypeの上書きできるんですね……
Avatar
where句を書くのはextension、protocolはassociatedtypeに制約を記述します
Avatar
おお、 C のそこ associatedtype になるんですね。 typealias で書いてエラーになってあきらめてました。
Avatar
同じく
Avatar
@t.ae そろそろRecursive Constraintsも来るので色々出来るようになりますよ
Avatar
レベル高い
Avatar
なるほど!
Avatar
個人的には逆をやりたいのですが出来なくて困っています
3:27 AM
protocol A { associatedtype E } protocol B { associatedtype E } struct C: A, B { typealias A.E = Int typealias B.E = String } これはどうあがいてもムリです。 (edited)
Avatar
associatedtypeで制約を書けばよかったんですね・・ @t.ae#5802 @koher @tarunon ありがとうございます!
Avatar
associatedtypeの 名前が かぶっちゃいけないってこと?
Avatar
associatedtypeの名前がかぶると同じ型にしかならない
3:28 AM
ネームスペース気にしなきゃいけなくなって苦痛
Avatar
わかる
Avatar
それひどい仕様ですね・・・。
Avatar
古き良きベンダープリフィクス
Avatar
プロトコルつくるときにはローカルな名前つけたいんだけど、あっちのあれとぶつかるかも、みたいな。
Avatar
Shitだ
Avatar
HogeProtocol.FugaAssocType みたいな書き方ができれば解決?
Avatar
そのあたりってどういう整理なんでしょう?たまたまそういう実装になってる?or意図的な仕様?
Avatar
#swift でよさそう
Avatar
#ios#beginner-help_archived か迷ったのですが、こっちで質問してみます iOS11のみで起きる CFNetwork URLResponse::guessMIMETypeCurrent(__CFData const*) のバグに苦しめられてまして、どなたか同じような現象に出くわした方いらっしゃいませんか。 MIMETypeについてなので、URLResponseをNSHTTPURLResponseにキャストしてMIMETypeの中身を見てるんですが、たまにnullが返ってくるのが問題かなと思ったのですが、iOS10や9でもnullで返ってくるので、特にこれが原因でクラッシュするわけではないような…。 ググっても同じような問題に悩んでいる人が見つからなかった…。 Crashed: com.apple.NSURLSession-work SIGABRT ABORT 0x0000000180ded348 -------------------------------------------- libsystem_kernel.dylib __pthread_kill + 8 CoreFoundation _CFRelease + 1252 CFNetwork URLResponse::guessMIMETypeCurrent(__CFData const*) + 1548 CFNetwork -[__NSCFURLLocalSessionConnection _tick_sniffNow] + 348 libsystem_pthread.dylib start_wqthread + 4
Avatar
コードが欲しい…
Avatar
ですよね
7:28 AM
しばしお待ちを
Avatar
objcのコードで辛い感じですが、マルチパートを自作してPOSTするメソッドです。
3.59 KB
Avatar
``` でくくってここに貼れませんか?
Avatar
それが長すぎて
Avatar
ならgistとかのほうがみんな見やすいと思います
Avatar
投稿できなかったのファイルになりました
7:41 AM
あ、確かに
Avatar
objcをシンタックスハイライトなしで見るのは大変なのでw (edited)
Avatar
すみません,
🙆 1
7:43 AM
これでどうでしょうか。
Avatar
どこでクラッシュしてるんだろ
7:46 AM
(objcだと思ってなかったw)
😭 1
Avatar
Kishikawa Katsumi 11/22/2017 7:46 AM
コードは問題ないように見えます。
Avatar
ちょっとわかんないですけど、構築してるリクエストに何かしらの問題があって、NSURL系のドライバが内部で死んじゃうんだと予想します
Avatar
レビューありがとうございます。たぶん、なんですがcrashlyticsにログは来てますが、クラッシュしてるわけではないようなんですが、iOS11のみログが送られてきてまして
Avatar
Content-Type: が multipart/form-data; のときって、 charset は要らないようなきがするのと
7:48 AM
Content-Length: が無いのが気になるけど
7:48 AM
クラッシュしちゃうほどのことでも無さそう・・・
7:49 AM
Content-Length: は NSURLRequestが勝手に付け足す気もするな。HTTPBodyに入れてるのがNSDataだし。うーん、なんだろう・・・
Avatar
なるほど、ちょっとそこを変更してみると、「構築してるリクエストに何かしらの問題があって、NSURL系のドライバが内部で死んじゃう」可能性を想定してもう一度コードを見てみます
7:50 AM
ありがとうございます
Avatar
Kishikawa Katsumi 11/22/2017 7:50 AM
guessMIMETypeCurrent だからContent-Typeを付け足してみて試すとか。
Avatar
あ、ほんとだ、含めてるオブジェクトの方が無いですね15行目あたり
7:51 AM
26行目のほうはContent-Typeついてるけど、こっちは画像添付で別フローだ。
Avatar
むむ
Avatar
Kishikawa Katsumi 11/22/2017 7:51 AM
再現できないと難しいので、再現方法を探りつつ、クラッシュがそれほど多くないのであれば、勘で色々な対策を通常のアップデートに紛れて入れていくくらいしか思いつかないですね。
Avatar
あ、いや、いいのか。こっちはFORM VALUEなのか
7:52 AM
https://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean POST / HTTP/1.1 [[ Less interesting headers ... ]] Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150 Content-Length: 834 -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="text1" text default -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="text2" aωb -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="file1"; filename="a.txt" Content-Type: text/plain Content of a.txt. -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="file2"; filename="a.html" Content-Type: text/html <!DOCTYPE html><title>Content of a.html.</title> -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="file3"; filename="binary" Content-Type: application/octet-stream aωb -----------------------------735323031399963166993862150--
What does enctype='multipart/form-data' mean in an HTML form and when should we use it?
Avatar
Kishikawa Katsumi 11/22/2017 7:52 AM
if (image){ のとこではContent-Type指定してあるんですね。
Avatar
↑のstackoverflowにMIMEなリクエストの例が載ってて、それと見比べてたんですけど、怪しいところみつけられず。
Avatar
みなさんの意見参考に、もうちょっと再現方法を探りつつ頑張ってみます。
Avatar
100%クラッシュなのであれば (edited)
Avatar
そこまで大きくないバグですが、iOS11のユーザーが増えつつあるので、気になる数にはなっています
Avatar
MIMEリクエストを行う他のライブラリをいくつかためしてみて
7:56 AM
自前実装では問題が起きて、他のライブラリなら大丈夫、ってところまでいければ
7:56 AM
実際に飛ばしてるリクエストを見比べて絞りこめると思います
7:57 AM
HTTPリクエスト内容とは全然違う制御系の部分のバグだったらダメですけど・・・ (edited)
Avatar
100%じゃないと真っ先にスレッド周り疑いたくなりますね
7:57 AM
非同期のタイミングで落ちる系のやつ
Avatar
なるほど・・・ライブラリと比べるのも手ですね
Avatar
100%ではないにしろSIGABORTなのでアプリクラッシュは起きてそう。
Avatar
そもそもの話になってしまうのですが、 CFNetwork -[__NSCFURLLocalSessionConnection _tick_sniffNow] + 348 でNSのプレフィックスが付いているのでobjcから呼ばれた通信でバグっているのはあっているのでしょうか?
8:00 AM
このメソッドは廃止予定のものなのですが、まだSwiftに置き換えられてないといった状況でして
Avatar
CoreFoundation _CFRelease + 1252 こっちじゃないかなあ
Avatar
Swiftから呼ばれていたとしても、内部は __NSCFURL... とかが動いてると思うんで
8:00 AM
ObjCから呼ばれてる通信が原因とは限らないかと。
Avatar
むーそうですか・・・。
Avatar
CFReleaseで落ちるってことはオーバーリリースだと思うので
Avatar
ObjcとSwiftが混在してるプロジェクトなのかな?
Avatar
生きてないといけないオブジェクトがリクエストの稼働中に消えちゃってるんじゃないだろうか
Avatar
オーバーリリースというのがあるのか
Avatar
リクエストではなくレスポンスに問題あるのでは?
Avatar
そうです、objcとSwiftが今のところ5:5てきな感じです
8:02 AM
生きてないといけないオブジェクトがリクエストの稼働中に消えちゃってるんじゃないだろうか
Avatar
@omochimetaru そのオーバーリリースってARCの環境でも起きるもんなんスカ
Avatar
むー、問題の特定が難しい
Avatar
@hiragram Swiftだとweakがあるから大丈夫だけど昔の ObjC だと弱参照じゃなくて生ポインタだから、Delegateがもう死んじゃってるとよくおきた
Avatar
CF某は自分でやってなかったっけ、あれはもうなくなった?
Avatar
After you create a task, you start it by calling its resume method. The session then maintains a strong reference to the task until the request finishes or fails; you do not need to maintain a reference to the task unless it is useful to do so for your app’s internal bookkeeping purposes. 大丈夫そうだなあ・・・
Avatar
Kishikawa Katsumi 11/22/2017 8:05 AM
確かにレスポンスの問題っぽいですよね。
Avatar
@omochimetaru オーバーリリースっていうとretain countが0なのにreleaseしようとしたっぽい感じに聞こえたけど、実際は解放済みのメモリにアクセスしたから落ちたってことかしら
Avatar
NSURLProtocol実装してたりします?
Avatar
@hiragram そうだね。実際は解放済みメモリへのアクセスが起きる。
🆗 1
Avatar
NSURLProtocolはつかってないです
8:07 AM
レスポンスの問題だとサーバー側にも何か原因があったりするのでしょうか
Avatar
Kishikawa Katsumi 11/22/2017 8:08 AM
コードは問題なさそうですし、100%起こらないというのもそれなら納得できるし、クラッシュのメソッドはURLResponseというオブジェクトのメソッドなので、何かレスポンスの処理なんでしょう。
8:09 AM
CFNetworkのコードを探したけどそのメソッドは見つかりませんでした。CFNetwork外か新しく追加されたものか。
Avatar
特に、responseに関しては、statusCodeを見るぐらいにしか使用していないつもりなのですが・・・。どこかでつかってるのかな。
Avatar
Kishikawa Katsumi 11/22/2017 8:09 AM
あ、いや、レスポンスの内容です。サーバーから返ってくるレスポンスのデータ。
Avatar
あ、なるほど
Avatar
再現性ないとなると、レスポンスデータのロード中の read の区切れ具合で運が悪いとクラッシュしたりとかありそう。
Avatar
雲をつかむような質問を投げてしまった。みなさんありがとうございます。もうちょっと色々、探ってみます。
Avatar
まあ逆に尻尾つかめたときには質問することはなくなってますからねだいたいw
Avatar
確かにw
Avatar
Kishikawa Katsumi 11/22/2017 8:15 AM
あ、場所がわかってるということなら、クラッシュレポートに、ここのコードに送信してる内容のログを含めるようにしたら再現に役立ちませんかね。レスポンスが動的だったらあまり意味はないかもしれませんが。
Avatar
ユーザーから、通信が切れるから困るみたいな問い合わせが増えてるわけではないので、本当にこのバグは起きているのか少し疑問でもあります。
Avatar
多分ですけどNSURLSessionのinternalで起きていてどのreq/resかすら掴めないのでは
Avatar
いい機会と捉えてSwiftに書き換えてみては
Avatar
Contribute to iOS9-SpringBoard-Headers development by creating an account on GitHub.
Avatar
なんかワーカースレッドがタスク探してディスパッチしそうなメソッド名だよね
Avatar
あ、すでに同じメソッドをSwiftに置き換えているのですが、最初のログでNSのプレフィックスがついてたから、objcの古いコードから起きてるのかなと、勝手に予測してしまいました。
Avatar
なるほど
Avatar
問題のありそうなところに、詳細なログを送るように色々しこんでみるしかないですね
Avatar
Crashlyticsのレポートってアプリのバージョンがいくつかって含まれてなかったでしたっけ
Avatar
含まれてまして、iOS11に対応したときから、このバグが出現しはじめてまして
8:22 AM
iOS11にアップデートしたユーザーが増えるにつれて、少しづつバグの件数が増加している感じです、まだそこまで多くないのですが。
Avatar
レポートが上がってきているバージョンのアプリは、上述のobjcからswiftへの置き換えをする前のものですか?
8:23 AM
kuroさんがおっしゃっているバージョンというのはiOSのバージョンのことかな・・
Avatar
あ、すみません。段階的にobjcからSwiftに移行してまして、iOS11に対応してバージョンのときぐらいに、このバグがで始めたと言った感じです。
8:26 AM
NSURLSessionのinternalで起きていてどのreq/resかすら掴めないのでは
8:27 AM
これもそのとおりで、どのリクエストでこのバグが起きているのか特定できていないので、通信するクラスに詳細なログを取れるようになにか手を打って、バグの再現に努めます
Avatar
1 はじめに Burp Suiteは、Webの脆弱性診断を行う製品です。 XSSや、その他の脆弱性であるreflectedやstoredのDOMベースの検査パターンを有しています。 今回は、この製品の機能のうちの一つであ […]
8:27 AM
↑こういうのを使って
8:27 AM
できるかわからないけど、リクエスト、レスポンスを、
8:28 AM
一個ずつ時間をあけてしか通さないようにプロキシを設定できれば
8:28 AM
落ちたときに、飛んでいたレスポンスが、捕捉できるかも。
Avatar
https://qiita.com/hiragram/items/195c7117fb6ebd50653e Charlesなら通信にブレークポイントを貼れますぞ〜!
この記事はSpeee Advent Calendar 2日目の記事です。 前日の記事はこちら [Ruby力を高めるためには標準メソッドを学べ...
Avatar
Burpでの通信の監視自体はやったことがあって、結構よかったです。
Avatar
手元で再現できてないと使えないのでは
Avatar
手元で再現できてないと使えないのでは
それはそう
Avatar
CharlesとBurpちょっとためして、手当たりしだい見てみます
8:29 AM
ありがとうございます
Avatar
URLSessionから実行中のtask一覧取り出せるけどあれは非同期だからクラッシュ時に埋め込むのは無理かなぁ
Avatar
URLSessionから実行中のtask一覧取り出せる
8:32 AM
知らなかったです、それも試してみます
8:32 AM
ありがとうございます
8:37 AM
大掛かりだけど、自前で実行中のreqをリストで持てるように改修して、クラッシュ時に全部取ってくるようにするのが確実な気がしますね。急がば回れです (edited)
8:37 AM
非同期でリストいじって死なないようにだけ注意しないとダメですけど
Avatar
なるほど・・・それを仕込んでリリースしてリクエストの特定をするのがまずは先な感じがしてきました。実装が大変そうですが、トライしてみます。
Avatar
サーバー側のログと照らし合わせて特定とか出来ないかな?
8:43 AM
もし可能ならそっちは今すぐ出来るかもしれない。 (edited)
Avatar
たしかに、iOS内でしかまだ問題を共有してなかったので、レスポンスが問題ならサーバー側のログにも当たってみます
Avatar
UIImage の↓の二つのプロパティは、ドキュメントを素直に読めば片方が nil のときはもう片方は nil でないということになると思うんですが、それは保証されているんでしょうか? var cgImage: CGImage? { get }
If the UIImage object was initialized using a CIImage object, the value of the property is NULL.
https://developer.apple.com/documentation/uikit/uiimage/1624147-cgimage var ciImage: CIImage? { get }
If the UIImage object was initialized using a CGImage, the value of the property is nil.
https://developer.apple.com/documentation/uikit/uiimage/1624129-ciimage
4:16 PM
たとえば、↓のようなコードは正当な(決して ! に失敗しない)んでしょうか?より良い書き方がありますか? if let cgImage = uiImage.cgImage { // `cgImage` を使う処理 } else { let ciImage = uiImage.ciImage! // forced unwrap // `ciImage` を使う処理 } (edited)
Avatar
if let ... else if let ... else fatalErrorの方が良さそう
Avatar
これで Playground で再現するのですが、 UIImage のインスタンスがあっても どっちも nil の場合はあるみたいですね let image = UIImage() switch (image.ciImage, image.cgImage) { case (let ciImage?, nil): print("ciImage: \(ciImage)") case (nil, let cgImage?): print("cgImage: \(cgImage)") default: print("none") } // none CIImage, CGImage において、 どちらかで init すると片方が nil になるとは書いてありますが、 それ以外の関係性が書いてないので
ドキュメントを素直に読めば片方が nil のときはもう片方は nil でないということになると思うんですが
これは少し憶測が入ってるかも switch で書いたのは単純に好みなのですが、 こっちの方が網羅性があるので CIImage, CGImage どっちかがあれば とう意味では読みやすいかなと思います
🙏 1
Avatar
おおお、ほんとだ、両方 nil になりますね・・・。
1:26 AM
それ以外の関係性が書いてないので
なるほど。 "If the UIImage object was initialized using a CIImage object, the value of the property is NULL." だけど、それ以外で NULL / nil にならないとは言ってないってことですね。
Avatar
もしかして UIImageinit() ってObj-C の NSObject 由来で、 public に使われることは想定されてないんでしょうか?ドキュメントにも記載されてない・・・。 https://developer.apple.com/documentation/uikit/uiimage
Avatar
確か昔のとあるプロジェクトで空のイメージを UIImage() 作って渡してた記憶が…
1:56 AM
ああ確か何かのUIKitコンポネント作って、ボタンか何かの設定の時に nil 渡すとデフォルト画像が使われちゃうので UIImage() で渡してたはず、なんのコンポネントかは忘れたけど
Avatar
UINavigationBarのshadowImageあたりとかそんな感じ
Avatar
なるほど、普通に使用することがあるんですね。
2:15 AM
とりあえず↓のような感じになりました。 extension Image where Pixel == RGBA<UInt8> { public init(uiImage: UIImage) { #if os(iOS) || os(tvOS) if let cgImage = uiImage.cgImage { self.init(cgImage: cgImage) } else if let ciImage = uiImage.ciImage { let context = CIContext() // This `guard` can be replaced with `!` if you are sure that the `createCGImage` below never fails. guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else { fatalError("Failed to create a `CGImage` from an internal `CIImage` object from this `UIImage` instance: \(uiImage)") } self.init(cgImage: cgImage) } else { // This `gurad` can be replaced with `assert` if you are sure that the `size` is always equal to `.zero`. guard uiImage.size == .zero else { fatalError("The `size` of this `UIImage` instance (\(uiImage)) is not equal to `.zero` though both `cgImage` and `ciImage` of the instance are `nil`.") } self.init(width: 0, height: 0, pixels: []) } #else if let cgImage = uiImage.cgImage { self.init(cgImage: cgImage) } else { // This `gurad` can be replaced with `assert` if you are sure that the `size` is always equal to `.zero`. guard uiImage.size == .zero else { fatalError("The `size` of this `UIImage` instance (\(uiImage)) is not equal to `.zero` though `cgImage` of the instance is `nil`.") } self.init(width: 0, height: 0, pixels: []) } #endif } #if} else if ... { を落とすことができなくて悲しい・・・。
2:17 AM
そして、 CoreImage 使ったことなかったんですが、↓を発見して頭を抱えてます😂
Initializes an image of infinite extent whose entire content is the specified color.
https://developer.apple.com/documentation/coreimage/ciimage/1437947-init
(edited)
Avatar
大きさが規定されない場合はfatalErrorにするか、引数を追加して大きさも同時に指定したらvalidというAPIにするのが良さそう (edited)
Avatar
public init(uiImage: UIImage, clampedTo rect: CGRect? = nil) とかはありかもしれないけど、 fatalError が順当そう。
Avatar
確かにそれっぽい気が
UINavigationBarのshadowImageあたりとかそんな感じ
Avatar
先日、ここでiOS11のみで起きる CFNetwork URLResponse::guessMIMETypeCurrent(__CFData const*) のバグを質問したものですが、バグの解消できました!いろいろアドバイスくれた方々、本当にありがとうございました!いろいろ対策をしたのでどれが解決になったのかわかりませんが、おそらく URLSessionをsharedで呼べばいいのに不要にConfigurationを組み立てたり、奇妙なタイミングで finishTasksAndInvalidate している通信クラスがあり、そいつが原因だったように思います。お騒がせしました! (edited)
🎉 3
Avatar
iOS11でAppStoreのアプリのアップデートが手動で取らないとうまく出なかったりすると思うんですが、作成したアプリを強制バージョンアップしたい場合にStoreへ飛ばしてもアップデートへ遷移して手動で引っ張るみたいな事しないといけないといけないと思うですが これを回避してアップデート正常に出す方法とかありますかね?
Avatar
アップデートタブではなく、アプリ自体のページに飛ばしてしまえばいいのでは?
Avatar
アプリ自体のページに飛ぶとまだアップデートになってないから結果 アップデート→引っ張るってなってしまうんですよね かつアプリのページは引っ張ってもプルリフレッシュしないできなという。。。 (edited)
Avatar
iOS11で仕様どうなったかわからんですけど、以前なら個別ページが最速でアップデート表示されてたような?(記憶違い?
2:57 PM
仕様とか変わってたらわからんすなー😑
Avatar
iOS11からですね。AppStoreの更新の動きがおかしくなったのは😂
Avatar
もしかして段階的appdateの設定がonとかでしょうか?
Avatar
にはしてないですね。 http://sbapp.net/appnews/app/upinfo/ios11/app-store-8-72913 この現象の時に引っ張れば既に出る状態だけどアプリページに飛ばすとアップデートボタンになってないから更新できないって感じです
これまでApp Storeでアプリをアップデートするには、アップデート画面を開くだけでアップデートのあるアプリが表示されていましたが、iOS11ではアプリのアップデートの確認方法が変更され、アップデート画面を開いただけではアプリが表示されず...
Avatar
力技でやるなら、アプリ自体のページ情報からversion取ってきて、今のversionと比較して大きかったらStoreに飛ばす あーこれでも、結局ストアに飛んだらアップデートになってないやんけーってなる場合もあるか… (edited)
Avatar
たぶんそうなりますね。。。。
Avatar
超力技でやるなら、リリースした翌日とかの確実にアップデートがきてるタイミングで、サイレントプッシュとかを使って強制アップデート (万策尽きたので、他妙案、正攻法ご存知の方お願いします🙇 (edited)
Avatar
はじめまして。未使用のメンバ変数 (グローバル変数?)を検出することは出来ないでしょうか?よく消し忘れてしまうので自動的に見つけられると嬉しいのですが 😱
7:05 AM
自分なりに探したところ、今はその機能がなさそうなのでライブラリやAppCodeのプラグインを使うしかないのかなと思っています https://bugs.swift.org/browse/SR-3721
Avatar
Swiftlintの導入をオススメします。 Build scriptに swiftlint autocorrect と書いておけば、autocorrect可能なルールについてはビルド時に修正されます。 https://github.com/realm/SwiftLint/
SwiftLint - A tool to enforce Swift style and conventions.
7:08 AM
単純にwarningだけでよければ、swiftlint と書けばwarningが出ます。僕はautocorrectしたあとに再度swiftlintを呼びます
Avatar
omochimetaru 12/5/2017 7:09 AM
[omochi@omochi-iMac tt]$ cat a.swift let a: Int = 3 let b: Int = 2 print(b) [omochi@omochi-iMac tt]$ swiftlint Linting Swift files in current working directory Linting 'a.swift' (1/1) /Users/omochi/temp/tt/a.swift:1:1: error: Identifier Name Violation: Variable name should be between 3 and 40 characters long: 'a' (identifier_name) /Users/omochi/temp/tt/a.swift:3:1: error: Identifier Name Violation: Variable name should be between 3 and 40 characters long: 'b' (identifier_name) Done linting! Found 2 violations, 2 serious in 1 file.
7:09 AM
@d_date 未使用グローバル定数は検出されなかった
Avatar
マジか
7:11 AM
完全
7:11 AM
にいける頭でいたわ。失礼しました🙇‍♀️
7:13 AM
そっかーと思ってググってたらこんなのみつけた https://bugs.swift.org/browse/SR-3721
Avatar
欲しいよねこの機能、作ったけどいらなくなったメソッドとかも消したい
🙏 2
Avatar
omochimetaru 12/5/2017 7:14 AM
ローカル変数であれば未使用のものを見つけてくれるけどグローバルやメンバは反応しないなあ
Avatar
メンバはinitializerと絡むからあんまり困ってないな。
Avatar
omochimetaru 12/5/2017 7:17 AM
Xcodeの左のペインの左から3番目のタブを開いて
7:17 AM
Hierarchical表示にした上で
7:18 AM
下部の [C] のチェックを外すと
Avatar
おおー!
Avatar
omochimetaru 12/5/2017 7:18 AM
Classes Protocols, Functions, Structs, Unions, Enums, Types, Globals と
7:18 AM
シンボル種類ごとに整理されたツリーが表示されるので
7:18 AM
ここからGlobalsを開いて
7:18 AM
目で一個ずつ確認する・・・とか・・・
Avatar
OSSのも出てくるの、絞りたい…
Avatar
omochimetaru 12/5/2017 7:20 AM
現在のモジュールだけに絞り込みたいけど見当たらんなあ
Avatar
Prefixついてるの多いし、まだなんとかなるか。それでもターゲットの数だけ重複してでちゃうのね
7:23 AM
同じファイルを複数のターゲットに含めてる、という意味ね
Avatar
皆さん、ありがとうございます。 @d_date SwiftLintは使ってましたが、SwiftLintで出来ないと改めてわかったのはありがたいです🙏
7:28 AM
@omochimetaru この機能は触ったことなかったです。 試してみます、ありがとうございます!
🙂 2
Avatar
改めてプロジェクト見渡したけど、自分が書いたグローバル変数は1つもなかったので勘違いしたっぽい🙃
🐧 1
😆 2
Avatar
今のところ、その変数を右クリックして、 Find Call Hierarchyで呼ばれてる?ところが出て来るので、それで探してみるのがいいかなと思いました (edited)
Avatar
omochimetaru 12/5/2017 7:30 AM
@available(*, unavailable) let a: Int = 3 print(a)
🙏 1
7:30 AM
こうやって、 @available(*, unavailable) をつけてみると
7:30 AM
使っていればエラーになるので
7:31 AM
エラーが出なければ不要ってわかりますよ
Avatar
@d_date レビュアーの方にもグローバル変数はそもそもゼロを目指してほしいと言われました
7:32 AM
@omochimetaru おお!試してみます!ありがとうございます
Avatar
全部まずは@available(*, unavailable)つけて、エラーが出たものを@available(*, deprecated)に置き換えて残ったものを消す、deprecatedは使ってる箇所でwarningになるのでグローバル変数を減らしていく、とするとうまくいくのかな
Avatar
お〜確かにエラーになりました
Avatar
@tarunon それはとても良さそうです コミットする前はそうやって確認してみます! ありがとうございます🙏
Avatar
特定のViewの高さとか色とか、そういうのは定数で管理すると良いので然るべき場所で管理したいですね。レビュアーの方と相談してみると良いと思います。
Avatar
あ、たしかに定数はいいと言われました。丁寧にありがとうございます 〜
Avatar
使ってないメソッド問題は確かになんとかしたい
Avatar
Coverage?で出てくるみたいですが、これだとTest走らせないといけないし、全部のクラス見て回るのも面倒ですね
12:36 PM
試してみました
Avatar
https://bugs.swift.org でも https://bugreport.apple.com でも、どんどん要望あげましょう。
Avatar
norio_nomura 12/5/2017 1:07 PM
XcodeのFind Call Hierarchyがどの様にSourceKitを使っているか観察する事で、全てのグローバルメソッドの利用状況をチェックするツールを作れないか?と思ったのだけど、想像以上にめんどくさそうだった…
🙏 1
1:08 PM
オープンソースになっていないSourceKitの機能が使われてるし。
Avatar
ちなみに Xcode の Build Settings > Apple LLVM 9.0 - Warnings - All languages に GCC_WARN_UNUSED_FUNCTION GCC_WARN_UNUSED_LABEL GCC_WARN_UNUSED_PARAMETER GCC_WARN_UNUSED_VALUE GCC_WARN_UNUSED_VARIABLE っていう設定がありますが、 Swift には効かないです。
Avatar
Swiftは効かないんですね。。。残念(´・ω・`)
Avatar
初めまして、teratailに質問を投げたのですが回答がつかず涙を流しております 環境はxcode7.3.1、swift2です 助けていただけましたらありがたいです>< 何卒よろしくお願いします https://teratail.com/questions/103813
swiftでiOSアプリの開発をしているのですがBackボタンでの画面遷移がうまく行かず困っております。 画面遷移Aから順に画面遷移していき、C’でBackボタンを押した際にBに遷移させたいと思っています。また、BでBackボタンを押した際にはAに戻したいと思っています。EからC'に遷移
😢 1
Avatar
ありがとうございます!試してみます!!
Avatar
正規表現で半角@だけ通したいのに、パターンマッチで@の全角半角が区別されてないのって仕様なんすかね?
Avatar
最近話題のメールアドレスの正規表現かな
Avatar
まさにそれ…
Avatar
パターンマッチで@の全角半角が区別されてない
なんかunicodeの同じような文字同じとみなすモードみたいなのになってそう
3:05 AM
半角 aと 全角 みたいな。 (edited)
🤔 1
Avatar
Swiftがそういう風にみなしてる可能性があると…
Avatar
正規表現はNSですよね?
Avatar
です
3:23 AM
だからiOSがそもそも?というかApple全般で同じか (edited)
Avatar
[dc] 的な
Avatar
let stringA = "123@456" let stringB = "123@456" let rangeA = stringA.range(of: "@[0-9]", options: .regularExpression, range: nil, locale: nil) //.some let rangeB = stringB.range(of: "@[0-9]", options: .regularExpression, range: nil, locale: nil) //nil .range ならNS通らなくて済むからできそうですね
Avatar
おー。良さそう。ありがとうございます🤗
Avatar
山田パーだ!
Avatar
えっ、Stringの下請けもNSRegularExpressionではないのか??
Avatar
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
6:20 AM
OpenSource版ですけど調べてみたら
6:20 AM
range(of:options:range:)は、最終的に内部的には NSRegularExpressionを呼び出していました。
6:20 AM
internal func _rangeOfRegularExpressionPattern(regex pattern: String, options mask: CompareOptions, range searchRange: NSRange, locale: Locale?) -> NSRange { var matchedRange = NSRange(location: NSNotFound, length: 0) let regexOptions: NSRegularExpression.Options = mask.contains(.caseInsensitive) ? .caseInsensitive : [] let matchingOptions: NSRegularExpression.MatchingOptions = mask.contains(.anchored) ? .anchored : [] if let regex = _createRegexForPattern(pattern, regexOptions) { matchedRange = regex.rangeOfFirstMatch(in: _swiftObject, options: matchingOptions, range: searchRange) } return matchedRange }
6:23 AM
↑呼び出し方としてはこの通りなので、 regexOptions と machingOptions は、 mask 引数で決まってて、
6:23 AM
これは @lovee さんのサンプルだと .regularExpression しか与えてないから (edited)
6:23 AM
謎になった
6:24 AM
@ありぜ さんが元々書いた NSRegularExpression はどんなコードだったんでしょう?
Avatar
@omochimetaru こんなメソッドで判定してますね func isValidEmailFormat(string: String) -> Bool { let emailReg = "[a-zA-Z0-9._%+-/:~$^()&!']+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" let predicateMail = NSPredicate(format:"SELF MATCHES %@", emailReg) return predicateMail.evaluate(with: string) } (edited)
8:12 AM
hoge@gmail.comでもhoge@gmail.comでもtrueになる
Avatar
NSPredicate(format:"SELF MATCHES %@", emailReg) おおNSPredicate式だ
8:14 AM
func isValidEmailFormat2(string: String) -> Bool { let emailReg = "[a-zA-Z0-9._%+-/:~$^()&!']+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" // valid regexp let regexp = try! NSRegularExpression.init(pattern: emailReg, options: []) let nsString = string as NSString let matchRet = regexp.firstMatch(in: string, options: [], range: NSRange.init(location: 0, length: nsString.length)) return matchRet != nil } isValidEmailFormat2(string: "aaa@aaa.com") isValidEmailFormat2(string: "aaa@aaa.com")
8:15 AM
これでうまくいくようです
8:15 AM
NSPredicateよりNSRegularExpressionのほうが標準的だと思います。
Avatar
@omochimetaru .init は消せそう。
Avatar
コードレビューはいった
Avatar
最近は.init書く派です
Avatar
あえてなのか。
Avatar
というかxcode補間が安定する (edited)
Avatar
それはある < 補間が安定
8:16 AM
補間してから消す派
Avatar
左辺に型書いて = 書いて 右辺に .init ってのが最近のお気に入りです 安定する
Avatar
[a-zA-Z0-9._%+-/:~$^()&!']. と (最後の)- をエスケープしないと意図とちがうことになりそう (edited)
Avatar
左側で型推論、オシャンティーだけど引数とか返り値になった時に型が見えにくくなるのが弱点
Avatar
// valid regexptry! にかかってるのか
Avatar
はい > try!
Avatar
個人的にはこれ表示するのはIDEの仕事だと思ってるけど、JetBrainsはAppCodeに実装してるのかな
Avatar
ただなんか一部 .init だとだめなケースがあるんだよね rawValue enum で
Avatar
>rintaro ですね…前任者が適当だから(責任逃れ
Avatar
あー古い稼働コードなのか
8:19 AM
NSRegularExpressionに変更して他にも挙動の変化があるとアレですね
8:19 AM
まあでも ↑ で出てた String.range... にしても内部では結局これになってます。
Avatar
プロジェクト的には弄るの難しいかもだけど、自分の知見としてありがたい話だったので助かりました。ありがとうございます😊 (edited)
😃 1
Avatar
左辺に型書いて = 書いて 右辺に .init ってのが最近のお気に入りです 安定する
わかる、最近この書き方気に入ってる
🙂 1
🤗 1
Avatar
良さそなので暫く真似してみる
Avatar
FirebaseのRTDBやFirestoreをSwiftで使う場合に既にDictionaryになって値が取得出来るかと思いますが、既にDictionaryになってしまっている値でCodableを簡潔に使える方法無いですかね? すぐに思いついて簡単なのは JSONSerialization で一度 Data 化してから JSONDecoder を利用する方法かなと思いますが JSONDecoder 内で JSONSerializationDictionary というか Any 化されてるんですね。 https://github.com/apple/swift/blob/5836ea4d11ff5eb66f9c74ec1c0202585a467a9d/stdlib/public/SDK/Foundation/JSONEncoder.swift#L1060 なんか非効率だなーと感じるので、他に良い方法があれば知りたいです。最悪 JSONDecoder を丸々コピって DictionaryDecoder みたいなものを作る事になるのかなと思うんですが JSONDecoder が同じ処理をしてると思うとそれも非効率に感じます。。
swift - The Swift Programming Language
Avatar
@かっくん 同じことを思ってました。 [String: T] where T : Codable に encode/decode するライブラリとかあるといいのになと思います。
2:06 AM
ただ、僕は Codable にあまり詳しくないので、何かいい方法があるかもしれません。 @norio_nomura さんとか詳しそうです。
Avatar
以前何かその手の、ObjectEncoderみたいなのが出てきた気がする
2:07 AM
Codable DictionaryあたりでDicordを検索すると出てくるかもしれません (edited)
Avatar
ObjectEncoder - Swift Encoders implementation using [String: Any], [Any] or Any as payload.
👌 1
Avatar
norioさんだった・・・
Avatar
さすがだ。。w
Avatar
まさにこれっぽい
Avatar
試して見ます!ありがとうございます! @koher @tarunon @omochimetaru
👍 1
Avatar
まさに ObjectEncoder 使わせてもらおうとしたんですが、
2:57 AM
JSONEncoder.DateEncodingStrategyに相当するものが無いのに気づき
2:58 AM
結局 JSONEncoder.swift を本家からコピーして適当にリネームして (edited)
2:58 AM
Anyを食わせるようにしてしまいました。。
Avatar
特定の型のエンコード戦略の変更をエンコーダー側でサポートしないと注入できないの微妙なんですよね
3:00 AM
キーのsnake_case化の機能もJSONEncoderに入りそうだけど、JSONにかぎらずニーズありそう
3:00 AM
(って話をのむらさんがそのPR上で投げてたけどJSON固有の話だし〜みたいな感じになってた
Avatar
えー
Avatar
このへんの流れですかね
3:08 AM
(メーリングリストの正しいリンク先がわからない・・)
3:11 AM
PRがすでにあった
3:11 AM
In some cases, it's possible to have a Foundation object (either NSArray or NSDictionary) that produce a valid JSON. The current implementation of JSONDecoder allows decoding only from Data. This p...
3:13 AM
↑これです
3:14 AM
(メーリングリストの正しいリンク先がわからない・・)
そろそろフォーラムに移行されるからわからないままで大丈夫!w
😀 1
Avatar
ぬ、やっぱりDateEncodingStrategyとか要りますかね。僕の用途では不要だったので付けなかったのですが…
Avatar
PRの流れ
Avatar
僕の場合は、既存コードのAPIレスポンス処理部分を部分的にCodable対応して行こうと思い、特定のkey以下をJSONDecoderでデコードさせたかった、という用途でした (edited)
Avatar
そのまま使うとDate型のオブジェクトがそのまま入るんじゃなくて、Date型自体のencodeメソッドのデフォルトの挙動ベースで、 DictionaryだかArrayだか + パラメータの形になっちゃうのかな?
Avatar
DateDecodingStrategyの方か。
Avatar
そうですね、たしか2001/1/1 originでDateが作られるんだったかな
Avatar
オフセット秒数になるのか・・・
Avatar
DateDecodingStrategy .deferredToDate 扱いか (edited)
Avatar
StringからDate?を作るメソッドを指定できる仕組みがあれば良いのかな?
4:05 AM
あいやAnyからか。
Avatar
JSONDecoderはstrategyによって、生成方法を指定できるようになってるみたいですね
4:20 AM
そっか iso8601 だとStringからDate、になるんか (edited)
Avatar
お、keyEncodingStrategyとかも既にSwift 4.1に入ってるのか。 import Foundation let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase
😍 1
Avatar
ObjectEncoderで任意の型にCoding Strategyを設定できる様になりそう。 https://github.com/norio-nomura/ObjectEncoder/pull/11 var encoder = ObjectEncoder() encoder.encodingStrategies[Date.self] = .iso8601 let encoded = try encoder.encode(Date(timeIntervalSince1970: 1000)) encoded == "1970-01-01T00:16:40Z" // true var decoder = ObjectDecoder() decoder.decodingStrategies[Date.self] = .iso8601 let decoded = try decoder.decode(Date.self, from: encoded) decoded == Date(timeIntervalSince1970: 1000) // true (edited)
Add ObjectEncoder.EncodingStrategy and ObjectDecoder.DecodingStrategy that creating strategy Add ObjectEncoder.encodingStrategies and ObjectDecoder.decodingStrategies th...
👏 3
Avatar
おお、型をキーに。
Avatar
やったーあとで試してみます!
Avatar
Swiftでフレームワークを作っています. フレームワーク内で,自分で作ったObjective-Cのクラスを使うには,どうすればいいですか? Swiftでアプリケーションを作っているときは,bridge-headerを使って,そこにObjective-Cのヘッダファイルをインポートすればいいのはわかるのですが・・・. フレームワークでは,bridge-headerがサポートされないので困っています・・・・.
4:40 AM
っていうか,前にも同じところでハマった気がする
Avatar
modulemapこねこねしたんだっけ、、、
Avatar
同じことちょうど昨日はまって、おもち先生からはフレームワーク分けたら?と (edited)
Avatar
フレームワークからCommonCrypto.hを参照したくて困ったことがありますが解決しなかった
Avatar
moulemap で module 作るのもいけるとのことだけど、詳細は追えてない
Avatar
システムヘッダーかフレームワーク内のヘッダーなのか、で違って来ますね。
Avatar
既に閲覧済みかもしれませんが、
4:57 AM
It's already 2 years of Swift and its interoperability with Objective-C as well. When app extensions were released we've got a way to share our code across targets using frameworks. I used to build lots of frameworks since then, sometimes I even worked full-time just on frameworks. But as I
👏 1
Avatar
mixed-swift-objc-framework - Shows how to mix Swift and Objective-C code inside a framework target
5:06 AM
これが参考になるかも。
Avatar
Kishikawa Katsumi 12/16/2017 5:14 AM
インポートしたいライブラリ用のmodulemapを作るのがオーソドックスな方法ですね。相手がどんなライブラリかにもよるのでサンプルプロジェクトかそのものを見せてもらえたら解決しますよ。リモートでやるには情報が足りない。最低限何のライブラリをリンクしようとしてるかが必要です。 @sonson
Avatar
フレームワーク内で,自分で作ったObjective-Cのクラスを使うには,どうすればいいですか?
「自分で作った」、だから、CommonCryptをリンクするようなパターンじゃなくて、自作のライブラリがSwiftとObjC両方のソースを抱えてるパターンの話な気がしますね。
Avatar
Kishikawa Katsumi 12/16/2017 5:20 AM
ああ、なるほど。ちゃんと読めてなかったですね。それなら上におもちさんが貼ったリンクのプロジェクトが参考になると思いますね。
5:21 AM
そのプロジェクトで説明すると、
5:25 AM
1. ライブラリのディレクトリ Foo を作って 2. module.modulemap ファイルを作って、アンブレラヘッダー( <Foundation/Foundation.h>のようなもの)を作って参照できるように書く module Foo { header "../Foo.h" export * } 3. SWIFT_INCLUDE_PATHSにモジュールまでのパス(Fooディレクトリまでのパス)を設定する 4. import FooできればOK
5:26 AM
っていうのが基本です。そのFooライブラリがさらにStaticライブラリに依存してるとかだとmodulemapにリンクの設定とかが必要になります。
5:27 AM
ライブラリの書くクラス等はアンブレラヘッダーでimportしておきます。アンブレラヘッダーがブリッジヘッダーのような役割をしますね。
🙏 2
Avatar
SwiftPMとの共存に困る場合があるのでmodule.modulemapは極力使わない様にしてる。SwiftPM対応しないなら関係ないけど。
Avatar
ただいまー
5:55 AM
みなさんありがとうございます
5:56 AM
modulemap,なんだか面倒だなぁ・・・・.
Avatar
modulemap によって C言語の #include の世界が シンボルベースの世界に変換されて
5:57 AM
健全な時代になりそうで僕は好き
Avatar
自動でやってほしいw
Avatar
Xcodeは適切に設定すればビルド時にmodule.modulemapを自動生成します。 (edited)
Avatar
includeするけどライブラリとしてはexportしない、とか細かい制御ができるっぽいですよ、modulemapのところで
Avatar
Kishikawa Katsumi 12/16/2017 5:59 AM
あ、よく考えたら自分で作ったフレームワークをインポート、ってことだからインポートする側じゃなくてされる側のObjCフレームワークの方で設定すれば簡単だ。
5:59 AM
野村さんのいう通り。
Avatar
される側です
6:00 AM
すみません,それはどのドキュメントを読めばよいでしょう・・・・・か,サンプルか
Avatar
Kishikawa Katsumi 12/16/2017 6:01 AM
RealmSwiftがRealmをインポートしてるのと同じ関係なので、ちょっと大きいけどRealmのプロジェクトを見るとわかりますよ。
Avatar
ドキュメントは知らないです。経験として知ってるだけ。
Avatar
あう・・・・
Avatar
Kishikawa Katsumi 12/16/2017 6:01 AM
Realmはmodulemapを自動生成じゃないけど、逆に仕組みはわかりやすいと思います。
6:02 AM
ドキュメントはたぶんClangのmoduleのところがそうだと思います。
6:03 AM
ただそれはSwiftでどうかということは書いてない。
Avatar
うーむ・・・・clangのドキュメント・・・・つらいw
Avatar
Swiftは clang module を読み込めるんだと思ってる
Avatar
今は,Objective-CのコードをSwiftに書き直した方が早いし,将来性あるんじゃないかと考え始めている
Avatar
Swiftの package 機能は clang module を限定的に使うやつで
6:04 AM
swift の @_exported import の裏技とかは、
6:04 AM
仕組み上 clang module が取り扱える基盤があるから動いてそう。
Avatar
SwiftPMでビルド可能にした後にXcodeプロジェクトを作るのがやっぱりオススメかな。
6:07 AM
OSSならばSwiftPMでビルド可能、の時点で公開できれば、具体的なアドバイスが出来る。
Avatar
Kishikawa Katsumi 12/16/2017 6:07 AM
そのフレームワークがiOS用だったらSwiftPMでビルドするまでが結構大変じゃないです?
Avatar
僕も結構ビルド芸やってるのでモノがあれば助けられると思います
Avatar
芸ってw
Avatar
Kishikawa Katsumi 12/16/2017 6:09 AM
ビルドとかコード署名とか環境周りの問題は見ればそこそこ短時間に解決できると思うけど、リモートで解決するのは難しいですね。 😄 (edited)
Avatar
サンプルというか,切り出したいObjective-Cのコードは別にオリジナリティないんで,公開できます
6:10 AM
今は,そのコードをSwiftに移植しようかと思っていますが,後学とコミュニティのためにどうすればいいか議論していい気がしています
6:13 AM
っていうか,めっちゃしょうもないサンプルプロジェクトになってしまった
6:15 AM
Contribute to ObjCInSwiftFramework development by creating an account on GitHub.
6:16 AM
状況. やりたかったのは,iconvでデコードする昔書いたobjective-cのコードをswiftから呼びたいということです. ただし,swiftのコードは,frameworkで,applicationではありません. このサンプルコードのsampleがアプリケーションで,sample2がフレームワークになっております. sampleでは,objective-cのコードがswiftのコードから見えません.
Avatar
やってみます
Avatar
ありがとうございまする
Avatar
なるほど、システムヘッダ依存なのね。
6:25 AM
^ とりあえず、絶対パスとかで書いてるけどこれがImportする側を変更する場合の基本ですね。相手がベンダーライブラリとかでインポート側を訂正できない場合に使います。
6:26 AM
次、インポートされる側でモジュールをエクスポートする方法をやってみます。
6:27 AM
と、思ったけど、今はsample2.framework自体にSwiftとObjCが混ざってるからたぶん無理ですね。
6:28 AM
そうするにはObjCのコードを分けて、iconvのラッパーライブラリとして作る、みたいなことが必要。
6:28 AM
そうすると、Swiftのフレームワーク(sample2.framework)でそれがインポートできる。
6:32 AM
^ の変更は stringByDefaultEncodingWithData の呼び出しまでしか確認してないけど、modulemapファイルにlibiconvをリンクする設定がいるかも。
6:35 AM
6:37 AM
^ Importされる側を修正するバージョン。ObjCのコードNSString+iconv.h/mを1つのモジュール(IconvWrapper.framework)にしてそれをsample.framework(およびTestApp)からインポート。
Avatar
Contribute to ObjCInSwiftFramework development by creating an account on GitHub.
6:37 AM
できた
Avatar
Kishikawa Katsumi 12/16/2017 6:37 AM
元ライブラリに手を入れられるならこっちの方が’簡単。実質的にObjCのCocoa Frameworkのプロジェクトを作ってソースファイルをコピーするだけなので。 (edited)
Avatar
リポジトリルートにあるxcworkspaceを開いて作業するようになってて、 ObjCのstatic libraryのプロジェクト Swiftのdynamic libraryのプロジェクト SwiftのiOSアプリのプロジェクト の3つが入っててそれぞれ依存設定してあります。
6:38 AM
import IconvSwift class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let data = Data.init(bytes: [0x82, 0xA0]) // SJIS で "あ" let str = NSString.init(byDefaultEncodingWith: data) print(str) } ↑で、これが動いたので、OK
6:39 AM
ObjCのやつをSwiftから読み込むために src/IconvObjC/module.modulemap ファイルと Swiftのプロジェクト側の BuildSettings の Import Paths が設定してあります
Avatar
ふーむ
Avatar
Kishikawa Katsumi 12/16/2017 6:42 AM
おもちさんのと私の2つ目との違いはIconvObjC(=IconvWrapper)がStaticフレームワークかDynamicフレームワークかというところですね。
6:43 AM
いずれにしても、言語Mixの1つのフレームワーク、よりは言語ごとの複数のフレームワークを作る方が簡単だと思います。
6:43 AM
言語Mixの1つのフレームワークの場合は内部でモジュールを作ってインポートする。
Avatar
構成のバリエーションがいくつかあってそれぞれに特性があるのでややこしいですね・・・
Avatar
言語ミックスは辞めときます
Avatar
Kishikawa Katsumi 12/16/2017 6:45 AM
そうですね。例えばIconvをSwiftから使いやすいラッパーを提供したいということなら、内部でIconvを使う1つのSwiftフレームワークで提供した方が、ユーザーにとってはわかりやすい。
6:46 AM
ここからは、全然別の仮の話ですけどFramework in FrameworkがAppStoreに出せるなら上記の色々な方法はほとんど必要なくて、たいていはFramework in Frameworkの方法をよかった。 (edited)
6:47 AM
IconvObjCをIconvSwiftに組み込んでしまうということ。技術的には全然可能で問題なく動くけど、ただこれはAppStoreに出せないので実質意味がない。 (edited)
Avatar
そのサンプルに限って言うなら、iconvはDarwin, (LinuxならGlibc)をインポートすれば使えるのでSwiftに書き直すのが良いと思う。
👍🏻 1
Avatar
sample2をXcodeとSwiftPMの両方に対応させた https://github.com/sonsongithub/ObjCInSwiftFramework/compare/master...norio-nomura:support-both-of-swiftpm-and-xcode (compare branchesのリンクに差し替え) (edited)
Contribute to ObjCInSwiftFramework development by creating an account on GitHub.
8:22 AM
Xcodeプロジェクトはswift package generate-xcodeprojで再生成したものを修正してる。
Avatar
ありがとうございます!
8:39 AM
色々選択肢があって・・・結局,swiftに移植する道を選びますたw
8:39 AM
でも,とりあえず参考にして,どっかにまとめたいと思います
Avatar
最低限の変更にしてXcodeプロジェクトの編集ステップ毎にコミットを別けた。 https://github.com/sonsongithub/ObjCInSwiftFramework/compare/master...norio-nomura:support-both-of-swiftpm-and-xcode-take2
Contribute to ObjCInSwiftFramework development by creating an account on GitHub.
Avatar
Cのライブラリが,処理に失敗した時にポインタの代わりに-1を返すのをSwiftでチェックする場合,以下のコードでよいのかしら? let intIconv: iconv_t = iconv_open("UTF-16//IGNORE", "SHIFT-JIS") guard Int(bitPattern: intIconv) != -1 else { throw EncodingErrors.invalidEncodingName }
Avatar
良いと思います〜
👍 1
Avatar
@omochimetaru thx
Avatar
すみません、質問させてください。 Swiftってこんな風に、structのletに初期値を代入しておいて、それ用に中ではletに代入を行わないinit作った場合に以下のことをしたら勝手にletに代入されたんだけど、こんな言語仕様でしたっけ? struct Card { enum Suit { case spade case heart case club case diamond } enum Rank { case one case two case three case four case five case six case seven case eight case nine case ten case j case q case k } let suit: Suit = .heart let rank: Rank = .j init(suit: Suit, rank: Rank) {} } let card = Card(suit: .spade, rank: .k)
12:53 PM
普通こんな風には書かないと思いますが、TDDの説明用の資料として作っていたので、言語仕様の確認がしたかっただけと理解いただけるとありがたいです。m( )m
Avatar
Kishikawa Katsumi 12/24/2017 12:54 PM
合ってると思いますよ。むしろ let suit: Suit = .heart と書くと init では代入できない。
Avatar
a,
Avatar
Kishikawa Katsumi 12/24/2017 12:54 PM
init(suit: Suit, rank: Rank) {} で渡しているパラメータは self.suit には代入できないので別のことに使うしかない。
Avatar
letで書いているのでinitで代入できない問題は、仮実装中のコードとして置いていたからです。この後一般化しようと思っています。
12:56 PM
あー、やはりそうですよね;
Avatar
Kishikawa Katsumi 12/24/2017 12:56 PM
initで代入したいなら、let で初期値は渡せないです。
12:56 PM
letで初期値を書かないなら、initで代入する、どちらか。
Avatar
あ、ああ、やはりそうですよね。理解しました🙇
12:58 PM
・letに初期値を入れずにinitで代入するようにする ・letに初期値を代入しておく この二つは用途が違う
Avatar
Kishikawa Katsumi 12/24/2017 1:00 PM
そうですね。指定されなかった場合のデフォルトはあるけど、最初に任意に指定して変更できるようにしたいという場合はプロパティに代入する形では書けないです。
Avatar
ありがとうございます😀
Avatar
Kishikawa Katsumi 12/24/2017 1:00 PM
それができたら揃ってキレイなんだけど、、、みたいに思うことはよくあります。
1:00 PM
というかそうやって書いて、initに書き直すとかよくやってる気がする。
Avatar
それができたら揃ってキレイなんだけど、、、みたいに思うことはよくあります。
なるほど、これは確かにありそうですね🤔
Avatar
init側のデフォルト引数にするとやりたいことは出来そう?
Avatar
Kishikawa Katsumi 12/24/2017 4:33 PM
そうだと思います。
Avatar
SwiftのArrayとかから,ポインタにするコード,いつまでたっても,空でコード書けない
7:25 AM
普段から書かないもんなぁ・・・・・
Avatar
全然覚えられない
7:29 AM
毎回,コピペしてる気がする
Avatar
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
7:06 AM
これ関連でよくわからない挙動が有りまして
7:06 AM
import UIKit class ViewController: UIViewController { var provider = Provider() override func viewDidLoad() { super.viewDidLoad() provider.reload { self.provider.layout() // 1) Simultaneous access ! } } struct Provider { let cache = Cache() // 2) comment out mutating func reload(completion: @escaping ()->Void) { // 3) remove mutating keyword completion() } func layout() { } } class Cache { } } (edited)
7:07 AM
このコード自体に特に意味は無いんですが、適当なiOSプロジェクトを作ってiOS Simulatorで実行すると 1) で例外?が発生します
7:08 AM
3) の mutating を外すと正常に動くので、SE-0176 関連の挙動かなとは思うんですが
7:08 AM
謎なのは、2) の行をコメントアウトするだけで、例外が発生しなくなるという点です
7:10 AM
手元の再現環境は、macOS 10.13.1 + Xcode 9.2 + iPhone 8 Plus Simulator + デバッグ実行で再現しました。 (edited)
7:11 AM
何かご存知の方いらっしゃいますか?
Avatar
omochimetaru 1/9/2018 7:13 AM
バグか仕様か悩ましいですねこれは
7:14 AM
例外というか実行時クラッシュのはずです 排他則の動的検出にひっかかっていて
7:14 AM
reloadメソッドがmutatingなのでProviderのインスタンスは書き込みアクセスされているんですが
7:15 AM
completionブロックの中で provider.layoutを呼んでいるので、これは読込アクセスなんで
7:15 AM
書き込みアクセス保護中のオブジェクトにたいして読込アクセスをしてはいけないので
7:15 AM
クラッシュするっていうのがまず基本で
7:16 AM
で、// 2 をコメントアウトするとクラッシュしなくなる理由については予想ですが
7:16 AM
stored propertyを1つも持たないstructに関しては
7:16 AM
書き込みアクセスがあろうが実際に書き込みの影響を受けるメモリ領域を持っていないので
7:16 AM
同時アクセスをしても問題ないはずです
7:16 AM
だからクラッシュが発生しなくなるんだと思います
7:17 AM
ただそれが仕様上許された例外的な挙動なのか、実装の都合でたまたまそうなっているのかはわかりません。
7:17 AM
3でmutatingを外すと動くようになるのは、 reloadが読込アクセスに降格するからで
7:18 AM
読み込みアクセスは重複が許されてるのでこれはLoE違反しないです。
Avatar
あーなるほど
7:20 AM
>stored propertyを1つも持たないstructに関しては 書き込みアクセスがあろうが実際に書き込みの影響を受けるメモリ領域を持っていないので 同時アクセスをしても問題ないはずです
Avatar
omochimetaru 1/9/2018 7:20 AM
これは予想ですけど、//2 をコメントアウトしても、代わりに var hoge:String = "" とか
7:20 AM
つけたすと
7:20 AM
同じようにクラッシュするんじゃないですかね〜
Avatar
たしかにクラッシュしました
Avatar
omochimetaru 1/9/2018 7:23 AM
おー じゃあやはり 「stored property が 0個 の場合」にまつわる挙動っぽいですね。
Avatar
なるほどー!
7:23 AM
ちなみに
7:23 AM
override func viewDidLoad() { super.viewDidLoad() provider.reload() } struct Provider { var cache = Cache() mutating func reload() { layout() } func layout() { } }
7:23 AM
これだとクラッシュしないのは
7:24 AM
LoE違反ではない、ってことですかね?
7:24 AM
closureがからむとNG..?
Avatar
問題になるのはlayoutを呼ぶ対象とreloadした結果のProviderが食い違うことで、この場合はプログラマが明示的にどれなのかを管理できるから問題ない (edited)
Avatar
omochimetaru 1/9/2018 7:25 AM
それだと、reloadメソッドが所有してるアクセス権の範囲内で layout を呼び出しているのでOK
Avatar
なるほど、reloadの中で処理が閉じているから問題なしで、元コードはclosure経由で外部から読まれてしまうので問題ありと・・ (edited)
7:36 AM
理解できました、ありがとうございます!
🙂 1
Avatar
>おー じゃあやはり 「stored property が 0個 の場合」にまつわる挙動 はSE-0176 Proposed solutionの No enforcement is required for immutable memory, like a let binding or property, because all accesses must be reads.
7:55 AM
の仕様によるものですかねー (edited)
Avatar
omochimetaru 1/9/2018 7:57 AM
そのセンテンスは、 letでのローカル変数定義やclass/structのletで定義されるpropertyのような、immutableなメモリについてはLoE強制処理は必要ない ってことを言っていると思います
7:57 AM
言語仕様の時点でletに対しては読込アクセスしかできないからです
7:58 AM
「immutable memory」に、カンマ以降の like ... がかかっているので。 「0 propertyの場合」が「immutable memory」とみなされるかどうかは別の議論だと思います
Avatar
stored property が 0個 = immutable memory
7:58 AM
なるほど
Avatar
omochimetaru 1/9/2018 7:58 AM
「1個追加したら壊れる」っていう仕様だと、逆にこういう混乱が起きたり、後から追加してバグらせたりしかねないので
7:58 AM
0個であっても保守的にエラーにしておくほうがいいんじゃないかと個人的には思います
Avatar
たしかに!
Avatar
omochimetaru 1/9/2018 7:59 AM
bugsに投げてみた方がいいかな・・・うーん・・・。。
Avatar
Int.advanced(by:)Array.filter(_:) のような、同じ型の新しいインスタンスを返すメソッドのことを、ゲッター、セッター、ミューテーターみたいな分類でいうと何と言いますか? (edited)
Avatar
トランスフォーマー?(違
Avatar
アリかも!
Avatar
「トランスフォーム」は「変形」だから型が変わるイメージがなきにしもあらず… 🤔
🤔 2
Avatar
高階関数とは別ってことだとなんだろう…
Avatar
変質が近いニュアンス?deterioratorとかalterationerとか?
Avatar
extension UIView { var ii : Int { get { return 0 } set(i) { // hogehoge } } } let v = UIView() v.ii = 3 propertyがこんがらがってしまって、Stored property と Computed propertyがあって上のコード内のiiはComputed propertyであってますでしょうか🙇
Avatar
はい、ii は Computed Property です。
Avatar
ありがとうございます。
Avatar
// Stored property. var p1: Int = 1 // Computed property. var p2 Int { get { return 1 } set { /* ... */ } } // Computed property ( 暗黙のgetのみ ) var p3: Int { return 1 } (edited)
Avatar
ありがとうございます!
9:07 AM
つまり、これはだめだということですね extension UIView { var a = 0 }
Avatar
ですね。 extension に Stored property は追加できない。
✋ 1
Avatar
もう1つ質問なのですが、setterの中で extension UIView { var ii : Int { get { return 0 } set(i) { backgroundColor = UIColor.red } } } と、classにある値を変更するのは、よくないでしょうか?
Avatar
「classにある値を変更」自体は問題無いと思いますが、 set した値を get で取り出せるようにすべきだと思いますよ。
Avatar
ありがとうございます。そうですよね。setterのことだけ気になっていたのですみません。
Avatar
getterが無意味なら普通に一引数のfunctionにしたほうが良いですよ
Avatar
いまのところgetterが無意味なのですよね・・・
9:17 AM
Computed PropertyとSetterのことがわかったのでありがとうございます。functionも考えてみます
Avatar
func example<T>と定義したのって、example<Int>()で呼べましたっけ?
Avatar
そう言う呼び方はできなかった気がする
1:44 PM
そもそもシグネチャの引数か返り値にT使ってないとコンパイル通らないような
Avatar
引数に型情報与えないとやはりダメなのかなー。
Avatar
どういうことがやりたいんですか?
Avatar
型で、なんかコンパイラに証明させようかと思ったんですよ。
Avatar
ほう
1:50 PM
func example<T>(_ type: T.Type) { } example(Int.self)
1:50 PM
これしかないよーな
Avatar
ですね、ちょっとなんかそれだと、エレガントじゃないなぁという感じですが、仕方ないですねぇー。
Avatar
example<Int>() こう呼べても良いような気もちょっとだけする
1:55 PM
何か不都合があるのかな
Avatar
エレガントじゃない方法で良ければ、高階関数にして(T.Type) -> (T) -> ()でexample(Int)とかできませんかね
2:03 PM
できたぞ
2:03 PM
func example<T>(type: T.Type=T.self) -> (T) -> () { return { arg in print(arg) } } let intE = example(type: Int.self)
Avatar
目がチカチカするコードきた
Avatar
慣れて
Avatar
あー
2:04 PM
ん?
2:05 PM
intEInt が引数の関数でしょ
2:05 PM
これやりたかったことなのか?
2:06 PM
もしかしてこれ example<Int>() で呼べるのか
Avatar
example()(1)が出来る
Avatar
それは @Nobkz さんやりたかったことなんか…?w
Avatar
本質的に欲しいのは、Intで確定したexampleを使いまわしたいということなのでコレで可
2:08 PM
仕方ねぇな~~~~
Avatar
壊すなよ〜
2:09 PM
あーこれもしかして別スレの文脈があるのか ここしか見ていなかった
Avatar
func example<T>(arg: T) -> () { print(arg) } func example<T>(type: T.Type=T.self) -> (T) -> () { return example } let intE = example(type: Int.self)
2:09 PM
ほれ、オーバーロード編だ
Avatar
まぁ、なんだ、やりたいことがなんかできそーだからちょっとやってみるかね。10分くらいまて。
Avatar
Xcode落ちたんだがww
Avatar
『僕は悪くない』
Avatar
絶対言うと思った
Avatar
できたぞ。
3:37 PM
ここに流すより、mathに流したほうがええか。1 + 1 = 2の証明っぽいの。
Avatar
おやつだ
Avatar
そのざっくりとして申しわけないんですが、Swiftで、Listっぽいことやりたいのですが、みなさんどうしてますかね?
Avatar
ListってJavaのLinkedListみたいな感じですよね
Avatar
どっちかというと、HaskellのListっぽいやつ。
5:29 AM
あ、でも遅延はしなくてよい。
Avatar
Kishikawa Katsumi 1/30/2018 5:29 AM
SwiftもObjective-Cも標準のデータ構造は貧弱なんですよね。自分でチョチョっと書くことになると思います。
5:30 AM
ただまあ"Swift data structure"とかで検索したら出てくることはでてくる。
5:30 AM
ただそういうのはSwift 2あたりで更新が止まってることが多い。
Avatar
indirect enumでtailとnextのケースを書くのがよく見る奴
Avatar
なんか自分で書くかんじなんすかねー。
5:32 AM
それが分かれば、かくかーって感じでわかりますた。
Avatar
Sequenceに適合すると便利です
5:33 AM
あでもmapしたらArrayになるのは微妙いかな
5:34 AM
@koher が遅延評価なやつ作ってた
Avatar
SequenceTypeだからswift2かな (edited)
Avatar
SequenceはmapしたらArrayになるんか....うーむ。
Avatar
HigherKindedTypeないねん、ごめんな
Avatar
Swiftz - Functional programming in Swift
5:36 AM
これとかじゃダメです?
5:37 AM
だいたい欲しいものが揃ってるので満足してました
Avatar
揃ってそうですね
5:37 AM
いきはよいよいかえりはこわひ
Avatar
Kishikawa Katsumi 1/30/2018 5:37 AM
確かに、Haskellっぽいことをするなら。
Avatar
後戻りできなくなるのでプロダクトに入れるのは悩むやつです
Avatar
Kishikawa Katsumi 1/30/2018 5:38 AM
プロダクトに導入するにはエクストリームすぎるかな。。。
Avatar
まあでも大体のライブラリはそうか
5:38 AM
チームメンバーが全員パワー系なら入れたい
Avatar
たしかに満足しますね。
Avatar
チームメンバーがパワー系、未来永劫そうであるかという問題もあって難しい
Avatar
個人的には Either, Monoid, Functor ぐらいは使っても理解は容易なので害はないだろう、と思っていたりします
👀 1
5:43 AM
Monad あたりから敬遠する人が増えてくると思いますが、まあ上記のものぐらいは最悪自前実装にも簡単に変えられますしね
Avatar
mapとflatMapがわからん人間がいてabuseするのでcompactMapに名前を変更するのが現実ですよ
5:43 AM
現実を見て
5:43 AM
理想は
Avatar
現実は厳しいw
Avatar
Kishikawa Katsumi 1/30/2018 5:44 AM
世の中にはmapとflatMapがあればいいやんみたいな人もいるから大丈夫。
Avatar
(ちなみに、プロダクトの話がありましたが、うちはプロダクトに Either と Monoid は持ち込みましたね)
Avatar
お忙しいところすみません>< 困っていることがありましてお助けいただけましたら幸いです objectMappingを使ってjsonに変換しているのですが、例えば下記のようなことは可能でしょうか? サンプル userId = 100 --- Int userName = "gabacho" --- String honest = nil --- Bool tel = nil --- Int この際にtelは含めず、honestだけnilもjsonの中に含めたいです 例えば、最初はhonestをtrueにしてたけどやっぱりどっちでもないnilに変更したいと言った場合などです そもそもBool型でなくすという手もあるとは思うのですが、既存アプリの改修のためできれば型を変えずにできるとありがたいです 理想のjson {"user"=>100, "name"=>"gabacho", "honest"=>nil} 何卒よろしくお願いします!
Avatar
API絡みの話題と推測しますがリクエストとレスポンスどちらの話でしょうか?
Avatar
はい、APIがらみです! アプリで編集してその結果をサーバーに送信するのでリクエストかと思います (単語の意味から送信がリクエストで、受信がレスポンスと解釈しましたが間違っておりましたらすみません)
Avatar
ObjectMapperは結構自前でマッピング処理書けたんでなんとかなるとは思います、レスポンスの場合は型を変えると既存のアプリが壊れるから確認しました。リクエストなら古いバージョンのアプリから古い型でAPIが叩かれるのを考慮する必要がありますね。
Avatar
既存のコードで honest がすでにBool型なところにnilを入れたいということなら Bool? なり適切なモデル型なりに型を変える必要ありそう
Avatar
@tarunon ありがとうございます! 法人向けアプリのためバージョンはこちらで一律管理できるので古いバージョンから送信されることはないので大丈夫です!
Avatar
Boolにnilは無理なのでBool?にするのは必須ですね
Avatar
@hiragram @tarunon 確かにそうですね、ありがとうございます! ざっくりとした質問で申し訳ないのですが、マッピング処理はどのあたりでやってるのでしょうか? (コード読めという話だと思うのですがお助けいただけるとありがたいです...)
Avatar
マッピングというのがオブジェクトからJSONへの変換という意味だったら、プロジェクト内を JSONSerialization とかでgrepしてみたらどうでしょうか
3:18 AM
個別のライブラリでラップされてたらなんとも言えないですね
Avatar
ライブラリはObjectMapperであってますよね?
Avatar
あとは通信呼び出してる処理から辿るとか、、、?
Avatar
それならモデルのコードに入ってるはず
Avatar
Kishikawa Katsumi 1/31/2018 3:18 AM
モデルにinit(from)かmappingみたいなメソッドがあるはずです。
Avatar
個別のプロパティのマッピングは<=だったかな、うろ覚えですが
3:20 AM
ObjectMapperのドキュメントを読むのが良いです
Avatar
@tarunon 念のため確認いたしましたがObjectMapperでした!
3:21 AM
@hiragram JSONSerialization見てみます!
Avatar
@tarunon@Kishikawa Katsumi が言ってるのはJSON→オブジェクトのマッピングじゃないですか?リクエスト側とのことなので逆方向な気がする
3:22 AM
(ObjectMapper使ったことないので正しかったらすません
Avatar
ObjectMapperはどっちも共通なんす
3:23 AM
たしか
Avatar
そうなんや
Avatar
@Kishikawa Katsumi ありがとうございます! 調べてみます!! @tarunon ありがとうございます! みなさんに教えていただいたヒント参考にドキュメント探ってみます
3:30 AM
@hiragram ありがとうございました!
👌 1
3:32 AM
またご報告にまいります! 前任者の引き継ぎでやってるのですが、前任者がすでに退職していてiOSわかる人間が社内にいないというなんともな環境でして...w またここでご質問させていただけましたら幸いです
😨 4
Avatar
上記の件ですが、コメントいただきありがとうございました! 現在ですが userId = 100 --- Int userName = "gabacho" --- String honest = nil --- Bool? tel = nil --- Int? に対してできたJSONが {"user"=>100, "name"=>"gabacho"} となっておりnilが無視されている状態です 別作業も挟まってきておりますが、継続して解決策を探していければと思っており、見つかりましたらまた報告いたします!!
Avatar
そのJSONのオブジェクトがSwiftのDictionaryだとしたらnil代入はキーの削除と同じってことになってキーごと消えるのはまあわかる
Avatar
ObjectMapperに手を入れないとnull入れるのは実現できない気がしてきた
Avatar
SwiftyJSONにはSwiftyJSON.nullみたいなのがあった気がするからその辺がObjectMapperにも無いかなって感じ
6:58 AM
@tarunon ↑こういうのない?
7:13 AM
NSNullを特別扱いしてるっぽいですねぇ
7:13 AM
NSNullならkey付きのnullになってくれるかも
7:13 AM
key付きのnullとkey削除の区別をしないとAPIが壊れるのかどうかによると思います。
Avatar
@hiragram @tarunon ありがとうございます! ObjectMapperのコードで下記があって、そこに入ってきているので 「keyがhonestかつnilだったらnull入れて」みたいなことしようとしてたのですがうまく実装できず、別作業が差し込みで入ってきたのでそっちに移ってしまいました ちなみにignoreNilにはfalseが渡されています ここいじれば行けそうでしょうか? public subscript(key: String, nested nested: Bool, ignoreNil ignoreNil: Bool) -> Map { // save key and value associated to it currentKey = key keyIsNested = nested // check if a value exists for the current key // do this pre-check for performance reasons if nested == false { let object = JSONDictionary[key] let isNSNull = object is NSNull print(object) isKeyPresent = isNSNull ? true : object != nil currentValue = isNSNull ? nil : object } else { // break down the components of the key that are separated by . (isKeyPresent, currentValue) = valueFor(ArraySlice(key.componentsSeparatedByString(".")), dictionary: JSONDictionary) } // update isKeyPresent if ignoreNil is true if ignoreNil && currentValue == nil { isKeyPresent = false } return self }
Avatar
ignoreNilがあるのか、それfalseなら行けそうな気がするんですけどね
Avatar
名前的には行けそうだなと僕も思いました
Avatar
先週はお世話になりました。 ご相談させていただいていた件なのですが、アプリ側で対応するよりサーバー側で要素がなければnilにするという処理の方が早かったためをサーバー側で対処することになりました。 せっかくお力お借りしたのに答え出すまでやりきることができずすみませんでした。 次回こそは!と思っておりますので、また顔だした時にお力お借りできましたら幸いです。 何卒宜しくお願いいたします
💪 2
✨ 1
Avatar
がんばって
Avatar
ありがとうございます!!
Avatar
https://stackoverflow.com/questions/48478143/app-submission-failed-1-corrupted-binaries-non-public-api-usage-and-no-additi/48512154
Non-public API usage: The app contains one or more corrupted binaries. Rebuild the app and resubmit
1月26日以降、このエラーに遭遇するようになった方いますか?
I’ve been submitting my app to the App Store for test flight and after build 11, I’ve been getting failures via email from Apple: Non-public API usage: The app contains one or more corrupted binar...
7:11 AM
いろんなワークアラウンドが提示されていて、結局なにをどうすればいいのか分からず
👀 1
7:13 AM
(遭遇してない方は遭遇してないリアクション絵文字もらえると、ありがたいです!)
Avatar
どうやらウチの場合はbitcodeの有無が効いていたようです
7:59 AM
ちょうど運よく(&珍しく?)、bitcode有効にできるのに無効だったアプリを1月24日にTestFlightしたときは成功していて、おなじコミットで今日rebuildすると Non-public API usage で、bitcode有効にすると通りました
8:04 AM
アナウンス出てないと思うのですこし様子見してみます...
Avatar
extension<T: SomeProtocol> Array where Element == T みたいなジェネリックなエクステンションってまだできないですよね?
Avatar
@Taketo Sano できないです。
7:00 AM
これは Swift に欠けてる言語機能なので早くできるようになってほしいですね。 Parameterized Extensions はまだですが、まずは 4.1 から Conditional Conformance が使えるようになります。
Avatar
ありがとうございます!Conditional Conformance は心から心待ちにしてます😸
7:58 AM
4.1 っていつ出るか明らかになってます?
Avatar
春だと思ってましたが、今ぱっと探した限りでは公式情報は↓しか見つけられませんでした。
Swift 4.1 is intended to be released in the first half of 2018.
https://swift.org/blog/swift-4-1-release-process/
This post describes the goals, release process, and estimated schedule for Swift 4.1.
Avatar
norio_nomura 2/12/2018 8:31 AM
Xcode 9.3と同時だろうから3月?
👀 2
Avatar
楽しみですね 👺
Avatar
Read a free sample or buy The Swift Programming Language (Swift 4.1 beta) by Apple Inc.. You can read this book with iBooks on your iPhone, iPad, iPod touch, or Mac.
6:00 AM
4.1の本はあるのか。betaだけど。
Avatar
もう更新されてたのか。 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html Revisionはここ。 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/RevisionHistory.html#//apple_ref/doc/uid/TP40014097-CH40-ID459 - Added the Conditionally Conforming to a Protocol section with information about conditional protocol conformance. - Added information about recursive protocol constraints to the Using a Protocol in Its Associated Type’s Constraints section. - Added information about the canImport() and targetEnvironment() platform conditions to Conditional Compilation Block.
Avatar
そういえば、「空」でないことをどう表現するんだ?と思いまして、型で表現できねーかとか考えてまして、
Avatar
それで、まぁPhantom Typeが書ければいいかーってなってまして、SwiftでPhantom Typeって例ありますかね??
Avatar
omochimetaru 2/19/2018 9:38 AM

はじめに

Swiftの界隈ではPhantom Type(幽霊型)という、型に状態をエンコードする手法がある。この記事ではまずこのPhantom Typeを用いた手法について解説し、この方法よりも著者がよいと思うLIO...
Avatar
社内の「Scala 勉強会」で Phantom Type (幽霊型) という厨二心をくすぐる感じのデザインパターンを教えてもらったので、同じことを Swift でもやってみました。 インスタンスの状態を変数ではなく **型パ...
Avatar
Kishikawa Katsumi 2/19/2018 9:39 AM
NotAutoLayout is a framework to help you layout subviews without Auto Layout constraints.
SpreadsheetView - Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if y...
Avatar
Kishikawa Katsumi 2/19/2018 9:42 AM
数個以上の複数の状態の組み合わせがあるけど、なってはいけない状態の組み合わせがある、みたいなときに状態を型にエンコードすると、おかしな状態を排除できるので、そういう場合に使っています。
Avatar
おお、参考になります。
9:46 AM
RxSwiftでSingleとMayBeがファントムタイプになってます。
9:46 AM
Single(1)をfilterするとMayBe(1 or 0)になる。これってまさに「空」のエンコーディングの実用例かも。
Avatar
あ、NotAutoLayout紹介されて光栄です☺
Avatar
Kishikawa Katsumi 2/19/2018 10:26 AM
NotAutoLayoutは中途半端な制約にならないように使われてましたね。片方だけしか制約がないといった不完全な状態の時は違う型を返して、制約が全部ついたら初めてコンパイルが通るという感じ。
☺ 1
Avatar
ですです
Avatar
omochimetaru 2/22/2018 6:26 AM
|[ A ] [ B ]| | [ C ]| こういう感じで、BとCがそれぞれ可変サイズだとして、Aの右端が、BかCのどちらかより長い方の左端にくっつく ってAutoLayoutでどうやって書くんです? (edited)
Avatar
まかせて
Avatar
omochimetaru 2/22/2018 6:28 AM
A <= B , A <= C って不等号条件を2つ並べるところまでは思いついたけど、それだと、Aの幅にまだ自由度があって駄目だ
Avatar
BとCを詰めたViewを一個作って
6:30 AM
priority 750の [B&C].width == [B].width, [B&C].width == [C].width priority 1000の [B&C].width >= [B].width, [B&C].width >= [C].width
Avatar
omochimetaru 2/22/2018 6:32 AM
それだと
Avatar
後は[A]と[B&C]の隙間をよしなに設定すればオッケーだよ。Aの中身も幅が可変ならAのContentなんちゃらPriority下げればいい
Avatar
omochimetaru 2/22/2018 6:32 AM
[B&C] が B よりも C よりも長い可能性を許さない?
6:32 AM
あ〜端っこくっつければそれは無いのか。
6:33 AM
ん、でも端っこくっつけるのも1000だと矛盾するか
Avatar
てかB&Cをstackviewで作れば
6:33 AM
よしなにいけると思うけど
Avatar
omochimetaru 2/22/2018 6:34 AM
B.width = 100 ; C.width = 200; のとき、 B&C.width = 300 でもprio1000の解は満たす(曖昧になってる
6:34 AM
stackviewは独自ロジックも持ってるから、AutoLayoutだけでできるのか興味ある
Avatar
B&CはBとCからしか決まらないから、300はあり得ない
Avatar
omochimetaru 2/22/2018 6:34 AM
そこは、Edgeをくっつけるってことだよね?
6:35 AM
そのEdge吸着の優先度はいくつ?
6:35 AM
両方1000にするとやっぱり駄目な気が prio750と共存できる方だけが残るのか・・・?
Avatar
上と左をはっつけて、高さと幅を計算するようにしてだな
6:37 AM
grater thanとweak equalで最大値をとるテクを使う
Avatar
|[A]-(>=10@1000)-[B]| |[A]-(>=10@1000)-[C]| |[A]-(0@750)-| ではだめですかね? (edited)
Avatar
この場合高さが可変じゃないなら、上左下貼り付けでいい
Avatar
omochimetaru 2/22/2018 6:39 AM
↑0@750が、「目一杯広がる」を意味しないと思ってて。
Avatar
ああ、高さは普通でよかった
Avatar
omochimetaru 2/22/2018 6:39 AM
「ルール3つで矛盾が起きたら750のルールが取り除かれる」だけですよね
6:40 AM
そうすると不等号2つだけが残るけど、不等号制約は別に、 >= の 「境界値に近づく」ように制約解決する方向付けの作用って無いんじゃないかと(あるのかな
6:41 AM
とりあえず試してみます
Avatar
「取り除かれる」なんでしたっけ。それを知らなかったです。
Avatar
omochimetaru 2/22/2018 6:47 AM
Even if an optional constraint cannot be satisfied, it can still influence the layout. If there is any ambiguity in the layout after skipping the constraint, the system selects the solution that comes closest to the constraint. In this way, unsatisfied optional constraints act as a force pulling views towards them.
6:48 AM
これか。例えスキップされた制約であっても、レイアウトが曖昧な場合にはできるだけ近づくように影響を与える。
👍 2
6:49 AM
rintaroさんの3条件のやつでうまくいきました、警告も無し
Avatar
おー
Avatar
omochimetaru 2/22/2018 6:49 AM
B&Cの包みView無しでできたわ。
6:49 AM
そうすると、iOSDCでinamyさんが作ってたやつは (edited)
6:50 AM
ここらへんの機能が無かったりしそうだ (edited)
6:50 AM
Cassowary - An incremental linear constraint-solving algorithm (Auto Layout) in Swift.
6:50 AM
priorityあるしあるのかな
6:52 AM
あ〜、priority1000の不等式条件は前提条件とした上で、750の等式条件を、誤差最小化問題として解けばこういう動きになるのか。
Avatar
要件勘違いしてた
6:54 AM
勝手にBとCはそれぞれ大きい方にサイズを合わせるみたいなのが脳内補完されていたw
6:54 AM
(よくあるので)
Avatar
omochimetaru 2/22/2018 6:54 AM
ああ、BとCは完全に独立ににょきにょきするイメージ。
Avatar
りんたろ先生の、BとCの大きい方が入れ替わると
6:57 AM
ニョッキキしてる片方のサイズがおかしくなる気が
Avatar
omochimetaru 2/22/2018 6:57 AM
BとCの大きい方を入れ替えてもちゃんと解決されたよ。
Avatar
B, C の width の制約次第だと思いますよ。
Avatar
omochimetaru 2/22/2018 6:57 AM
ああ、うん、BとCの幅は別途の事情で決まるっていう想定。
6:58 AM
BとCが何かしか決まってて、その上でAをどちらかにくっつける。
Avatar
B, C の width が何らか priority 1000 で決まれば破綻はしないはず。
Avatar
いけたっぽい
7:01 AM
最大値と合わせる~みたいな話は結構Autolayoutであるので
7:01 AM
スッと設定する方法が欲しい
7:03 AM
7:03 AM
逆におもちの本当にやりたかったことはStackViewだとできなさそう?
Avatar
omochimetaru 2/22/2018 7:04 AM
StackViewの場合、StackViewに縦にBとCを並べてやれば、StackViewの幅はBとCのでかい方に・・・
7:04 AM
StackViewの幅をBとCのでかい方に合わせる方法が無い??
Avatar
StackView の width 制約明示しなければ自動的にそうなりませんか?
Avatar
なる、ついでに中身は広がる
Avatar
コードレイアウトなら blue.right = max(stack.left, long.left, greater.left, long2.left) 的な感じで書けそう (edited)
Avatar
omochimetaru 2/22/2018 7:09 AM
そうなんですよね。 https://github.com/robb/Cartography ↑いまこれ使ってるんだけど、 max 関数をこういうDSL上に導入して
Cartography - A declarative Auto Layout DSL for Swift 📱📐
7:09 AM
blue.right = max(stack.left, long.left, greater.left, long2.left) ってかいたらそのまんまやりたいことがAutoLayout制約としてセットアップされたら一番嬉しい
Avatar
AutoLayoutが嬉しいのはコンテンツが動的に書き換わってレイアウト計算が自動で走るところなのだけど
7:10 AM
今日ではコンテンツ書き換わるの川で表現してるなら、Layout計算に流せばまあ動くし…というのもあって実際はそこまで優位ポイントではなくなってきてる可能性がある (edited)
Avatar
コードでも layoutSubviews() の中に書いとけばあとは自動でやってくれるじゃん?
7:11 AM
UIViewのサブクラスやらなきゃいけないけど
Avatar
そこがネックなんですよね~
Avatar
omochimetaru 2/22/2018 7:11 AM
layoutSubviews、びみょ〜な実行順の問題とかでハマるからできれば避けたい
Avatar
実行順番ってのは親ビューのlayoutSubviewsと子ビューのlayoutSubviewsの実行順番のこと?
Avatar
omochimetaru 2/22/2018 7:12 AM
それとか、 VC.viewDidLayoutSubviewsとか、viewDidAppearとか。
7:13 AM
あとなんかlayoutSubviewsの処理がレイアウトを発火しちゃって無限ループしたり。
Avatar
自分は基本UIViewのサブクラス大体自分でやってるからviewDidLayoutSubviews内にさらに別のレイアウト作業やるとか基本ないですね 🤔
Avatar
omochimetaru 2/22/2018 7:14 AM
SO見てると「最初にlayoutIfNeed呼べば直る」とか書いてあったりしてとりあえず書いたら直ったり・・・
Avatar
Kishikawa Katsumi 2/22/2018 7:14 AM
最大値に合わせるっていう場面は私もけっこうあって、モデル側で最大値はこれで持ってるのはこいつだっていうのを取得するやつを作った方がだいたいスッキリするんじゃないかと思っています。
Avatar
layoutSubviewsの処理がレイアウトを発火しちゃって無限ループしたり。
それlayoutSubviewsの中に自分のサイズとか自分の親のサイズとかさえ触らなければ基本ないはずじゃん?
Avatar
Kishikawa Katsumi 2/22/2018 7:14 AM
レイアウト側では単にそいつに合わせる。
Avatar
フォントサイズの違う二つのラベルで大きいのはどっち?(ドン)みたいなやつだと悲しみが
Avatar
Kishikawa Katsumi 2/22/2018 7:17 AM
ああ、それは面倒ですね。そういうのは考えてなかったな。。。
7:18 AM
AutoLayoutで複数のビューと1つのビューで制約が付けられたら、と思うことはあるけど、今でも複雑なのに手に負えなくなるかな?
Avatar
両方の label.sizeThatFits(label.size) を取れば大きい方はわかる…はず
Avatar
大凡StackViewでなんとかするのが思考停止で解決できて手っ取り早くてラクのイメージありますね
Avatar
+1
Avatar
UILabelのsizeはフォント次第でバグるの、マジで許さないからな
Avatar
AutoLayoutで複数のビューと1つのビューで制約が付けられたら、と思うことはあるけど、今でも複雑なのに手に負えなくなるかな?
いなみさん(ry
7:19 AM
ああフォントによってバグるのは確かによくある
Avatar
Kishikawa Katsumi 2/22/2018 7:23 AM
どちらかというとフォントの問題であって、UILabelやNSStringのメソッドは正しい値を返すはず。
7:24 AM
UILabelはフォントがはみ出すのとかは考慮してくれないけど、それはまた別として、、、 (edited)
7:24 AM
挙動は一貫していたはず。
Avatar
フォントをきちんと考慮したサイズを取りたいならやはりCoreTextとか触るしかないですかね… 🤔
Avatar
Kishikawa Katsumi 2/22/2018 7:26 AM
TextKit以降(iOS 6-8のどこか、忘れた)はCoreTextを直接触る必要はほとんどないです。Stringその他のメソッドで同じ値が取れるので、メソッドの仕様とパラメータの意味を理解して正しく使っていれば、よほどのエッジケースを除いて、意図した通りに合わせることは可能。 (edited)
🙇 1
Avatar
TextKitの存在、完璧に忘れていた 😇
Avatar
UILabelが
7:35 AM
なんだっけ、frameの外のレンダを許可するOp入れてもその通りに動かないのが一番悪い
7:35 AM
それさえできれば、多少計算がおかしいのはなんとかカバーできるんですけどね。
7:35 AM
clipsToBoundsかlayerのmasksToBounds?この辺。
Avatar
Kishikawa Katsumi 2/22/2018 7:45 AM
UILabelのサイズはフォント全体のメトリクスから決まるので(どこからどこまでの間かは忘れた)それよりもはみ出るようなフォントの場合(極端に斜体のフォントとか)は実際に文字の組み合わせがレンダリングするサイズに合わせてラベルの大きさを調整する方がいいと思います。
7:46 AM
自身のフレームの外に描画させるのは切れないというだけで、コントロールするのは無理なので。
Avatar
Codableなclassのプロパティに初期値付きletを使うとDecoder.decodeで読むデータにそのプロパティに対応するものがあってもなくても初期値が入る(例外も出ない)、という挙動を見つけたのですが、この挙動ってどうなんでしょうか 🤔
10:05 PM
10:07 PM
import Foundation class Hoge: Codable { let fuga = "default value" private(set) var privateSet = "default value" } let decoder = JSONDecoder() decoder.decode(Hoge.self, from: "{\"fuga\": \"json value\", \"privateSet\": \"json value\"}".data(using: .utf8)!)
10:10 PM
とりあえずprivate(set) varを使えば想定する動きをすることがわかったのでそちらを使っているのですが、初期値なしletは正常に動作するので、そちらと混ぜるとコードがデコボコして見栄えがよろしくないことになってしまってさらに 🤔 しています
Avatar
Kishikawa Katsumi 2/22/2018 10:19 PM
@rinsuki それはデフォルト値のせいではなくて、letのためですね。letでデフォルト値が与えられているのでそれ以上代入することができないのです。
10:20 PM
varにして試してみてください。たぶん、init(decoder:)を書いてみるとわかると思います。
Avatar
@Kishikawa Katsumi なるほど、letで初期値を与えるとコンストラクタでもその初期値が変更できないんですね...。ありがとうございます。 余談ですが、この書き方をしてしまったときにWarningやErrorを出す方法ってないでしょうか。鳥頭なので、できれば機械に指摘してもらいたいのですが...。
Avatar
Kishikawa Katsumi 2/22/2018 10:54 PM
この書き方をしてしまったときにWarningやErrorを出す方法
10:54 PM
たぶん無いと思います。
10:54 PM
私もlet x = "..."とした後にやっぱり外から与えられるようにしようとinitを書いた時点で、コンパイルエラーということがよくあります。
Avatar
なるほど、ありがとうございます。
Avatar
swift のランタイム時の関数呼び出しの上限数って増やせますか?
Avatar
スタックの容量を増やしたいという意味ですか?
Avatar
はい。
8:32 AM
僕は実際には試したことないです。
Avatar
Add -Wl,-stack_size,1000000 to the Other Linker Flags field of the Build Styles pane.
これですね👍 ありがとうございます!
8:37 AM
ld: -stack_size option can only be used when linking a main executable clang: error: linker command failed with exit code 1 (use -v to see invocation) なるものが出てしまった…😯 もう少し調べます🙇
Avatar
omochimetaru 2/26/2018 8:38 AM
main executableというのはアプリ本体のことですよ ライブラリのコンパイルに指定しているように思います
Avatar
ライブラリのテストに指定したいんですが、TestTarget の方に指定したら上のエラーになりました…😥
Avatar
Kishikawa Katsumi 2/26/2018 8:47 AM
テストバンドルはまた特殊で、ホストアプリを作ってそれを使うようにして、ホストアプリに指定したらどうなります?
Avatar
omochimetaru 2/26/2018 8:48 AM
なるほど。ライブラリのテストの場合ってメインはどうするんだろう・・・、わからないです。。 @Kishikawa Katsumi の言うように、アプリ+アプリテストの形ならできそう
Avatar
Kishikawa Katsumi 2/26/2018 8:51 AM
8:52 AM
^ のHost Applicationてとこ。TestHost.appは何の実装もないAppDelegateだけの空っぽのアプリで構わないです。テスト中に生きてさえいればいい。
Avatar
おぉ、なるほど!ありがとうございます😃
Avatar
Kishikawa Katsumi 2/26/2018 8:53 AM
swift testの場合はわからないです。HOST_APPっていう環境変数がきくかもしれない(たぶんきかない)。 (edited)
8:55 AM
KeychainAccessの場合はKeychain APIはデバイスとシミュレータで挙動が異なるのでデバイスでテストしたい、Frameworkはデフォルトでロジックテストなのでデバイスでは動かない、というのと、キーチェーンの共有などをテストするにはProvisioning ProfileやEntitlementsが必要でそれはテストバンドルでは指定できない、という問題を解決するためにホストアプリを使用したテストを行っています。
Avatar
Framework を TimeProfile に繋いでデバッグできるようにするために別の Workspace を作って command-line アプリを置いていたのですが、project 設定を色々変えた影響からか動作がおかしくなってしまいました😥 objc[29923]: Class _TtC8Dispatch16DispatchWorkItem is implemented in both /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftDispatch.dylib (0x1018f7530) and /Users/taketo1024/Library/Developer/Xcode/DerivedData/TimeProfile-aryrvmqtlkmqgqbautymimyzbktk/Build/Products/Debug/TimeProfile (0x1005c6820). One of the two will be used. Which one is undefined. こういうのがたくさん出て実行はできるのですが print の結果がおかしくなります😥 workspace は SwiftyAlgebra/Workspace/Sandbox/TimeProfile/ 下にあります。 https://github.com/taketo1024/SwiftyAlgebra/tree/TimeProfile (edited)
Contribute to SwiftyAlgebra development by creating an account on GitHub.
Avatar
Kishikawa Katsumi 3/12/2018 10:41 AM
@Taketo Sano Command Line Toolはバンドルを持てないので、DynamicFrameworkを自身に持つことはできないところを、Run Pathを変更してリンクできるようにしているという状況ですね。でSwift Standard LibraryがSwiftyAlgebraとTimeProfileのそれぞれにStatic LinkしているのでDuplicatedということです。
😃 1
10:42 AM
とりあえず問題の切り分けのために TimeProfileターゲットでSWIFT_FORCE_DYNAMIC_LINK_STDLIB=YESSWIFT_FORCE_STATIC_LINK_STDLIB=NOをUser Defined Settingで追加してみてください。
10:43 AM
で、プロファイルを取りたいということで配布したいというわけじゃなさそうなので上記の方法でもまあいいと思うんですけど、基本的にはCommand Line ToolじゃなくてMac AppにしてそれにDynamicLinkする形で使う方が素直な挙動になります。
Avatar
なるほど、やってみます、ありがとうございます🙇
10:52 AM
ちなみに MacApp にすれば Workspace を別にする必要もないんでしょうか?
Avatar
Kishikawa Katsumi 3/12/2018 10:56 AM
Workspace を別にするっていうのはどっちにしろ必要なさそうですけど、何が問題でそうしたんですか?Workspaceも場合によっては不要です。少し上に書いてあるようなホストAppを使ってUnitTestがしたいというくらいの用途なら同じプロジェクトでターゲットを増やすだけでもOKです。
10:57 AM
デモアプリとかPlaygroundを用意する場合はWorkspaceあった方がいいです。
Avatar
おぉなるほど😵
10:58 AM
あ、はい、Playground を置くために workspace にしています。
Avatar
Kishikawa Katsumi 3/12/2018 10:58 AM
でも別に複数のWorkspaceを使い分ける必要はないと思います。
10:59 AM
Workspace SwiftAlgebra.xcproj HostApp Playground.playground DemoApp.xcproj (edited)
10:59 AM
^ こんな感じのでいいと思いますよ。
Avatar
了解です、やってみます😄
Avatar
Kishikawa Katsumi 3/12/2018 11:01 AM
上の図でいうと、Playground.playgroundとDemoApp.xcprojは単体で実行するものなので独立させてWorkspaceに入れる、HostAppはユニットテストの一部みたいなものでユーザーは意識する必要ないので、本体プロジェクトに入れてしまえ、という意図があります。
Avatar
おぉ、 UserSetting を変更する方法で動きました、ありがとうございます!!!
Avatar
Kishikawa Katsumi 3/12/2018 3:13 PM
上の説明、正しくないですね。正確にはCommand Line Toolはバンドルを持てないのでSwiftの「標準ライブラリ」をバンドルに含むことができなくて、SwiftyAlgebraが標準ライブラリを参照しようとして見つからないのが最初のエラー。rpathをXcodeの/usr/libに向けてSwiftyAlgebraが標準ライブラリを見つけられるようにしたのが佐野さんの対処で、それだと動くけどCommand Line Toolに静的リンクされている標準ライブラリと衝突するのでそのエラーのログが出てしまうという状態(移植性も失われる)。
Avatar
Kishikawa Katsumi 3/13/2018 3:56 AM
最近関わりを持ったプロジェクトで、Model、ViewModel、ViewControllerがあり、それぞれModelの変更をViewModelが、ViewModelの変更をViewControllerが監視していて、ReactiveCocoaによってバインディングされています。 ViewModelの変更によって呼ばれるメソッドがちょっと長くて、 func updateTableView() { ... tableView.reloadData() // 1 ... tableView.scrollTo(latestIndexPath) // 2 ... } のようになっています。
3:56 AM
このとき、(おそらく)1と2の間にModelが更新されて、2のメソッド呼び出しでIndexPathが合わなくてクラッシュするということが起こっています。 (おそらく、と書いたのは再現できたわけじゃないけど、コードを見る限りそうとしか思えない。)
3:56 AM
updateTableView()はメインスレッドで呼ばれるけど、Modelの変更はバックグラウンドスレッドで頻繁に変更される。
3:57 AM
私はViewModelをイミュータブルにして、変更通知と変更通知の間で変わらないようにすべし(変更通知のたびにイミュータブルなViewModelを生成して渡す)、とアドバイスしたのですが、他に良い方法ありますか?
Avatar
omochimetaru 3/13/2018 4:00 AM
とりあえずスレッド問題なら Model <- ViewModel の購読を .observeOn(MainScheduler.instance) はさんで、メインスレでしか事が起こらないようにすれば問題は解決しませんか?
Avatar
RACでtableViewは沼だなぁ、、
Avatar
omochimetaru 3/13/2018 4:01 AM
1と2の間に別スレッドからindexPathがずれてるとするとそもそもUIKit系に非メインスレから干渉してるってことでそれ自体規約違反な気がしますが何か勘違いしてるかな
Avatar
単純に、tableView delegateが取りに行くタイミングと、indexPathの参照のタイミングの間に
4:02 AM
dataSourceが変更されてるという話で
Avatar
Kishikawa Katsumi 3/13/2018 4:02 AM
updateTableViewはメインスレッドでしか動かないんですけど、そこから参照しているViewModel(Modelは切れてるはず)がどんどん更新されているという。
Avatar
dataSourceの変更はそれだけで毎回reloadするようにして、そのほかの処理とは分離するのが賢そうです (edited)
Avatar
Kishikawa Katsumi 3/13/2018 4:04 AM
で、それでいうとModel->ViewModel
4:05 AM
間をメインスレッドでしか呼ばれないようにするというのはそれはアリな気がします。
Avatar
omochimetaru 3/13/2018 4:05 AM
似たようなシチュエーションで、アーキテクチャは昔ながらの方法だったけど、TableViewのいろんなタイミング問題が出て、最後のスクロールする処理を、なんとかフラグとか立てて後回しにするようにしたりしたことはありますね
Avatar
Kishikawa Katsumi 3/13/2018 4:05 AM
ただまあなんとなくそれは直し方が一時しのぎ的かなあという。
4:07 AM
全体的にこのプロジェクト、マルチスレッド系のよくわからないバグをロックを取るなどの一時的な対処で複雑にしてる感があって、それよりはイミュータブルを積極的に使った方が根本的に簡単になるんじゃないか、と考えています。
Avatar
あるある
4:08 AM
わかるわかる
Avatar
Kishikawa Katsumi 3/13/2018 4:10 AM
良い例がないかと思ってKickstarterのOSS版を調べると
4:11 AM
https://github.com/kickstarter/ios-oss/blob/master/Kickstarter-iOS/Views/Controllers/ActivitiesViewController.swift#L80-L85 ViewModelの更新ではDataSourceというまた別のデータを更新していて、tableView.reload()はその後でいつ呼んでもいい感じになっていたので、こういう方式が良いんじゃないかと。
ios-oss - Kickstarter for iOS. Bring new ideas to life, anywhere.
Avatar
reactive+table/collection viewはとにかく難易度が高くて
4:12 AM
基本的にはまずtable/collection使わなくて出来ないかを考えるべきだと思っています
Avatar
Kishikawa Katsumi 3/13/2018 4:13 AM
一般的なiOSアプリでUITableViewを使わないのは難しくないですか。
Avatar
無限長データはもうどうしようもないので、そういうのが出てきてから
4:14 AM
使うべきところと使うべきでないところがあるので
Avatar
Kishikawa Katsumi 3/13/2018 4:15 AM
Reactiveと組み合わせると難しいというのは同意します。 少しそこから議論を進めて、
4:16 AM
UITable/CollectionViewの場合はViewModelとUIコンポーネントを直接バインディングするのは問題があることが多い、ということじゃないですかね。
Avatar
そうですね
Avatar
Kishikawa Katsumi 3/13/2018 4:16 AM
ビューと直接バインディングするんじゃなくてデータソースとバインディングするのがベターなのでは。
Avatar
そもそもcellの生成時しかアクセスが保証できないものなので
4:17 AM
そこの性質を間違えると大変なことになります
Avatar
omochimetaru 3/13/2018 4:17 AM
綺麗にやるんだったら、 scrollToの宛先をViewModelのパラメータとして常に持つ?
4:18 AM
その宛先もビュー側のインデックスパスじゃなくて、エントリを特定できるモデル側のキーで持つ。
Avatar
因みにRxSwiftはまさしく、dataSourceとバインディングする仕組みになっていて
4:19 AM
RxDataSourcesは良く出来ています
Avatar
Kishikawa Katsumi 3/13/2018 4:25 AM
@omochimetaru scrollTo()のタイミングで補正するってことですかね。
Avatar
omochimetaru 3/13/2018 4:34 AM
岸川さんの言う通り、ViewModelをイミュータブルにして、どんどん新しい塊で流すようにするなら、 その情報だけからビューの命令を発行する必要があるので、 scrollToの宛先をそこでビューモデルのプロパティの一つとして持つ必要があると思ったんですが
4:34 AM
それだったらリストの要素も塊に入ってるから、やっぱりインデックスで持てばよいですね。
4:37 AM
その、テーブルビューと対応したデータソースを持つってパターンを想像してます UITableViewへの実際の操作は必ずそれを経由するようにする
4:37 AM
@tarunon RxDataSourcesでお行儀よくスクロールコントロールするときはどうなるの?
Avatar
indexPath→モデルの取得のみ出来る構造になっていて、あんまりそういうことをするようには出来ていないように感じるなぁ
5:17 AM
dataSource.sectionModelsに格納されているモデル群があるから
5:17 AM
必要があるならExtension生やして出来るようにする感じだと思う
5:17 AM
中身がEquatableなら処理追加してモデルからindexPath引く実装とかは作れる
Avatar
omochimetaru 3/13/2018 5:18 AM
なるほど
5:20 AM
この話しばらく考えてたんだけど、 UITableViewからすると、reloadData()とscrollTo()がメインスレッドから立て続けに呼ばれた場合、 tableView.dataSourceのデリゲートメソッドを呼び出してセルを引っ張ったり、 内部でrowからscroll座標を計算したりする一連の手続きの間に、 tableView.dataSourceのデータは変化しちゃいけない ってのがまずある話よね
Avatar
例えばTwitterのTLでセルのモデルとしてTweetとクリックするとあいだのツイートを読み込むアレとがあったとして、 アレまでスクロールする機能を作りたいなら、アレのindexPathをdataSourceに問い合わせてあればスクロールする(その間ロックする)みたいな機構を作る
5:21 AM
まあ結構泥臭くなると思うよ
Avatar
Kishikawa Katsumi 3/13/2018 5:21 AM
そうですね。言い換えるとdataSourceに変更があったらreloadData()(またはinsert/removeRows)を呼んで同期しなければならない。 (edited)
👀 1
Avatar
omochimetaru 3/13/2018 5:22 AM
でも今は、dataSourceとして見てるオブジェクトが、VCなのかproxyなのかわからんけど、とにかく、その先のViewModelオブジェクトのプロパティを参照する形で実現されていて、 その一連のタイムシーケンスの間に変更が起きてしまう
5:22 AM
まず第一にそういう割り込み変更が起こらないアーキテクチャにはなっている必要があって(そうじゃないと個別にケアしないといけなくなる)
5:25 AM
そうするとDataSourceオブジェクトを一個定義して、そこに一任するのは筋が良いと思う。
Avatar
Kishikawa Katsumi 3/13/2018 6:53 AM
私の中では以前より整理できました。どうもありがとうございます。 リアクティブプログラミングとイミュータブルはセットだと考えてるんですけどあまりそれを示した記事が見つからなくて、どう話したものか、
6:53 AM
と思ってまして。
Avatar
条件付き extension でより強い型の場合にオーバーライドしたいケースが割とあるんですが、こういうのってできないんでしょうか。 例えば行列式の計算で、一般の環では置換を使って定義しておいて、体の場合は掃き出しを使う、というようにより強い型で実装をオーバーライドしたいケースがあります。
8:53 AM
(あれ、もしかして普通にできる?)
Avatar
protocol extensionだと、三角継承問題が発生する(superが何かわからない)のもあって今はできないです。protocol extensionのfuncのimplを、global funcとして切り出せば、やりたいことは出来ると思います。あくまでextensionはエイリアスとして働く、みたいな感じ。
11:33 AM
「今は」なのかそもそもそういう指針なのかはどっちだったかな、
Avatar
なるほど、struct ではできて protocol ではできないんですね、ありがとうございます。
4:24 PM
protocol extensionのfuncのimplを、global funcとして切り出せば
おぉ、やってみます😺
Avatar
protocol A where Y.X == Self, Y.Z == Z { // Redundant same-type constraint 'Self.Z' == 'Self.Y.Z' associatedtype Y: B associatedtype Z } protocol B where X.Y == Self, X.Z == Z { // Redundant same-type constraint 'Self.Z' == 'Self.X.Z' associatedtype X: A associatedtype Z } struct AA: A { typealias Y = BB typealias Z = Int } struct BB: B { typealias X = AA typealias Z = String // !? } このコードが通ってしまうんですが(本来は BB.Z == AA.Z == Int でなければいけない)protocol の associatedType の相互参照周りはまだバグバグしいんでしょうか? (edited)
Avatar
しかも B, BB のペアを別ファイルに置くとコンパイルできない😨
Avatar
バグってますねー。ABAABB で循環しているので、循環まわりはまだまだ安定していない印象
7:39 AM
一応 4.1 だと
7:39 AM
test.swift:11:8: error: 'A' requires the types 'AA.Z' (aka 'Int') and 'BB.Z' (aka 'String') be equivalent struct AA: A { ^ test.swift:11:8: note: requirement specified as 'Self.Z' == 'Self.Y.Z' [with Self = AA] struct AA: A { ^
Avatar
@Taketo Sano プレリリースの Swift を手軽に試すなら↓便利ですよ。現状なら、 Languages から Swift 選んで Swift HEAD 4.2-dev (LLVM ... を選択です。 https://wandbox.org/ (edited)
🙏 1
Avatar
おぉ、ありがとうございます!
Avatar
wandboxってメンテされてない印象がある。
Avatar
Xcode 9.2使用中なのですが、コメントに書いたクラス名にジャンプ出来るようにする書き方ってありますか?
Avatar
目的としてはViewModelとViewControllerを簡単に行き来したかったのですが
8:16 AM
takasek/XCJumpToTests: the Xcode Source Editor Extension / AppleScript to jump files of Implementation⇄Tests https://github.com/takasek/XCJumpToTests こちらのAppleScriptを改変したら目的は達成出来ましたm( )m (edited)
XCJumpToTests - the Xcode Source Editor Extension / AppleScript to jump files of Implementation⇄Tests
🙌 3
👏 2
swift 1
Avatar
ご活用いただきありがとうございます!
🙏 1
Avatar
@takasek おお、こちらにいらっしゃるとは!かなり快適になりました!ありがとうございます〜🙏
😉 1
Avatar
protocol ViewProtocol: class { associatedtype Presenter: PresenterProtocol var presenter: Presenter! { get } } protocol PresenterProtocol: class { associatedtype View: ViewProtocol weak var view: View? { get } } 1ファイルにこれ書くとbuild通るんですけど、それぞれのprotocolを別のファイルに書くとbuild通らないのがよくわからないんですがどうしてなんでしょう? (edited)
Avatar
型の相互参照?
9:07 AM
型Aを書いたファイルAをビルドするのに型Bを定義したファイルBが必要、でも型Bを定義したファイルBをビルドするのに型Aを定義したファイルAが必要的な?
Avatar
あーそうか😩
Avatar
Kishikawa Katsumi 3/28/2018 9:09 AM
私の環境(Xcode 9.2、適当なiOSプロジェクト)では別のファイルにプロトコルを書いてもビルドできましたね。
9:10 AM
念のため、プロトコルを実装するクラスも別のファイルに書いてみましたけどエラーは起こらなかったです。
Avatar
ありゃ?同じくXcode9.2でSwift4.0で新規プロジェクトにさっきのコードを別ファイルで書いてエラーになってるんですよね、自分の環境は
Avatar
試しにBuild Phaseでファイルのビルド順番を変えてみたらどうでしょう?
Avatar
順番変えてもエラーのままですね
Avatar
Kishikawa Katsumi 3/28/2018 9:14 AM
私の方は変わらずエラーなしです。ついでにDebug/Release構成も切り替えて試しました。
Avatar
Cross-reference to module 'Protocol'
こうあるから出来なそう
9:15 AM
@Kishikawa Katsumi クリーンしてビルドしなおしたら通らなくなったりしませんか?
Avatar
Kishikawa Katsumi 3/28/2018 9:15 AM
すみません。ツールチェーンが4.1でした😅
Avatar
Avatar
4.1ならいける!ということ? (edited)
Avatar
なんでいけるんだろ
Avatar
Kishikawa Katsumi 3/28/2018 9:16 AM
4.1なら通りますね。
Avatar
そういうもん?
Avatar
omochimetaru 3/28/2018 9:16 AM
バグがなおったからでは。
Avatar
そうか。
Avatar
なるほど
Avatar
なるほど
Avatar
omochimetaru 3/28/2018 9:17 AM
コンパイラがクラッシュするのは単純にコンパイラのバグで
9:17 AM
ただそれが直る過程で、できるようになるものと、できないようになるものは、ある
Avatar
ありがとうございます🙇
Avatar
protocol A where Y.X == Self, Y.Z == Z { // Redundant same-type constraint 'Self.Z' == 'Self.Y.Z' associatedtype Y: B associatedtype Z } protocol B where X.Y == Self, X.Z == Z { // Redundant same-type constraint 'Self.Z' == 'Self.X.Z' associatedtype X: A associatedtype Z } struct AA: A { typealias Y = BB typealias Z = Int } struct BB: B { typealias X = AA typealias Z = String // !? } ↑こちら Xcode 9.3 beta で試してみたらちゃんとエラーになりました👍
Avatar
Taketo Sano 4/1/2018 1:13 PM
protocol A, B で同じメソッド名のデフォルト実装があって、それを conform する struct X がどっちのものを使うかを指定するのってできないですよね?(明示的にオーバーライドしないといけない?)
1:13 PM
protocol は associatedtype つきのものです。
Avatar
出来ないですね、extensionの実装は、条件が厳しいものが優先され、同じである場合はambiguousで失敗します
Avatar
Taketo Sano 4/1/2018 1:14 PM
了解です、ありがとうございます🙏
Avatar
Swift repl で変数に値を代入するとき、複雑な struct だと中身丸ごとダンプしたような出力がされますが、この表示を抑えたりカスタマイズしたりってできるんでしょうか?(既出でしたらすみません)
Avatar
CustomDebugStringConvertibleとかどうでしょ?できるのかな
Avatar
@swiftbot CustomDebugStringConvertibleでいけるっぽいですね struct A { var name = "a" } print(A()) struct B { var name = "b" } extension B: CustomDebugStringConvertible { var debugDescription: String { return "{\(name)}" } } print(B())
Avatar
swiftbot BOT 4/4/2018 1:05 PM
Swift version 4.1 (swift-4.1-RELEASE)
1:05 PM
A(name: "a") {b}
Avatar
CustomPlaygroundLookableというのもあって、いじって遊んでたけど多分deprecatedになるw(もうなったかな?)
Avatar
CustomDebugStringConvertible とは別に CustomStringConvertible というのもありますので用途によって使い分けてください。
Avatar
Taketo Sano 4/4/2018 2:34 PM
おぉ、CustomDebugStringConvertible ってそのためのものだったのですか…!ありがとうございます🤗
2:36 PM
4> let a = A() a: A = { name = "a" } 5> struct B { 6. var name = "b" 7. } 8. 9. extension B: CustomDebugStringConvertible { 10. 11. var debugDescription: String { 12. return "{\(name)}" 13. } 14. } 15> let b = B() b: B = { name = "b" } あれ、REPL だとやっぱり変わらないような🤔
Avatar
REPLはだめなんですねぇ
Avatar
Taketo Sano 4/4/2018 2:36 PM
あ、そうなんですか😥
Avatar
他に何かないかな
Avatar
Taketo Sano 4/4/2018 2:37 PM
大きめの struct だとドバーッって出て来て困りますよね🎅
Avatar
Kishikawa Katsumi 4/4/2018 3:50 PM
REPLやPlaygroundはMirror使ってるんじゃなかったかな。
Avatar
Kishikawa Katsumi 4/4/2018 3:58 PM
うーん、customMirrorは使われなかったです。。。
Avatar
お手上げ感
Avatar
Taketo Sano 4/4/2018 4:07 PM
When using Swift REPL, every time I assign a value to a variable, it displays a whole dump of the value. I want to suppress this, because when it is an instance of a large struct, it completely blo...
Avatar
:set set print-decls false で行けるそうです😆
👍 6
Avatar
Taketo Sano 4/7/2018 2:12 PM
SwiftyMath というものを作っていて、REPL を使ってインタラクティブに計算を走らすようなことができるようになりました👍
2:14 PM
Windows ユーザにも気軽に使ってもらえるように、Web IF を用意してサーバ側で Swift REPL を動かすというようなことをしてみたいと思うのですが、そういうことは可能なのでしょうか?
Avatar
omochimetaru 4/7/2018 2:14 PM
できると思いますよ
2:14 PM
プロセスを立てて
2:14 PM
stdin/stdout/stderrをストリームとして制御することができるので
2:15 PM
サーバサイドでそういうサービスを回せば。
Avatar
Taketo Sano 4/7/2018 2:15 PM
なるほど!
Avatar
omochimetaru 4/7/2018 2:15 PM
ただswiftbotみたいな一発実行だと
Avatar
Taketo Sano 4/7/2018 2:15 PM
今時のイケてる構成だとどんな風にするのがいいんでしょう?
Avatar
omochimetaru 4/7/2018 2:15 PM
Dockerに閉じ込めてタイムアウトもつけてってやってリソース制限できるけど
2:16 PM
REPLだとプロセスが生きてる必要があるからそこらへんのリソースクォータの制御がどうやるのがいいのかパッと思いつかない・・・
Avatar
Taketo Sano 4/7/2018 2:16 PM
ふむふむ
Avatar
omochimetaru 4/7/2018 2:16 PM
一発実行ならDockerはまさにそういう使い捨ての仮想環境を作って捨てるためのしくみなのでちょうどよいのですけど。
2:17 PM
まーやるとしたらその制御側で、REPLの行の応答にタイムアウト制御するのを自分で書くとかかな・・
Avatar
Taketo Sano 4/7/2018 2:17 PM
今作っているものを、研究室の先生や他大の学生にも使ってもらおうとしているのですが、非エンジニアにとってインストールのハードルがあることや windows しかもってなかったりということがあるので、web で動かしたい気持ちが高まっています。
2:17 PM
↑プロセス制御はFoundationのこれでできます。
2:18 PM
うーんそれだったら
2:18 PM
BashOnWindowsで動かすのが手っ取り早いとは思います。
2:18 PM
インストールの手間はあるけど。
Avatar
Taketo Sano 4/7/2018 2:18 PM
それが結構なハードルでしてw
2:18 PM
僕が苦労する分には構わないというスタンスで、他の人にはできるだけ楽させてあげたいw
Avatar
omochimetaru 4/7/2018 2:19 PM
なるほど・・・
2:19 PM
まあそういう身内の展開だったら
2:19 PM
とりあえずクォータとか無視して
2:19 PM
↑のProcessとかで作ってみるのが早いかも?
Avatar
Taketo Sano 4/7/2018 2:19 PM
ふむふむ!
Avatar
omochimetaru 4/7/2018 2:19 PM
ようするに問題になるのはAWSとかでホストしてるとして
2:19 PM
無限ループを書かれただけで
2:19 PM
CPU課金が死んじゃうってことですね
2:19 PM
あとは無限にファイルを書き出すループとか。
Avatar
Taketo Sano 4/7/2018 2:19 PM
はいはい、それは避けたいですね。
2:20 PM
でも悪意なくそういうコードを書いてしまうリスクはありますねw
Avatar
omochimetaru 4/7/2018 2:20 PM
そうなんだよなあw
Avatar
Taketo Sano 4/7/2018 2:21 PM
ちなみに severside swift をホストするのは IBM のやつがいいんでしょうか?(その辺りも全然知らない)
Avatar
omochimetaru 4/7/2018 2:21 PM
Vaper + VaperCloudが楽というのは聞きますね
Avatar
Taketo Sano 4/7/2018 2:21 PM
ほほぅ!
Avatar
omochimetaru 4/7/2018 2:22 PM
Simple and flexible Vapor hosting, Built for Vapor by Vapor. One command to get your Vapor app running in the Cloud.
Avatar
Taketo Sano 4/7/2018 2:23 PM
全編mac版。Vaporのバージョンは2.0.4 Vaporの始め方やHello Worldまでの手順は記事がいっぱいあるので割愛します。 サーバーサイドに慣れてないSwift開発者だけど、自分でもできそう! ...
Avatar
omochimetaru 4/7/2018 2:23 PM
ひろしさんだ。
2:26 PM
あーそっか
2:26 PM
別にウェブ側もSwiftで作る必要はないですね
2:26 PM
REPLプロセスとの媒介は別にNodeJSとかRubyでも作れるし。
Avatar
Taketo Sano 4/7/2018 2:26 PM
そうですね
Avatar
omochimetaru 4/7/2018 2:27 PM
Contribute to swift-playground development by creating an account on GitHub.
2:27 PM
岸川さんのplaygroundはnodeだった。
Avatar
Taketo Sano 4/7/2018 2:27 PM
おぉ、こんなものが。
2:28 PM
デプロイされてるのはこっち。
Avatar
Taketo Sano 4/7/2018 2:28 PM
axa,
2:28 PM
なるほど。
2:28 PM
REPL でなくてもこういう形式でもいいのかもですね。
Avatar
omochimetaru 4/7/2018 2:30 PM
それならこれをほぼそのままデプロイしつつ
2:30 PM
SwiftyMathをもったコンテナをDockerで用意して
Avatar
Taketo Sano 4/7/2018 2:30 PM
https://repl.it/site/languages/swift こんなのもあるんですね。
Swift Compiler, REPL, and IDE. Compile and run code online. Host and share your code.
Avatar
omochimetaru 4/7/2018 2:31 PM
最初からimportできるようにしておくのが手っ取り早いですね
2:31 PM
おお。
Avatar
Taketo Sano 4/7/2018 2:34 PM
while true { } って書いてみましたがずっと動いてるようですw
Avatar
omochimetaru 4/7/2018 2:35 PM
マジか・・
Avatar
Taketo Sano 4/7/2018 2:42 PM
とりあえず色々とありがとうございます、もう少し自分でも調べてみます 🙌
Avatar
@Taketo Sano なんとタイムリーな😀 https://swift-tweets.github.io/#timetable Swift Tweets 2018 Spring 2018-04-14 21:00 JST "Swift Playgroundを作ろう" @k_katsumi
😆 1
Avatar
Kishikawa Katsumi 4/7/2018 10:18 PM
@taketo1024#1158 私の中期的な展望をいうと、おそらく私のも含めて今の現存するSwiftのWeb SandboxはXcodeのPlaygroudやSwift REPLのように1行ごとに評価するようにはなってないはずなので、そういう風に結果を返せるようにしたい。 ただ、Swift REPLのような対話的な環境を用意するのは解決する問題が多いので(オンラインシェルとかターミナルというのはすでにあるのでそれと同じような仕組みでいけるなとも思っていますが。無限ループ対策は一定のレスポンスや操作がなかったら切れるとかそういうの)とりあえず毎回入力されたコードを最初から実行しなおす、そして各行を全部評価するという方法にすれば、実際は対話的実行じゃないけどそういう風に見えるはず、みたいな。
10:19 PM
@taketo1024#1158 あとSwiftbotに適当にフレームワーク足してもいいなと思ってるんで試しにSwiftMath足してみましょうか? (edited)
Avatar
エクセレント🤩👉👉
11:06 PM
@Kishikawa Katsumi おぉ、是非お願いします😆
11:08 PM
自分のケースで REPL にしたいのは、一行の実行にそれなりに時間がかかることが想定されるためです。
Avatar
Kishikawa Katsumi 4/7/2018 11:10 PM
なるほど。
Avatar
まとまった情報を持ったものをドガッと計算して、そこから色々調べるというような。
Avatar
Kishikawa Katsumi 4/7/2018 11:11 PM
それなら、単に現在の仕組みで実行結果を前のに積み上げて(下げて?)表示していくだけで良い感じになりそうです。
😆 1
Avatar
preconditionFailureやfatalErrorを使った場合に、そこを通るテストを書きたい場合ってどうしてますか?
Avatar
これ絶対絶対beginner-helpに書く内容じゃないだろw
Avatar
Kishikawa Katsumi 4/9/2018 7:10 AM
私はそれはテストしないで諦めています。諦めているというのはたまにテストしたいことはあるということです。 解決策はpreconditionFailureをラップするか条件によって分岐するくらいしかないと思います。
7:11 AM
たまにテストしたいことはありますが、preconditionFailureやfatalErrorの部分をややこしくするのもアレだなあと思って、諦めています。
Avatar
テスト対象のコードに直接fatalError書くのやめてthrowしてcatchした所でfatalErrorするようにするくらいしか思い浮かばないけどオーバーキル感ある
7:20 AM
enum UnrecoverableError: Error { case preconditionFailure } struct Hoge { func テストしたいメソッド() throws { if true { throw UnrecoverableError.preconditionFailure } } } let hoge = Hoge() do { try hoge.テストしたいメソッド() } catch let error as UnrecoverableError { switch error { case .preconditionFailure: preconditionFailure() } } うーんやりたくない
Avatar
Kishikawa Katsumi 4/9/2018 7:21 AM
自分のコードの実行結果でFatalErrorに落ちる可能性がある部分で不安なところは、それまでに至る部分でテストを書くって感じかなあ。
Avatar
func hoge() -> Never { return unsafeBitCast((), to: Never.self) } guard 1 == 0 else { hoge() } print("離脱してないよー")
7:23 AM
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=EXC_I386_GPFLT). The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation. * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) * frame #0: 0x00007fffaba7aa9b libobjc.A.dylib`_objc_msgSend_uncached + 11 frame #1: 0x00007fff9865d231 Foundation`-[NSPlaceholderString initWithString:] + 107 frame #2: 0x000000010c5d4007 PlaygroundLogger`function signature specialization <Arg[0] = Dead> of static PlaygroundLogger.LoggingPolicyStack.get() -> PlaygroundLogger.LoggingPolicyStack + 151 frame #3: 0x000000010c5cdf22 PlaygroundLogger`function signature specialization <Arg[1] = Owned To Guaranteed and Exploded> of playground_log_hidden + 98 frame #4: 0x000000010c5cd65b PlaygroundLogger`playground_log_hidden + 27 frame #5: 0x000000010c5fc094 $__lldb_expr82`hoge() at MyPlayground.playground:2
7:23 AM
コンパイルは通って実行時に死んだ
7:25 AM
unsafeBitCast((), to: Never.self) これでNever型のインスタンス作れるの @Yuta Saito が気づいた
Avatar
Xcode でカバレッジ見れるじゃないですか、容赦なく preconditionFailure のところでお前テストしてないやんけってお怒りになってしまったので
7:26 AM
いいway有るかなーと思った次第
Avatar
カバレッジ太郎だ
Avatar
Kishikawa Katsumi 4/9/2018 7:27 AM
それはしょうがないので基本的には気にしない。カバレッジマニアでもなければ。。。
Avatar
本気でやろうとはあんまり思ってなくてふと気になったのでここに書きました
7:27 AM
↑それ最初に書けって話やな、すみません
Avatar
Kishikawa Katsumi 4/9/2018 7:28 AM
私もまあ89%みたいな時にそこを通せれば、、、みたいに思うことはあるんですけど、無意味やなと思ってやめます。
Avatar
それはそれとして、Xcodeのカバレッジはこれ直接Function呼んでなかったら怒ってるのかしら、ブレークポイント貼れば通ってるのに怒り心頭みたいなの結構ある
Avatar
Kishikawa Katsumi 4/9/2018 7:29 AM
^ 通ってるはずなので通ってないと表示されてる? (edited)
Avatar
異常系のユニットテストの書き方のコツみたいなのはありますか?
8:51 AM
Coredataのデータファイルがぶっ壊れてた時に正しく終了できるようにしたものをテストするとかってどうしてます?
8:52 AM
壊れたデータファイルを用意したりするんでしょうか?
Avatar
Kishikawa Katsumi 4/9/2018 8:53 AM
壊れたものを用意する必要があるならそうします。が、アプリケーションの場合はそこまでする必要はないと思います。 開けなかった場合に返ってくる状態、エラーなりnilなり、を与えて、それが意図した通りに処理されるかどうかを確認します。
😀 1
8:54 AM
CoreDataそのもののテスト、みたいな場合は壊れたファイルを用意することは妥当だと思います。
8:55 AM
あと、CoreDataのファイルをダウンロードしてくるとか、そういう場合も妥当かもしれません。
8:55 AM
大抵はアプリケーションで生成したファイルを使う、ということだろうから、そうそう壊れたものが存在することはないとして扱うと思います。
Avatar
Kishikawa Katsumi 4/9/2018 9:04 AM
まあ蛇足なんですけど、基本的にユニットテストは外部に依存しないほうがいい、というのにくわえて、あまり大がかりだったりややこしい仕組みにしないほうがいいです。 というのはプロダクトコードと一緒に継続的にメンテナンスしていくものなので、めっちゃテストできるすごい仕組みのユニットテスト、みたいなのは作ったきりになりがちです。
😀 1
Avatar
例えば func coodinator() -> NSPersistentStoreCoordinator { do { return try makeCoodinator() } catch { //エラー処理 アラートを出してterminate } } という関数であった場合 func coodinator(_ f: () throws -> NSPersistentStoreCoordinator) -> NSPersistentStoreCoordinator { do { return try f() } catch { //エラー処理 アラートを出してterminate } } にしてテスト時にthrowする関数を与えるような感じ? だとおかしいですね... ちょっと考えてみます
Avatar
こうゆう部分をテストしたいと思ったのは「アラート出してterminate」の処理が間違っていたために、「原因不明のクラッシュをしてした」という報告をユーザーさんからもらってしまったためです
Avatar
Kishikawa Katsumi 4/9/2018 9:33 AM
ユニットテストで防止するのはあまり向いてないように見えますね。間違ってたっていうのは具体的にどんな感じですか?
Avatar
メインスレッドでないスレッドでNSAlertをmodalで表示してしまった
9:36 AM
です
Avatar
Kishikawa Katsumi 4/9/2018 9:37 AM
その間違いをユニットテストで防止するのは向いてないですね。
9:37 AM
一般的に。
9:38 AM
重要な画面で「こういう場合には必ずこういう画面が出なければならない」みたいなものはやる価値がありそうですが。
9:39 AM
今ならメインスレッドチェッカーがあるから、自動化するとしたら、UI Testを使ってすべての画面を経由するような操作のテストを定期的に実行するとか、ですかねえ。
Avatar
omochimetaru 4/9/2018 9:39 AM
やったことないけどiOSのUIテスト機能とかで画面操作のレベルでシナリオ書いて、ダイアログが出ることって検証できるのかな?
Avatar
Kishikawa Katsumi 4/9/2018 9:40 AM
^ できますよ。
Avatar
XCUITestでボタン操作は割りと出来る雰囲気
Avatar
omochimetaru 4/9/2018 9:40 AM
おー、じゃあ、関数の粒度じゃなければ、この話自体の再発防止テストは書けそう。
Avatar
Kishikawa Katsumi 4/9/2018 9:41 AM
そうですね。この例のような、手作業の操作では確認しにくい、ユニットテストもしにくい、ものはUIテストは向いてると思います。
9:42 AM
ただUITestはユニットテストと違って、テスト対象のプログラムは全く操作できないので、意図的にエラーになる状態を用意するのが難しいです。
9:42 AM
壊れたファイルを用意する必要があります。
Avatar
omochimetaru 4/9/2018 9:45 AM
なるほど。
Avatar
KIFみたいなのを使えば,ユニットテストなので壊れたファイルを差し込みつつ,画面操作のあとアラートにある文字がstaticTextで出ていてOKが押せる,みたいなのそこそこ書けます
Avatar
今のこれに限定するなら「Errorを受け取ってメインスレッドでNSAlertだしてteminateする」関数をつくってそれをテストすればいいのかな?
9:55 AM
メインスレッド以外から呼び出すテスト付きで
9:58 AM
UIテストはなにをテストすればいいのかというところからわからない
Avatar
Kishikawa Katsumi 4/9/2018 10:03 AM
UIテストはユニットテストより難しいです。
UIテストはなにをテストすればいいのかというところからわからない
というのは真理をついていて、UIテストはどういう状態になったら成功か失敗かをまず定義するのが難しいです。
10:04 AM
XcodeのUIテストでいうと、Assertメソッドもないので、^で正しい(間違い)状態を定義した上で、どうAssertionすべきか、というところから始めないといけないので、大変です。
Avatar
後出しですみません アプリケーションは 1、起動したら第三者が提供しているサーバーからデータを取ってくる 2、変換してCoreDataに突っ込む 3、CoreDataの変化を受けてデータが表示/更新される というものです 今回の件ではユーザーさんは起動後何もしていない段階でクラッシュしています
10:09 AM
なのでUIテストではどうにもならない?のかな?
10:12 AM
発言遅くてすみません理解が追い付いてないのでじっくり考えてます
Avatar
Kishikawa Katsumi 4/9/2018 10:14 AM
全然非同期のやりとりで構わないですよ 😄 私もちょうど帰るのでしばらく離れますし。
Avatar
!!!!
11:59 AM
terminateしたらテスト通らないじゃん!
11:59 AM
根本的なところを見落としてた
Avatar
#if TEST func myPrecondition() -> Never { ... } #else func myPrecondition<T: FatalObjectCompatible>() -> T { return T.fatal() } #endif
1:08 PM
こういうの使ってTest側にFatalObjectCompatibleの実装を作って、後は呼び出したことを検知できればまあなんとかなるかなー
1:09 PM
書くところはreturn myPreconditionみたいにして
1:14 PM
preconditionは有り得ない状態なのでproductionコードを多少汚しても許されるのではという気持ちが発生している
Avatar
ビルドに時間かかってるとこの特定ってどうやってます?
Avatar
The Swift type-checker remains a performance bottleneck for compile times, though it has improved tremendously over the past two years. You could even say the type-checker has gone from being drunk to sober. To help users debug these issues, awhi...
12:15 PM
これで設定した閾値以上コンパイル時間かかっている箇所に警告が出るようになるはずです。
12:18 PM
コマンドラインからのビルドで、もっと網羅的に見たいなら、 https://github.com/apple/swift/blob/master/docs/CompilerPerformance.md#how-to-diagnose-compilation-performance-problems-Xfrontend -debug-time-function-bodies-Xfrontend -debug-time-expression-type-checking が使えます。
swift - The Swift Programming Language
Avatar
BuildTimeAnalyzer-for-Xcode - Build Time Analyzer for Swift
Avatar
おぉ、ありがとうございます!
Avatar
ちょうど、改善していきたいなって思っていたところだったので参考にします!!
Avatar
@giginet って人がこんなのも作ってますね http://techlife.cookpad.com/entry/2016/12/28/112806
技術部モバイル基盤グループの@giginetです。 我々のチームでは、iOS/Androidアプリの認証、決済、ロギングと言った基幹部分の開発のほか、各事業部のモバイルエンジニアの開発効率を...
Avatar
手前味噌ですがBuildTimeAnalyzer-for-Xcodeより便利だと思います 😎
😁 2
5:08 AM
まあやってることは同じなんだけど
Avatar
お助け願います 🙇 import Foundation public protocol MapType { associatedtype Domain associatedtype Codomain init(_ fnc: @escaping (Domain) -> Codomain) func applied(to x: Domain) -> Codomain } public struct Map<Domain, Codomain>: MapType { internal let fnc: (Domain) -> Codomain public init(_ fnc: @escaping (Domain) -> Codomain) { self.fnc = fnc } public func applied(to x: Domain) -> Codomain { return fnc(x) } } public protocol EndType: MapType where Domain == Codomain { static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return Self{ x in x } } public func composed(with g: Self) -> Self { return Self { x in // ココで EXC_BAD_ACCESS self.applied(to: g.applied(to: x)) } } } extension Map: EndType where Domain == Codomain { } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(Element.identity) { (res, f) in res.composed(with: f) } } } let f = Map { x in 2 * x } let g = [f, f].composed() print(g.applied(to: 0)) 関数(写像)を抽象化した MapType と、具体型の Map: MapType を作り、特に Domain(定義域) と Codomain(値域) が一致している場合に EndType: MapType という subprotocol を用意して、配列に入った関数をまとめて合成できるようにしたいと思って上のようなコードを書いたのですが、実行時に EXC_BAD_ACCESS が出てしまいます 👼 protocol で関数値を取る init を置いてるのがまずいんでしょうか…?わかる方いたら教えてください 🙏 (edited)
Avatar
@Taketo Sano 本質的な回答ではないですが、最近の Swift では FooType より FooProtocol という命名の方が主流だと思います。標準ライブラリがそのように変わったので。↓など。 https://developer.apple.com/documentation/swift/iteratorprotocol
Avatar
omochimetaru 4/16/2018 9:56 AM
@swiftbot import Foundation public protocol MapType { associatedtype DomainType associatedtype CodomainType init(_ fnc: @escaping (DomainType) -> CodomainType) func applied(to x: DomainType) -> CodomainType } public struct Map<Domain, Codomain>: MapType { internal let fnc: (Domain) -> Codomain public init(_ fnc: @escaping (Domain) -> Codomain) { self.fnc = fnc } public func applied(to x: Domain) -> Codomain { return fnc(x) } } public protocol EndType: MapType where DomainType == CodomainType { static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return Self { x in x } } public func composed(with g: Self) -> Self { return Self { x in // ココで EXC_BAD_ACCESS self.applied(to: g.applied(to: x)) } } } extension Map: EndType where Domain == Codomain { } public extension Array where Element == Map<Int, Int> { func composed() -> Element { return self.reduce(Element.identity) { (res, f) in res.composed(with: f) } } } let f: Map<Int, Int> = Map { x in 2 * x } let fs: Array<Map<Int, Int>> = [f, f, f] let g: Map<Int, Int> = fs.composed() let t: Int = g.applied(to: 1) print(t)
Avatar
swiftbot BOT 4/16/2018 9:56 AM
Swift version 4.1 (swift-4.1-RELEASE)
9:56 AM
8
Avatar
omochimetaru 4/16/2018 9:57 AM
Arrayのwhereを concrete type で書いたら動く・・・
9:58 AM
@Taketo Sano コンパイラのバグな気がしますが踏む条件がまだわからないです 直感的には Self.init のところでバグを踏んでそうだけど、コードやアイデア自体は特にまずいことはやってないように見えます。
😥 1
Avatar
@swiftbot import Foundation public protocol EndType where DomainType == CodomainType { associatedtype DomainType associatedtype CodomainType init(_ fnc: @escaping (DomainType) -> CodomainType) func applied(to x: DomainType) -> CodomainType static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return Self { x in x } } public func composed(with g: Self) -> Self { let fnc: (DomainType) -> DomainType = { x1 in let x2: DomainType = g.applied(to: x1) let x3: DomainType = self.applied(to: x2) return x3 } return Self.init(fnc) } } public struct Map<Domain>: EndType { internal let fnc: (Domain) -> Domain public init(_ fnc: @escaping (Domain) -> Domain) { self.fnc = fnc } public func applied(to x: Domain) -> Domain { return fnc(x) } } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(Element.identity) { (res, f) in res.composed(with: f) } } } let f: Map<Int> = Map { x in 2 * x } let fs: Array<Map<Int>> = [f, f, f] let g: Map<Int> = fs.composed() let t: Int = g.applied(to: 1) print(t)
Avatar
Swift version 4.1 (swift-4.1-RELEASE)
10:06 AM
8
Avatar
EndTypeとMapTypeの分離をやめてEndTypeだけで書くとこれも動く。
10:08 AM
[omochi@omochi-iMac-PC43 et]$ swift a.swift 0 swift 0x00000001062c5ffa PrintStackTraceSignalHandler(void*) + 42 1 swift 0x00000001062c53b6 SignalHandler(int) + 966 2 libsystem_platform.dylib 0x00007fff55398f5a _sigtramp + 26 3 libsystem_platform.dylib 0x000000000000ffff _sigtramp + 2865197247 4 libsystem_platform.dylib 0x0000000109f2a4fb _sigtramp + 3032028603 5 libsystem_platform.dylib 0x0000000109f2a7c4 _sigtramp + 3032029316 6 libsystem_platform.dylib 0x0000000109f2a922 _sigtramp + 3032029666 7 libsystem_platform.dylib 0x0000000109f2ac61 _sigtramp + 3032030497 8 libswiftCore.dylib 0x000000010c0a894b _T0s8SequencePsE6reduceqd__qd___qd__qd___7ElementQztKctKlF + 603 9 libswiftCore.dylib 0x0000000109f2a8a7 _T0s8SequencePsE6reduceqd__qd___qd__qd___7ElementQztKctKlF + 4259848631
10:08 AM
10 libswiftCore.dylib 0x0000000109f2a187 _T0s8SequencePsE6reduceqd__qd___qd__qd___7ElementQztKctKlF + 4259846807 11 swift 0x0000000103606c0a llvm::MCJIT::runFunction(llvm::Function*, llvm::ArrayRef<llvm::GenericValue>) + 362 12 swift 0x000000010360d30c llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, char const* const*) + 1004 13 swift 0x0000000102928735 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 48709 14 swift 0x000000010291ae64 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7908 15 swift 0x00000001028cf8b5 main + 18917 16 libdyld.dylib 0x00007fff5508a015 start + 1 17 libdyld.dylib 0x000000000000000a start + 2868338678 Stack dump: 0. Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret a.swift -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -color-diagnostics -module-name a Segmentation fault: 11
Avatar
むむぅ
Avatar
omochimetaru 4/16/2018 1:06 PM
本命はバグ報告+修正待ちとして、その場しのぎで書き方を工夫すれば動く方法があるかも?
Avatar
ConditionalConformanceって確か、ExistentialへのCastはFailしますよね
1:42 PM
そのあたりでしくじってる気がします
1:47 PM
@swift-4.1.3 // // main.swift // Math // // Created by tarunon on 2018/04/16. // Copyright © 2018年 tarunon. All rights reserved. // import Foundation public protocol MapType { associatedtype Domain associatedtype Codomain init(_ fnc: @escaping (Domain) -> Codomain) func applied(to x: Domain) -> Codomain } public struct Map<Domain, Codomain>: MapType { internal let fnc: (Domain) -> Codomain public init(_ fnc: @escaping (Domain) -> Codomain) { self.fnc = fnc } public func applied(to x: Domain) -> Codomain { return fnc(x) } } public protocol EndType: MapType where Domain == Codomain { static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return _identity(of: Self.self) } public func composed(with g: Self) -> Self { return _composed(with: self, g) } } func _identity<E: EndType>(of type: E.Type = E.self) -> E { return E { x in x } } func _composed<E: EndType>(with f: E, _ g: E) -> E { return E { x in f.applied(to: g.applied(to: x)) } } extension Map: EndType where Domain == Codomain { } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(_identity(of: Element.self)) { (res, f) in _composed(with: res, g: f) } } } let f = Map { x in 2 * x } let g = [f, f].composed() print(g.applied(to: 1)) (edited)
Avatar
4
Avatar
@Taketo Sano
1:48 PM
global func 作ってProtocol Extensionはそこのエイリアスにすると通りました (edited)
Avatar
@swift-4.1.3 import Foundation public protocol MapType { associatedtype Domain associatedtype Codomain init(_ fnc: @escaping (Domain) -> Codomain) func applied(to x: Domain) -> Codomain } public struct Map<Domain, Codomain>: MapType { internal let fnc: (Domain) -> Codomain public init(_ fnc: @escaping (Domain) -> Codomain) { self.fnc = fnc } public func applied(to x: Domain) -> Codomain { return fnc(x) } } public protocol EndType: MapType where Domain == Codomain { static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return Self { x in x } } public func composed(with g: Self) -> Self { return Self { x in // ココで EXC_BAD_ACCESS self.applied(to: g.applied(to: x)) } } } extension Map: EndType where Domain == Codomain { public static var identity: Map<Domain, Codomain> { return Map { x in x } } public func composed(with g: Map<Domain, Codomain>) -> Map<Domain, Codomain> { print("Map.composed self: \(type(of: self))") return Map { x in exit(0) // return self.applied(to: g.applied(to: x)) } } } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(Element.identity) { res, f in print("Array.composed res: \(type(of: res))") return res.composed(with: f) } } } let f = Map<Int, Int> { x in 2 * x } let g = [f, f].composed() print(g.applied(to: 0))
Avatar
Array.composed res: Map<Int, Int> Map.composed self: Map<Map<Int, Int>, Map<Int, Int>> Array.composed res: Map<Int, Int> Map.composed self: Map<Map<Int, Int>, Map<Int, Int>>
Avatar
↑これヤバくないですか? res.composed の直前の resMap<Int, Int> なのに、直後の composed の中の selfMap<Map<Int, Int>, Map<Int, Int>> になってる。
🙄 2
Avatar
これなんでPrint2回ずつ走ってるんだ
3:05 PM
あ、一回目は通るのか
Avatar
global func作る方は壊れてなかった
3:51 PM
conditional conformanceを別のconditionに利用すると崩壊なのかな
3:54 PM
+ Selfかな
Avatar
再現できた
Avatar
@swift-4.1.3 protocol A { static func foo() } extension Dictionary: A where Key == Value { static func foo() { print(type(of: self)) } } extension Array where Element: A { static func foo() { Element.foo() } } [String: String].foo() [[String: String]].foo()
Avatar
Dictionary<String, String>.Type Dictionary<Dictionary<String, String>, Dictionary<String, String>>.Type
Avatar
2つのGenericsパラメータを==で束縛してConditional Conformanceを使い、それを他のGenerics ParameterのConditionに利用して関数を呼ぶとTypeが壊れる (edited)
Avatar
むむむ…
1:24 AM
なるほど 😮
1:25 AM
単純なケースで再現できてよかったです(どこで壊れるのか分からないといつ世界が崩壊するか分からず不安なので 😅
1:28 AM
でも == 束縛パターン結構使ってるから不安だなぁ 😵
Avatar
omochimetaru 4/17/2018 1:28 AM
global func 作ってProtocol Extensionはそこのエイリアスにすると通りました
とりあえずこれでその場はしのげた?
Avatar
今からやってみます > global func
Avatar
omochimetaru 4/17/2018 1:29 AM
@swiftbot help
Avatar
swiftbot BOT 4/17/2018 1:29 AM
Usage: @swiftbot [--version=SWIFT_VERSION] [--command={swift, swiftc}] [--options=SWIFTC_OPTIONS] `​`​` [Swift Code] `​`​` Examples: @swiftbot `​`​` print("Hello world!") `​`​` @swiftbot --version=4.0.3 `​`​` print("Hello world!") `​`​` @swiftbot --command=swiftc --options=-dump-parse `​`​` print("Hello world!") `​`​` Subcommands: @swiftbot versions: show available Swift toolchain versions @swiftbot contribute: show repository URLs @swiftbot help: show help
Avatar
omochimetaru 4/17/2018 1:29 AM
@swiftbot --version=latest import Foundation public protocol MapType { associatedtype Domain associatedtype Codomain init(_ fnc: @escaping (Domain) -> Codomain) func applied(to x: Domain) -> Codomain } public struct Map<Domain, Codomain>: MapType { internal let fnc: (Domain) -> Codomain public init(_ fnc: @escaping (Domain) -> Codomain) { self.fnc = fnc } public func applied(to x: Domain) -> Codomain { return fnc(x) } } public protocol EndType: MapType where Domain == Codomain { static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return Self{ x in x } } public func composed(with g: Self) -> Self { return Self { x in // ココで EXC_BAD_ACCESS self.applied(to: g.applied(to: x)) } } } extension Map: EndType where Domain == Codomain { } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(Element.identity) { (res, f) in res.composed(with: f) } } } let f = Map { x in 2 * x } let g = [f, f].composed() print(g.applied(to: 0))
Avatar
swiftbot BOT 4/17/2018 1:29 AM
Swift version 4.2-dev (LLVM d14a2b25f2, Clang c38020c511, Swift 22530b922f)
1:29 AM
/usr/bin/swift[0x41336e4] /usr/bin/swift[0x4133a26] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7fd883d3e390] /usr/lib/swift/linux/libswiftCore.so(+0x42ea92)[0x7fd87eefca92] /usr/lib/swift/linux/libswiftCore.so(swift_getGenericMetadata+0x687)[0x7fd87eef6f87] [0x7fd88416d90a] [0x7fd88416d296] [0x7fd88416d35c] [0x7fd88416d41c] [0x7fd88416d65c] [0x7fd88416d715] [0x7fd88416d15e] /usr/bin/swift[0x10335de] /usr/bin/swift[0x1037702] /usr/bin/swift[0x4f21d2] /usr/bin/swift[0x4d9b77] /usr/bin/swift[0x4d503c] /usr/bin/swift[0x48a3ad] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fd882468830] /usr/bin/swift[0x487c09] Stack dump: 0. Program arguments: /usr/bin/swift -frontend -interpret /usercode/main.swift -disable-objc-interop -module-name main Segmentation fault (core dumped)
Avatar
omochimetaru 4/17/2018 1:29 AM
最新でもだめか。
Avatar
Kishikawa Katsumi 4/17/2018 1:50 AM
いつのスナップショットか表示した方がいいかな。今は2018-04-15のスナップショット。
Avatar
omochimetaru 4/17/2018 1:54 AM
それが出たほうがうれしいです。
Avatar
global func でやれば確かに通るようになりました。
1:56 AM
2つのGenericsパラメータを==で束縛してConditional Conformanceを使い、それを他のGenerics ParameterのConditionに利用して関数を呼ぶとTypeが壊れる
1:56 AM
これを気をつけるのかなり難しい…😥
Avatar
omochimetaru 4/17/2018 2:01 AM
早く直るように祈るしか無いですね tarunonのissueスレッドにSwiftyMathのリンク貼って、実際困る!って書き込むとか。
Avatar
ワロタ
Avatar
「いま俺もそれで困ってたんだよ!」的なw
Avatar
マッチポンプ感が半端ないですが、困ってるのは事実だしりんたろさんが見てるなので問題はないと思いますw
😳 2
Avatar
問題を簡易化してくれて助かります🙇‍♂️Map のままのバグレポだと優先度かなり下がりそうなのでw
Avatar
コメントしときました 👍
👍 2
Avatar
@Taketo Sano これ困ってるのどっちかといえば7450の方じゃないですか?Crash側は7450です
Avatar
原因は同じっぽいってことで…w
Avatar
masterで https://bugs.swift.org/browse/SR-7450 がクラッシュしなくなっていることを確認しました。
👏 3
💖 1
Avatar
はやい、昨日コメントついてましたね
2:25 AM
丁度話をしていたとか
Avatar
omochimetaru 4/18/2018 2:51 AM
はや!
Avatar
エクセレント!!!!!
Avatar
これを使うために @Taketo Sano さんもSwiftコンパイラをビルドすることに…😁 (↓この手順に従うだけで簡単にコンパイラをビルドできます。) https://qiita.com/rintaro/items/2047a9b88d9249459d9a
Swift がオープンソースになってしばらく経ちます。 コンパイラや標準ライブラリの開発に手を出してみたいけど、リポジトリを落とした後どうしていいかわからない!という方のた...
Avatar
おw
Avatar
omochimetaru 4/18/2018 1:40 PM
使うだけなら一晩待ってればswift.orgからdaily snapshotがダウンロードできますよ
Avatar
omochimetaru 4/19/2018 5:33 AM
@Taketo Sano April 18, 2018のsnapshotをxcodeでtoolchain設定したら動きました https://swift.org/download/#snapshots Trunk Development (master) > Download > Xcode
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
Avatar
conditional extensionに生やした関数が、conditionの外でも補完出ちゃうんですが同じ人いませんか? & 対策あれば教えてください。
Avatar
struct拡張だと出てprotocol拡張だと出ない気がしてきた
Avatar
↑予想通りstruct拡張をやめてprotocol拡張にしたら出なくなりました。🙋
Avatar
GomaIsNiceGuy 4/27/2018 12:42 AM
こんにちは。Swiftでコマンドライン引数を取得したい場合、どうゆう書き方をすればいいのですか??
Avatar
CommandLine.arguments で配列取れませんでしたっけ?
12:43 AM
CommandLine.argumentsですね
Avatar
GomaIsNiceGuy 5/1/2018 3:34 AM
ありがとうございます
Avatar
GomaIsNiceGuy 5/6/2018 6:58 AM
An internal error occurred. Editing functionality may be Limited というエラーが出ました。初めて見るエラーで、全くわからないです。
6:59 AM
I just created one new cordova ios project via CLI, and i opened that project in Xcode 7.1 and while running on simulator am getting some error on mainViewController.xib, if we clicked on that erro...
7:00 AM
このサイトの1番上の答えを翻訳しながら行ったのですが、trash it. で、どれをどう消せばいいかわからないです。下の追記みたいな所にファイル自体は消すなって書いてあることはわかるんですが、、、
Avatar
Developers.IOは、AWS、iOS/Androidアプリ、ビッグデータ、Alexa等の最新技術情報からリモートワークや働き方に関する記事まで多彩なトピックを紹介するクラスメソッドのオウンドメディア...
Avatar
GomaIsNiceGuy 5/6/2018 7:06 AM
試してみますありがとうございます🙇‍♂️
Avatar
Kishikawa Katsumi 5/6/2018 7:07 AM
開発に支障がなければ気にしなくてもいいです。
Avatar
GomaIsNiceGuy 5/6/2018 7:16 AM
出来ましたー!!
😁 1
7:17 AM
storyboardが青色の枠線だけになってしまってすごいことになってました、、
Avatar
1つのStoryboardファイルに大量のViewControllerとかAutoLayoutの制約があるとよく起きますね、それ。
Avatar
GomaIsNiceGuy 5/6/2018 8:04 AM
そうなんですね、、 開発初めてすぐなのでボタンとかしか置いてないんですけどねwwww なんで起きたのかイマイチわかんないです、、
Avatar
MacがStoryboardを画面に表示するときスペック的に時間かかる場合も出たりしたので、まぁ出るときは出るとしかw (edited)
Avatar
GomaIsNiceGuy 5/6/2018 9:49 AM
なるほど ありがとうございます🙏
Avatar
swift package generate-xcodeproj で作ったプロジェクトでフォルダの順番を入れ替えたりすると Xcode クラッシュしません? 😥
Avatar
omochimetaru 5/15/2018 2:15 AM
フォルダ並び替えるとクラッシュするxcodeprojは僕も踏んだことあります
2:15 AM
SwiftPMから作った時だったかどうか覚えてないですが
2:16 AM
なんかいろいろ消したり作り直してるうちに治っちゃった記憶がある
Avatar
is辛い 😥
Avatar
Folder reference使ってますか?
Avatar
Folder reference …とは何かを知りません 😅 generate-xcodeproj で作ったばかりのプロジェクトでフォルダの順番を変えようとすると落ちます 😥
Avatar
Folder ReferenceとそうじゃないGroupがあって怪しいファイル移動をするとすぐ落ちるみたいなのはよく踏みます。
2:17 AM
ファイルツリーに出てるフォルダのアイコンが水色だったらFolder referenceですが
Avatar
あぁ、それは確かにあります。
Avatar
Folder reference経由だとビルドターゲットに含められなかったから違うかも。
2:17 AM
おっ。
Avatar
generate-xcodeproj で勝手に追加されます。
Avatar
Kishikawa Katsumi 5/15/2018 2:18 AM
Xcode 9からのXcodeのグループを実際のディレクトリ構造に反映する機能が怪しいんじゃないかな。
2:18 AM
リネームとか中途半端に終わることがたまにある。
😇 2
Avatar
青い奴を外してから移動してみましたが、やはり落ちました 💣
Avatar
辛い
Avatar
pbxproj 直接編集で頑張りますw
Avatar
omochimetaru 5/15/2018 2:19 AM
リネームといえばクラス名をリネームする時に ClassName.swift もリネームされかけるけど絶対失敗する
Avatar
ファイル名も変えてくれるのか
2:20 AM
いや、変えてくれないのかw
Avatar
omochimetaru 5/15/2018 2:20 AM
最近はファイル名を手動で直してからrefactorしている
2:20 AM
一度も成功したことが無いw
Avatar
Kishikawa Katsumi 5/15/2018 2:20 AM
よく失敗するね。だいたい実際のリネームは成功するけどプロジェクトのファイル名がそのままで赤くなることが多いです。
😇 1
Avatar
omochimetaru 5/15/2018 2:20 AM
それですそれです。
Avatar
Kishikawa Katsumi 5/15/2018 2:20 AM
私の場合。
Avatar
渋い
Avatar
それなんかいけるパターンもあって謎すぎる
Avatar
リネーム機能、使ったこと無いな。。
2:21 AM
Find and replaceでやっちゃう
Avatar
omochimetaru 5/15/2018 2:21 AM
いけることもあるのか。
Avatar
あるね
Avatar
Kishikawa Katsumi 5/15/2018 2:22 AM
失敗するのはともかく中途半端な状態で終わるのなんとかしてほしい。失敗なら全部失敗で。。。 (edited)
Avatar
自分の場合は XVim2 のかみ合わせもあって入力モードのままだと落ちるとかもあったけど…
2:22 AM
そうですね。いっそ失敗してロールバックしてほしい…
Avatar
omochimetaru 5/15/2018 2:22 AM
あー、リネームは成功してるのか。
2:23 AM
プロジェクトの方のエントリ情報が更新されてないから
2:23 AM
赤くなるのか。
2:23 AM
いや、逆か?どっちかだけが変わる。
Avatar
Kishikawa Katsumi 5/15/2018 2:23 AM
そうそう、ロールバック。老化で言葉出てこない。。。
Avatar
omochimetaru 5/15/2018 2:23 AM
@hiragram Refactor > Rename 便利だよ
Avatar
ちゃんと動いてない報告受けまくったあとその凶悪なレコメンドやばない
Avatar
omochimetaru 5/15/2018 2:24 AM
「ファイル名を先に手動で変更する」だけでちゃんと使えるぜ。
Avatar
草草の草
Avatar
omochimetaru 5/15/2018 2:24 AM
コードの書き換えの方はちゃんと動く。
Avatar
Kishikawa Katsumi 5/15/2018 2:24 AM
実際のファイル名が変更される部分以外はかなり感動的に動作します。
Avatar
たしかにファイル名以外はちゃんと動いてる
Avatar
Kishikawa Katsumi 5/15/2018 2:25 AM
Storyboardの中の変更もばっちりだし。
Avatar
あ゛
Avatar
それめっちゃ便利
Avatar
それはうれしい
Avatar
omochimetaru 5/15/2018 2:25 AM
たしかに。自作Viewとかちゃんとなる。
Avatar
typealias でRename動かなかったり、 func test() { typealias Alias = String _ = Alias(12) // こっちをリネーム } (edited)
😇 1
2:27 AM
結構バグはあります。
2:28 AM
ユーザ側ではなく、いったん宣言側に移動して、そこからリネームかけると正常に動きやすい。
😃 1
Avatar
metal 2 やってい方いますかね?
Avatar
Realm databaseのSwift版って開発遅れてたり、放置されてたりするんです・・・?
というのを聞かれまして、何か知っている方いましたらよろしくお願いします。 その理由として、 ・Documentに書いてあるSwiftのバージョンが1.2ぽい ・LatestのDocumentにあるリンクからダウンロードできるサンプルソースを解凍してできあがる realm-swift-3.5.0/examples/ios/swift-4.1 のディレクトリ内にあるProjectの設定がSwift3.3 らしいです。
🤔 1
Avatar
Kishikawa Katsumi 5/18/2018 8:53 AM
@shunkun 先月に3.5 https://github.com/realm/realm-cocoa/releases/tag/v3.5.0 がリリースされているので特に放置されてることはないですね。 根拠とされているドキュメントについては、更新もれなどはまあRealmに限らず割とよくある話かと思います。
realm-cocoa - Realm is a mobile database: a replacement for Core Data & SQLite
Avatar
ありがとうございます! ドキュメントは割とよくある話ですよね。 更新されていると言ってみます!
Avatar
どなたかご存知な方がいらっしゃれば相談させていただきたいです。 Cocoapodsライブラリに依存したCarthageライブラリを配布することはできないのでしょうか? Carthageでpodsライブラリの依存関係の解消まではできないため、podsライブラリもgitにプッシュしたところ、Carthageライブラリのcheckout、buildまではできました。しかし、そのCarthageライブラリを利用しようとすると、podsライブラリが参照できなかったという旨のdyld: Library not loadedの実行時エラーが出ます。
Avatar
できなそうな印象です
12:22 PM
そういうことを試したことないな、、
Avatar
pods対応しかされてないライブラリに依存するcarthageライブラリを提供するために、自前フォークしてCartfileを追加してる例を見たことがある気がします
Avatar
フォークしてCarthage対応すればできますね
Avatar
やはり自前で対応するしかなさそうですね。該当ライブラリはGPUImage、SwiftLint、SwiftGenなので SwiftLint、SwiftGenはCarthage移行はできないのでhomebrewのものを使うとしてGPUImageをなんとかできるかチャレンジしてみます。
Avatar
あれ、GPUImageってCarthage対応してなかったっけ。昔使った記憶が
12:31 PM
いや、むかしCocoaPodsつかってたかも
Avatar
swiftlintはそもそもシステムインストールするものだと思いますが、リント定義のバージョンズレなどを避けたいからですか? それともそれを使った自前の前処理ツールみたいなものを作るため?
Avatar
対応しているはずなんですが、carthage updateでエラーがでてしまうようで、、、
12:32 PM
こちらの理由です
リント定義のバージョンズレなどを避けたいからですか?
👌 1
Avatar
どんなエラーじゃろ。
Avatar
こんなエラーです $ carthage update --platform ios *** Fetching GPUImage *** Checking out GPUImage at "0.1.7" *** xcodebuild output can be found in /var/folders/62/nrp34pc96t550_hhml86hmwrr_q2rc/T/carthage-xcodebuild.MYLmCm.log *** Building scheme "GPUImageFramework" in GPUImage.xcodeproj Failed to write to /Users/snakagam/Desktop/MyLibrary/Carthage/Build/iOS/GPUImage.framework: Error Domain=NSCocoaErrorDomain Code=260 "The file “GPUImage.framework” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///Users/snakagam/Desktop/MyLibrary/Carthage/Checkouts/GPUImage/build/ArchiveIntermediates/GPUImageFramework/BuildProductsPath/Release-iphoneos/GPUImage.framework, NSFilePath=/Users/snakagam/Desktop/MyLibrary/Carthage/Checkouts/GPUImage/build/ArchiveIntermediates/GPUImageFramework/BuildProductsPath/Release-iphoneos/GPUImage.framework, NSUnderlyingError=0x7f870a806a90 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
12:34 PM
“GPUImage.framework” couldn’t be opened
Avatar
うーん?
12:35 PM
なんだろう
12:36 PM
デスクトップでやってるのとか関係ないよなあ
Avatar
こちらの事例と似ているのですが、SYMROOTの削除では解決できませんでした https://github.com/Carthage/Carthage/issues/2389
carthage install method: [ ] .pkg, [ ] homebrew, [ ] source which carthage:/usr/local/bin/carthage carthage version: 0.29.0 xcodebuild -version: Xcode 9.2 Build version 9C40b Are you using --no-bui...
Avatar
Podsまで突っ込んでおいたりすればいけなくはないかもです (edited)
12:58 PM
でも場合によるかもしれない
1:02 PM
SYMROOTの件は、そのライブラリ側で削除する話なので、
1:03 PM
チェックアウトされてるGPUImageの0.1.7ではそれが対応されていないとかではないでしょうか (edited)
Avatar
SYMROOT消したら通りました
1:04 PM
あと、Podを使いたくない理由がxcodeprojに手を入れられたくない、っていう話なら参考になるかもしれないです https://qiita.com/kateinoigakukun/items/c9062caea630c71b4fc1
リポジトリのswiftlintのバージョンを固定したい時に。 Carthageはバイナリの配布をサポートしていないのでCocoaPodsで管理する。 が、他のライブラリをCarthageで管理している場合、バイ...
Avatar
お、ほんとですか
1:08 PM
SYMROOTの件は、そのライブラリ側で削除する話なので、 チェックアウトされてるGPUImageの0.1.7ではそれが対応されていないとかではないでしょうか
フォークして対応した方は新しいバージョンのタグを切りました
SYMROOT消したら通りました
こちらの差分と同様の対応でしょうか https://github.com/shtnkgm/GPUImage/commit/5e179f80b84837b38a8da731032c6ccc0df6ed02#diff-756457dc85f13450b3dfba2cbc1465e5
(edited)
Avatar
僕はそれで通りました
Avatar
なにかやり方がおかしいのかな。。。
Avatar
うーむ 🤔
1:21 PM
shtnkgm/GPUImage0773513209ae9f066db82497fd2342e0241d4fa2は通りました
Avatar
なんと!ちなみにcarthageバージョンはいくつでしょうか?
Avatar
0.29.0ですー
Avatar
同じですね
1:24 PM
違いがわからない 😇
Avatar
ちなみにXcodeのバージョンいくつですか?
Avatar
Version 9.3 (9E145)です
Avatar
同じだ。。。
Avatar
うーむ、 *** Cloning GPUImage *** Checking out GPUImage at "0.1.10" *** xcodebuild output can be found in /var/folders/62/nrp34pc96t550_hhml86hmwrr_q2rc/T/carthage-xcodebuild.5AWMmm.log *** Building scheme "GPUImageFramework" in GPUImage.xcodeproj Failed to write to /Users/snakagam/Desktop/MyLibrary/Carthage/Build/iOS/GPUImage.framework: Error Domain=NSCocoaErrorDomain Code=260 "The file “GPUImage.framework” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///Users/snakagam/Desktop/MyLibrary/Carthage/Checkouts/GPUImage/framework/build/ArchiveIntermediates/GPUImageFramework/BuildProductsPath/Release-iphoneos/GPUImage.framework, NSFilePath=/Users/snakagam/Desktop/MyLibrary/Carthage/Checkouts/GPUImage/framework/build/ArchiveIntermediates/GPUImageFramework/BuildProductsPath/Release-iphoneos/GPUImage.framework, NSUnderlyingError=0x7fa56e662420 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Avatar
あとはCarthageのDerivedDataを消すくらい??
Avatar
ちなみにこれは問題ないでしょうか https://github.com/Carthage/Carthage/issues/2220#issuecomment-377465217
BranchMetrics/ios-branch-deep-linking carthage package (https://github.com/BranchMetrics/ios-branch-deep-linking) seems to have trouble with 0.26.2, it builds fine, but the final copy step fails. I...
Avatar
ありがとうございます。uniqueに設定されていましたので問題なさそうです (edited)
1:33 PM
DerivedData削除しても同様のエラーでした🙇 rm -rf ~/Library/Developer/Xcode/DerivedData/
Avatar
Kishikawa Katsumi 5/21/2018 1:38 PM
Xcodeのビルドフェーズでpod installしたらいいんじゃないかな。 話を戻しちゃうけど。
Avatar
ライブラリ側のRun Scriptでpod installを実行する形でしょうか?
Avatar
Kishikawa Katsumi 5/21/2018 1:41 PM
いや、自分のプロジェクトです。
Avatar
うーんそもそも https://github.com/shtnkgm/GPUImage/commit/5e179f80b84837b38a8da731032c6ccc0df6ed02#diff-756457dc85f13450b3dfba2cbc1465e5 このコミットは関係なさそうです。変更してるのが、deploymen targetが4.3のターゲット(おそらくstatic library)なので、frameworkのターゲットではないので。 (edited)
Avatar
なるほど、、、ほかにSYMROOTの設定はなさそうです
Avatar
Kishikawa Katsumi 5/21/2018 2:46 PM
最初の議論から読みました。 1) 別のCocoaPodsでしか配布されてないライブラリB, C ,Dに依存した自分のライブラリAをCarthageで配布することは可能だと思いますが、 2) B, C, Dの依存の解決は使うプロジェクト自身でやってもらう必要がある、 というのが基本的な回答になるんじゃないでしょうか。 2の部分を頑張ろうとしてるように見えます。
Avatar
はい、 B, C, Dの依存の解決を行う方法がわからず、B,C,Dをpodsでの導入ではなくhomebrewやcarthage導入にする方法を検討していましたが、そのうちのGPUImageのCarthage対応がうまくできずという感じです。 B, C, Dの依存の解決は使うプロジェクト自身でやる方法が具体的にまだ理解できてないです。プロジェクトのビルド前にライブラリA側のpodfileを参照してpod installできればよさそうなのですが。 podsライブラリをすべてライブラリAのリポジトリにpushしておくという方法の場合、利用時に実行時エラーとなりました。
Avatar
Kishikawa Katsumi 5/22/2018 1:58 AM
B, C, Dの依存は実行時には存在しないので、そうなると思います。 そして、私はその解決は利用者がやるべきとする方が普通だと思います。 なので、そのライブラリAのセットアップ手順として、別途CocoaPods/Carthage/ビルド済みフレームワークなどで、B, C, Dをリンクしてください、と書いておく、とかがまあ基本かと思います。 そうはしたくないというのであれば、Carthageだとそれ以上は難しいと思います。 CocoaPodsだと任意のスクリプトを動かせる仕組みがあるのでなんとでもできますけど。
Avatar
ありがとうございます。まだ手動でリンクさせる方法が分かっていないので調べてみます。
Avatar
初めまして.Swift初心者の者です.よろしくお願いいたします! discord初心者でもありましたので使い方がおぼつかないかも知れませんがご容赦ください. Slackの方にも流させていただきましたが,Alamofireを用いてwikipediaから特定のタイトルのデータをJsonで取得しようとしましたが,エラーが発生してしまいました. 以下がSwiftのプログラムです. //parametersを定義 var parameters: Parameters = [ "action":"query", "prop":"revisions", "rvprop":"content", "format":"json", "titles":"tennis" ] var urlString = "https://en.wikipedia.org/w/api.php" //WikipediaAPIを通信する func getWiki() { Alamofire.request(urlString, method: .get, parameters: parameters, encoding: JSONEncoding.default,headers:nil) .responseJSON { response in debugPrint(response) } } 以下が出力されたエラーの部分です [Result]: FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})) [Timeline]: Timeline: { "Request Start Time": 548742968.775, "Initial Response Time": 548742970.085, "Request Completed Time": 548742970.088, "Serialization Completed Time": 548742970.106, "Latency": 1.309 secs, "Request Duration": 1.312 secs, "Serialization Duration": 0.018 secs, "Total Duration": 1.330 secs } Restlet client でAPIの動作自体を確認しましたが,上のパラメーターで無事にテニスに関する記事が取得できたので,おそらくAlamofireの使い方が間違っている可能性が高いと考えています. どなたかご教授いただけますと幸いです.どうぞよろしくお願いいたします. (edited)
Avatar
omochimetaru 5/23/2018 4:45 AM
(コードブロックはシングルクォート( ' ) ではなくバッククォート(`)ですよ。)(あ、治った) (edited)
Avatar
すみません,研究室のPCがENキーボードでバッククォートがどこかわかりませんでしたorz
Avatar
omochimetaru 5/23/2018 4:53 AM
同じクエリをCURLで発行してからjqにかけてみましたが、 ちゃんと動きますね。 プログラム自体に何か問題がありそう。 curl "https://en.wikipedia.org/w/api.php" -G -d action=query -d prop=revisions -d rvprop=content -d format=json -d titles=tennis > a.json cat a.json | jq
Avatar
同じくPlaygroundで実行してみましたが、貼られたコードは正常に動きましたね。 (edited)
Avatar
omochimetaru 5/23/2018 4:56 AM
あ〜AlamofireのPlaygroundとかあるのか。
Avatar
いや、自分はgithubからalamofireのproject取って来て、そこにPlaygroundぶち込んでimportしましたw (公式Playgroundあるのかな…) (edited)
Avatar
omochimetaru 5/23/2018 4:59 AM
なるほど
Avatar
QiitaのAPIにクエリを投げた時は日本語がエンコードされてない状態でしたがゲットすることができました.ここら辺が混乱している原因の一つでした...
👍 1
Avatar
先ほどの問題解決しました!多分JSONの形式ではなくStringないしはXMLのような構造でエンコーディングする必要があるみたいでした.おそらくオープンソースのサイトなのでそこまでかっちり構造決まってないようでした.
Avatar
omochimetaru 5/23/2018 7:11 AM
wikipediaのapi.phpは "format":"json"を与えることでJSONで落ちてくるみたいですけど (edited)
7:12 AM
具体的には上記のコードをどのように修正したら解決しました?
Avatar
encodingを消してresponseJSONの部分をresponseStringに変更しました.
Avatar
omochimetaru 5/23/2018 7:15 AM
なるほど。
Avatar
レスポンスは汚い形でしたが記事の内容が帰ってきました.もう少しencodingの部分を考慮すればもっと綺麗な形でレスポンスが得られると思います.もう少しやってみようと思います.
Avatar
あーこれわかった [Result]: FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(...
9:19 AM
encoding:部分不要ぽいですね。 func getWiki() { Alamofire.request(urlString, method: .get, parameters: parameters) .responseJSON { response in debugPrint(response) } } これで正しくJSON返ってくる
Avatar
ほんとですね!!試したと思っていたのですが,やっていなかったようでした.ありがとうございます!!
👍 1
Avatar
16777216 個の要素の配列を作ろうとしたら EXC_BAD_ACCESS で落ちてしまうのですが、どうしたらいいでしょう 😅
Avatar
すいません、前にも似たような質問してこちらを教えて頂いてました 🙇 https://developer.apple.com/library/content/qa/qa1419/_index.html
QA1419: Describes methods for setting the stack size of a process and/or thread.
Avatar
GomaIsNiceGuy 5/30/2018 10:29 AM
folding-cell - :octocat: 📃 FoldingCell is an expanding content cell with animation inspired by folding paper card material design. Swift UI Library by @Ramotion
10:30 AM
Developers.IOは、AWS、iOS/Androidアプリ、ビッグデータ、Alexa等の最新技術情報からリモートワークや働き方に関する記事まで多彩なトピックを紹介するクラスメソッドのオウンドメディアです。
10:31 AM
このライブラリを使って下のサイトの解説付きで作ろうと思ってるのですが、Outlet接続の項目でつまずきました。
10:32 AM
10:34 AM
10:35 AM
4つとも同じエラーが出てしまいました。
10:35 AM
よろしければ教えていただきたいです。よろしくおねがいします
Avatar
Kishikawa Katsumi 5/30/2018 10:37 AM
直接のエラーの原因はもともとweakが付いていないプロパティを、weakにしてオーバーライド(再定義)できないというものですが、 (edited)
10:38 AM
Cellを継承したViewControllerを作ろうとしているので、その辺から何か間違えてないですか?
Avatar
GomaIsNiceGuy 5/30/2018 10:52 AM
参考のサイト通りの手順で行ったのでよくわからないです..
Avatar
Kishikawa Katsumi 5/30/2018 10:57 AM
@GomaIsNiceGuy サイトの内容も確認しましたけど、上のようなコードになる手順ではないので、間違えていると思いますよ。 もう一度サイトの内容を見直してゆっくりやってみたらどうでしょうか? 特に
  • FoldingCellを継承したクラスの作成
  • Outlet接続
のセクションを読み間違えていると思います。
(edited)
Avatar
GomaIsNiceGuy 5/30/2018 11:01 AM
11:03 AM
この画面の右側が上の画像のようにバーって表示されてないのは何故なのですか??
11:04 AM
右クリック→Refarencing Outletで表示出来ました
11:04 AM
ありがとうございます
Avatar
Kishikawa Katsumi 5/30/2018 11:30 AM
Xcodeの操作は初見ではわかりにくいので、その辺が解説されている入門書を読まれると良いかもしれません。
Avatar
GomaIsNiceGuy 5/30/2018 2:04 PM
2:04 PM
なんどもすいません。このエラーはどうゆうものですか??
Avatar
omochimetaru 5/30/2018 2:36 PM
SampleCell型がselectedAnimationメソッドを持ってないって書いてあります
Avatar
Kishikawa Katsumi 5/31/2018 2:41 AM
^ となる理由はおそらくSampleCellがFoldingCellを継承できていないのだと思います。
Avatar
omochimetaru 5/31/2018 4:40 AM
(記事が古いのでライブラリのバージョンが上がっててメソッド名が変更されてるとかもありえそう)
Avatar
(1個目の引数名がデフォルトでラベルとして使うかどうかとかか
Avatar
GomaIsNiceGuy 5/31/2018 5:25 AM
解決しました。問題はメソッド名が変更されていたことでした。ありがとうございました。
5:39 AM
5:40 AM
このソースをそのまま貼って足りないライブラリimportしたんですけど、このエラーは一体なんなのでしょうか??
Avatar
Kishikawa Katsumi 6/1/2018 6:04 AM
Init(...)という関数が見つからないというエラーです。Use of unresolved identifier Initなので、Initを呼び出しているけどどこにも見つからなかった、というエラーです。 ConfigurationBlock.swiftで定義されている関数なのでそのファイルを忘れてませんか? (edited)
Avatar
GomaIsNiceGuy 6/1/2018 6:24 AM
6:24 AM
これですか??
Avatar
Kishikawa Katsumi 6/1/2018 6:26 AM
はい、そのファイルです。
Avatar
GomaIsNiceGuy 6/1/2018 6:28 AM
あ、Initありますね!
6:32 AM
加えたところAttribute can only be applied to types, not declarations
6:33 AM
to
6:33 AM
と、出てきました。
Avatar
2016年のソースだからSwift 2文法ののソースですね
6:45 AM
定義が Init(value: になっているから、使う側も今のSwiftの文法なら Init(value: で呼び出す必要がありますね、昔Swift 2までは一つめの引数がデフォルトでラベルとして使わなかったので
Avatar
omochimetaru 6/1/2018 6:46 AM
@noescape が怒られてるんじゃないか?
Avatar
Kishikawa Katsumi 6/1/2018 6:47 AM
@GomaIsNiceGuy たぶん古い解説記事やソースコードを見るより、 https://github.com/Ramotion/folding-cell 本体のリポジトリのDemoやREADMEをみた方が良いと思います。
folding-cell - :octocat: 📃 FoldingCell is an expanding content cell with animation inspired by folding paper card material design. Swift UI Library by @Ramotion
Avatar
omochimetaru 6/1/2018 6:47 AM
今だと @escaping ってクロージャ型の左側(コロンの右側)に書くけど
6:47 AM
Swift2だとラベルの左側に書いてたんだよね。
Avatar
Kishikawa Katsumi 6/1/2018 6:47 AM
Swift 2, 3, 4の違いを直していくのはまだ無理だと思います。
Avatar
GomaIsNiceGuy 6/1/2018 6:47 AM
そこは標準でついているとwarning出てたので外しました
Avatar
GomaIsNiceGuy 6/1/2018 9:08 AM
Demo見ながらやっていきます。ありがとうございました
Avatar
Swiftは,クラス変数のオーバライドはできないんですよね・・・・? 毎回言ってる気がする.
Avatar
出来るのでは
Avatar
セルのデザインを何種類か試したい時とかに使いたいんですが・・・・・.
1:42 AM
え?できんの?
Avatar
元々がget onlyならget only、 setもあるならsetも書けば出来るはず
Avatar
class ResCell: UITableViewCell { static var textViewLeftMargin: CGFloat { return 16 } } class ResCell2: ResCell { /// override static var textViewLeftMargin: CGFloat { return 8 } } これ書いたら,怒られた.static varはoverrideできんと.
1:44 AM
これ間違ってますか?
Avatar
Kishikawa Katsumi 6/2/2018 1:44 AM
static変数とclass変数は違います。
1:45 AM
staticは継承されない。
Avatar
あ、そっちか。class varにすればできるはず
Avatar
classとstaticは違うのか
1:45 AM
ごめんなさい,全然理解してない
Avatar
Kishikawa Katsumi 6/2/2018 1:46 AM
class変数は実質クラスメソッドみたいなものですね。
Avatar
今試してるんですがなんか怒られますね
Avatar
なんだろう,これはstaticは,継承によって挙動が左右されないことを保証するためにあるってことですかね
Avatar
Kishikawa Katsumi 6/2/2018 1:46 AM
上の例はComputed propertyだからclassにしたらできそうに見えますね。
Avatar
あいやいけた
1:47 AM
typoしてた、すません
Avatar
classにしたらいけました
1:47 AM
なんだろう,これはstaticは,継承によって挙動が左右されないことを保証するためにあるってことですかね 心は,こういうこと?
Avatar
Kishikawa Katsumi 6/2/2018 1:47 AM
「継承によって挙動が左右されないことを保証するためにある」かどうかはわからないですね。
Avatar
ぬう
Avatar
どっちかといえばstaticの方が使う気がする
1:48 AM
継承とかやりたい場合だけclassが出てきますけど、あんまり継承使わないから殆どstaticです
Avatar
なるほど
Avatar
class ResCell: UITableViewCell { class let textViewLeftMargin: CGFloat = 16 } classでもlet宣言はoverrideできないとかある
Avatar
ありがとうございましたー 勉強になりました.
Avatar
norio_nomura 6/2/2018 1:55 AM
class内のstaticfinal classですよね。
Avatar
意味的にも完全に一致してるのかな
Avatar
static = final class で納得
Avatar
Taketo Sano 6/2/2018 2:52 AM
(今別の質問しても大丈夫な流れです?)
Avatar
いいんじゃないですか
2:53 AM
だいたい終わったような
Avatar
Taketo Sano 6/2/2018 2:53 AM
恐縮です 🙇
2:54 AM
parametrized conformance を実現するために protocol をでっち上げて後付けで conform させるというのをやっているのですが、それを入れたことで元々問題なかったところにおかしなエラーが出て困っています 😟 https://github.com/taketo1024/SwiftyMath/blob/WTF/Sources/SwiftyHomology/Basics/ModuleObject.swift#L279 (edited)
SwiftyMath - Pure Math in Pure Swift.
2:56 AM
public protocol IntModuleObjectType: ModuleObjectType where R == 𝐙 { ... } extension ModuleObject: IntModuleObjectType where R == 𝐙 {} この 297 行目でコメントアウトしてる部分を外すと、 100 行目で Binary operator '==' cannot be applied to operands of type '_Matrix<Dynamic, Dynamic, R>' and '_Matrix<Dynamic, Dynamic, ModuleObject.R>' (aka '_Matrix<Dynamic, Dynamic, Int>') と勝手に R == Int と仮定されて怒られているようです 😟 (edited)
2:58 AM
原因や回避策など分かる方いたらご教示ください 🙇
Avatar
ブランチ名w
3:12 AM
IntModuleObjectTypeがModuleObjectTypeのconditionを持っているのが原因ぽいすね、独立させればコンパイルは通りました
3:13 AM
protocolで継承関係作ると色々なところで罠を踏むので、二つのprotocolは独立に作って、両方実装することでデフォルト実装が使えるようになる、みたいな形にしておくと罠を踏まずに済むことが多い印象があります
Avatar
Taketo Sano 6/2/2018 3:18 AM
おぉッ、やってみます。
3:21 AM
おぉ、ほんとですね…!
3:21 AM
protocol の継承使いまくってるのでいつ世界が崩壊するか分からないのは不安です 😂
Avatar
使わないようには出来ませんか?
Avatar
Taketo Sano 6/2/2018 3:23 AM
このケースでは問題ないですが、プロジェクト全体でたくさん使ってます。
Avatar
関数の宣言や実装は_Fieldみたいにアンスコつきにしておいて、利用者側に晒すprotocolをField: _Field, _EuclideanRing...のようにするとかで
3:24 AM
罠を回避しつつ使い勝手は変わらない世界を構築できるかも
Avatar
Taketo Sano 6/2/2018 3:27 AM
うーむ、なるほどです…
3:27 AM
あまり裏技使い過ぎると自分でも分からなくなりそうなので、いずれ治ることを望みつつ世界が崩壊したら随所対応してく感じにします… 😂
Avatar
Taketo Sano 6/2/2018 4:12 AM
問題なく直せました!感謝ですswiftswift
swift 1
Avatar
GomaIsNiceGuy 6/2/2018 11:36 AM
//#selectorはovjective-cだから頭に@objcをつける @objc func refreshHandler() { //deadlineTimeに1秒の遅延を追加 let deadlineTime = DispatchTime.now() + .seconds(1) DispatchQueue.main.asyncAfter(deadline: deadlineTime, execute: { [weak self] in if #available(iOS 10.0, *) { self?.tableView.refreshControl?.endRefreshing() } self?.tableView.reloadData() }) }
11:36 AM
11:36 AM
DispatchQueue.main.asyncAfter(deadline: deadlineTime, execute: { [weak self] in if #available(iOS 10.0, *) { self?.tableView.refreshControl?.endRefreshing()
11:37 AM
ってどうゆう意味ですか??
Avatar
@GomaIsNiceGuy deadline で指定された時間に main キューで execute のクロージャ式の中身を実行という意味ですね。 (edited)
2:20 PM
DispatchQueue についてちゃんと理解するためには↓あたりを読むと確実です。(もし並行処理について詳しくなければ Introduction から読んだ方が良いです。が、並行処理はそれだけで本が一冊書けるような分野なので、まずは日本語で並行処理について書かれた本を読んで概念を習得した方が良いかもしれません。) https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW1
Explains how to implement concurrent code paths in an application.
Avatar
norio_nomura 6/2/2018 2:27 PM
Concurrency Programming Guideは日本語版PDFがあります。 https://developer.apple.com/jp/documentation/ConcurrencyProgrammingGuide.pdf
🙏 1
👍 1
Avatar
ここのチャンネルで聞くべきかどうか迷いましたが、iOSアプリ開発・配布が初めてなのでここで質問させていただきます。 お客様の社内アプリをinHouse配布するのに、お客様に『iOS Developer Enterprise Program』のライセンスを取っていただいて行う予定です。 このときに、お客様の許可が得られるか、アプリがどのようなものなのか、またお客様側の知識・技術がどのくらいあるかにもよると思いますが、どのように配布すればいいか色々調べてもわかり辛く、迷っています。 サポートセンターに聞いた例を見てみても、堂々巡りになっていることもあるようなので、一度こちらでお伺いさせていただきたいと思いました。 (1)自社のアカウントをチーム管理者として登録していただいて、こちら側から定期的に更新を行う (2)ソースをそのままお渡しして、お客様側端末でコンパイルしていただく (3)証明書情報などをコンパイル時に教えていただいて、こちらでコンパイルを行う 調べてみた結果、方法としては以上のものくらいかなと考えているのですが、皆様はどのような方法を取られていらっしゃいますか。 ちなみに今回配布する予定のものは、元々Androidアプリとして作成しているものをiOS端末の普及に伴いiOS用にも移植するもので、Android版は既に6年程使っていただいています。またAndroid版は、何度か業務変更による改修も入っています。 今回のiOS版も、同じく長期間使っていただく・時折改修が入ると思うので、理想としては(1)の方法なのかなと考えてはいます。
Avatar
クライアントさんが将来的に開発ベンダーを切り替える可能性も考えると、クライアントさんにEnterpriseプログラムに入っていただいて、御社のアカウントををDeveloperとしてチームに追加していただくのがおそらく双方にとって一番楽な方法かと思います
1:54 PM
Enterpriseで配布まで試したことがまだないので具体的にどうすればいいかアドバイスできませんが、おそらくDeveloperとして追加してもIn House Distributionはできるはずかと思います 🤔
Avatar
状況とお客様側の知識とかで変わるけど、個人的に自分が楽できる方法を選ぶなら(2) お客様が「よくわからん!ビルドってなんだアーカイブってなんだ!エラー出たどうしたらいい!?」みたいな知識であれば(1)。ただこの場合、知識なくてもipa作れるように手順書作ったり、サポートすること考えると別途費用請求したい… (edited)
Avatar
(1)は(お客さんに承認はとるとして)自分で実機をDevicesに追加できるというメリットがありますね。実機デバッグで困りにくい。アプリの更新環境を作る作業はそこそこの手間なので、そこは見積もりに入れるとして。
Avatar
CI系のサービス使えるなら自動でipa作成とかまでやりたい系の内容だなー
Avatar
ご回答、有難うございます。 @lovee 証明書とかプロビジョニングプロファイルのことを考えると管理者じゃないと無理なのかと思っていたのですが、開発者でもIn House Distribution 出来るのですね。 https://developer.apple.com/jp/documentation/IDEs/Conceptual/AppDistributionGuide/ManagingYourTeam/ManagingYourTeam.html ここを見た感じだと、開発者はプロビジョニングプロファイルについては開発用のものは作れないけれども、チームのものは作れるようなので、これが配布のときに使えるんですね。 @ありぜ 今のところ、お客様の側にもシステム系の方がいらっしゃるのは把握しているのですが、どの程度なのかが微妙でして。今までのシステムに関しても、環境構築とかリリースとか保守とか完全にこちらがごっそり受け持っているため、やはり(1)が可能ならば無難なのかもしれないです。 ipa作成手順書、作ることも考えないといけなさそうです。 @hirobe 実機デバッグに関しては、基本的には開発時にこっちで端末を直接つないで落としてきてやれば良いかなと思っていたので、あまり重要視していませんでした。 ADEPでのIn Houseでの配布について、自社の場合はともかく顧客側のものを配布するとなると、証明書などを定期的に更新する必要がある部分がやはりネックになってきますね。
アプリケーションを開発、テスト、配布する作業の流れを説明しています。
Avatar
omochimetaru 6/10/2018 2:53 PM
内部利用アプリをEnterpriseビルドで提供するのはうちの会社もよくやっていますが1年に1回のリビルドが必要で、そのときにSwiftやXcodeが新しくなってるので、対応と動作チェックが必要なのは面倒ですねえ。
Avatar
証明書とかプロビジョニングプロファイルのことを考えると管理者じゃないと無理なのかと思っていたのですが、開発者でもIn House Distribution 出来るのですね。
管理者じゃないと配布用証明書が作成できないので、管理者以上の権限付与してもらわないと無理ですね。 まぁこれに関しては別途お客様に証明書作ってもらって、開発機にインポートするという手もあります。
(edited)
Avatar
配布用証明書の作成、そういえば以前調べたときにここがあって管理者にしてもらわないとと思ったような気がします。 結構前だったので、すっかり忘れておりました。 証明書やプロビジョニングプロファイルをお預かりできるなら、これらの作成手順書を作って、必要なとき(1年毎)にこれらのファイルを毎度送っていただくことになるんですよね。 omochimetaruさんがおっしゃっているように、結局毎回新しいSwift・XCodeで動作確認しなくてはいけませんし、仕方がないとはいえ手間がかかりますね。
Avatar
うちはApp Storeに出しているアプリを一部カスタマイズしたものをお客様のIn Houseで提供することがあるのですが、その時はだいたい (3) みたいですね。カスタマイズ部分以外の既存開発部分については、ライセンス的にお客様に提供できないソースもあって (2) はできないんですよね。
Avatar
今回のアプリは完全にお客様の業務内容に特化したもので、ソースを丸々渡すのは特にライセンス的にも問題ない感じです。 どの方法で配布を行うかは、やはりケースバイケースということですよね。 皆様、ご意見本当にありがとうございます。
Avatar
私も(3)にしてます。お客様のEnterpriseアカウントで複数アプリ・複数ベンダーとなったときに個々のアプリの都合で証明書いじられると困りそうなので、証明書管理はお客様にがんばってもらうようにしています(支援はしますが)。 更新時の新しいSwift, Xcodeについては、本当に期限の延長だけで改修がないなら、前の納品に署名だけ(+あとビルド番号とか)つけかえて出すというのができます(基本的にはfastlane sigh resignとかなんですが、罠はあるので注意が必要、、、)。
Avatar
確かに現時点だとそもそもiOS機を取り入れたばかりでうちの会社しかアプリを納品する予定がない状態ですが、今後増えたときのことも考える必要がありますね。 こちらを見ると配布用証明書は複数生成できるとのことなのですが、アプリごとに証明書を分けて生成するということはできないんでしょうか。 https://developer.apple.com/jp/documentation/IDEs/Conceptual/AppDistributionGuide/DistributingEnterpriseProgramApps/DistributingEnterpriseProgramApps.html
アプリケーションを開発、テスト、配布する作業の流れを説明しています。
Avatar
あれっ配付用証明書は複数作れない認識で(期限近いときにダブらせられるだけと思っていた)、そうしていたんですが、もしかして好きなだけ作れるんですかね・・・
Avatar
Distribution証明書は最大3つまでだったはずです なので、Expireしないように更新用で2枠は基本使いたいところ… (edited)
😮 3
Avatar
>Distribution証明書は最大3つまでだったはずです そうだったのですね。証明書の最大数についての情報を見かけたことがなくて、アプリごとにそれぞれ発行していけるのかなと思っていました。
Avatar
専用アプリの配信にはVPP Custom B2Bという方法もあり、そちらを使うと証明書のやりとりや、プロビジョニングプロファイルの期限切れなどに悩まされることはなくなります。 (ただし、ストア経由にはなるのでAppleの審査が入ります) こちらは検討されましたか?
4:04 AM
↑もとのAndroid版が完全な社内アプリだと審査を通すための手間の方が大変かもしれないですね・・
Avatar
VPP Custom B2BだとAppleの審査が入るので、おっしゃる通り完全な社内アプリのため断念致しました。
Avatar
配布方法はMDMでのIn-house配布(Push配布もしくはStore形式でのpull配布)などでしょうか?アプリの配信だけでなくプロビジョニングプロファイルのみのリモート更新も可能なMDMもあるかと思います。
Avatar
配布方法は、今回のアプリとも連動するWebアプリケーション(こちらもAndroid版と一緒に6年前に作成したシステムです)がありまして、そちらでダウンロードページを用意して行うようにする予定です。 Android版は既にそのようにしているので、出来るだけ揃えたいと考えています。 (edited)
Avatar
https://github.com/taketo1024/SwiftyMath 今まで普通にビルドが通っていたものが、 1. While running pass #509 SILModuleTransform "Mandatory Inlining of Transparent Functions". <unknown>:0: error: unable to execute command: Abort trap: 6 <unknown>:0: error: compile command failed due to signal 6 (use -v to see invocation) と出て通らなくなってしまいました 😵 コミットを過去まで遡ってもダメなので、恐らく Xcode のバージョンをあげたことによるものだと思うのですが、原因のわかる方いたらお助けください 🙏 (edited)
SwiftyMath - Pure Math in Pure Swift.
Avatar
最近 mac の調子が悪いし僕の xcode が壊れてるのかもしれません 😫 (edited)
Avatar
omochimetaru 6/12/2018 3:15 AM
Cleanはしましたか?
Avatar
はい、xcode で clean build folder してビルドしても、 swift package clean して swift build してもダメでした orz
Avatar
omochimetaru 6/12/2018 3:17 AM
Abort trap: 6ってことはコンパイラがクラッシュしてるので、コンパイラのバグを踏んだかもしれませんね、環境はXcode Version 9.4 (9F1027a)?
Avatar
Version 9.4 (9F1027a)
3:17 AM
です。
3:17 AM
昨日は普通にできてたんですが…
3:22 AM
ホントはやっちゃいけない、generic type つき typealias の extension をやってるのが原因かもしれません(これまでビルド通ってたので放置してた)
Avatar
norio_nomura 6/12/2018 3:25 AM
クラッシュ再現しないです。
Avatar
omochimetaru 6/12/2018 3:25 AM
[omochi@omochi-iMac-PC43 SwiftyMath (master=)]$ swift build Compile Swift Module 'SwiftyMath' (70 sources) Compile Swift Module 'SwiftyLieGroups' (12 sources) Compile Swift Module 'SwiftyHomology' (10 sources) Compile Swift Module 'SwiftyKnots' (9 sources) Compile Swift Module 'SwiftyTopology' (15 sources) Linking ./.build/x86_64-apple-macosx10.10/debug/libdSwiftyMath.dylib Compile Swift Module 'Sample' (1 sources) Linking ./.build/x86_64-apple-macosx10.10/debug/Sample [omochi@omochi-iMac-PC43 SwiftyMath (master=)]$ swift --version Apple Swift version 4.1.2 (swiftlang-902.0.54 clang-902.0.39.2) Target: x86_64-apple-darwin17.6.0
3:25 AM
こちらもビルドできた。
Avatar
げげ😫
3:28 AM
やっぱ本格的に mac が壊れてきてるのかな…
Avatar
Kishikawa Katsumi 6/12/2018 3:29 AM
とりあえずDockerでビルドしてみては。
Avatar
norio_nomura 6/12/2018 3:29 AM
Swift 4.2だとクラッシュはしないけどビルド出来ない。 (edited)
Avatar
4.2 だとダメなんですかね…
3:32 AM
Group.swift のコンパイルでコケてるのですが、 https://github.com/taketo1024/SwiftyMath/blob/824225ca51c1fdeb15c3fe089d1ebcc2f954b9ce/Sources/SwiftyMath/Abstract/Group.swift#L89-L91 この3行をコメントアウトして fatalError() にするとそのファイルでコケるのは無くなりました。
SwiftyMath - Pure Math in Pure Swift.
3:32 AM
var unions: Set<Set<Self>> = Set() ... return unions .sorted{ $0.count < $1.count } .map{ FiniteSubgroupStructure(allElements: $0) } (edited)
Avatar
omochimetaru 6/12/2018 3:32 AM
Xcode9.4はSwift4.1じゃない?
Avatar
あ、ほんとだ、4.1 でした。
Avatar
norio_nomura 6/12/2018 3:34 AM
とりあえずswift-4.2-DEVELOPMENT-SNAPSHOT-2018-06-11-aだと $ docker run --privileged -it -v `pwd`:`pwd` -w `pwd` --rm norionomura/swift:swift-4.2-branch swift test Compile Swift Module 'SwiftyMath' (70 sources) /Users/norio/github/SwiftyMath/Sources/SwiftyMath/Matrix/SquareMatrix.swift:18:1: error: conditional conformance of type '_Matrix<n, m, R>' to protocol 'Ring' does not imply conformance to inherited protocol 'Monoid' extension SquareMatrix: Ring where n == m { ^ /Users/norio/github/SwiftyMath/Sources/SwiftyMath/Matrix/SquareMatrix.swift:18:1: note: did you mean to explicitly state the conformance like 'extension _Matrix: Monoid where ...'? extension SquareMatrix: Ring where n == m { ^ error: terminated(1): /usr/bin/swift-build-tool -f /Users/norio/github/SwiftyMath/.build/debug.yaml test output: になります。 (edited)
Avatar
むむむ…
3:35 AM
それはまた原因が違いそうな…
3:37 AM
それはきっとこれですね
ホントはやっちゃいけない、generic type つき typealias の extension をやってるのが原因かもしれません(これまでビルド通ってたので放置してた)
(edited)
Avatar
昨日は普通にできてたんですが… クラッシュ再現しないです。 こちらもビルドできた。 Abort trap: 6ってことはコンパイラがクラッシュしてるので、コンパイラのバグを踏んだかもしれませんね コンパイラのメモリ関連バグ?マシン再起動したら直ったりしませんか? (edited)
Avatar
お、そうだ、それを試してみます(基本的なとこ抜けてました)
Avatar
norio_nomura 6/12/2018 3:40 AM
とりあえずリポジトリにCIを設定した方がいいんじゃないかな。
3:42 AM
CIが設定してあれば、ローカルマシンの問題なのかどうか直ぐにわかる。
Avatar
再起動したらコンパイル通りました 😂 お騒がせしてすみません 🙇
3:43 AM
なるほどです > リポジトリにCIを設定
Avatar
omochimetaru 6/12/2018 3:43 AM
マシン再起動で治るの・・・
3:43 AM
そういう事もあるのか。
Avatar
最近だいぶ壊れてきてるっぽいです。夜な夜なハードな計算回しすぎたかな… 😫
3:45 AM
NVRAMリセット、SMCリセット、Disk の First Aid は試してみたんですが、相変わらず突然ブラックスクリーンになったりします…
Avatar
メモリが部分的に逝ってそうな気配
Avatar
CI は Travis CI が良いんでしょうか(何も知らない)
Avatar
omochimetaru 6/12/2018 3:46 AM
Travisだけならやったことあるけど簡単だしおすすめです
Avatar
おっしゃ、入れてみます💪🏿
3:48 AM
https://support.apple.com/kb/PH25696?viewlocale=ja_JP&locale=fr_FR とりあえず Apple 診断 やってみます。
macOS を使用して Mac が起動しない場合でも、「Apple 診断」または「Apple Hardware Test」を使用して起動できる場合があります。
Avatar
Kishikawa Katsumi 6/12/2018 3:49 AM
OpenSourceプロジェクトならTravisはもっとも柔軟性が高いという意味で最強だと思います。MacとLinux同時に使えるし。 (edited)
Avatar
norio_nomura 6/12/2018 3:53 AM
そういえば少し前にtravis.comが対応したGitHubのchecksってまだ試したことがないな。
3:54 AM
新規でリポジトリにTravis-CIを設定しようとすると、以前のtravis.orgではなくtravis.comになるのかな?
3:57 AM
確か、OSS向けもtravis.comになったんだよね。
Avatar
Hardware Test も起動しないのでもうダメっぽいです🙅‍♂️とりあえず色々ありがとうございました🙇‍♂️
6:53 AM
唐突にすいません TableViewCellにマージンをかける方法とかってありますか? 理想は上の画像みたいにしたいです
Avatar
Kishikawa Katsumi 6/12/2018 6:54 AM
簡単でおすすめなのはTableViewCellに一回り小さなビューを載せることです。
Avatar
オートレイアウトなら layoutMarginsGuide があります
6:56 AM
というか通常ならCellに contentView があって、それはlayoutMarginsの中にあるじゃなかったっけ 🤔 詳しい仕様忘れましたが (edited)
Avatar
お二人とも、ありがとうございます! 早速試してみます!
Avatar
し、しんでる
Avatar
先ほどの問題ですが、やはりハードウェアに問題があるようでした😑
3:52 PM
これはハードウェアテストモードです😑
Avatar
TestResultにerrorって書いてますね
Avatar
はい😑w
3:53 PM
ハードウェアがイカれてビルドが通らないケース初めてだったので良い経験になりました😂
3:59 PM
4MEM というエラーコードはメモリが一部死んでる系のエラーのようです。@ありぜ さんの言う通りでした😂
😱 4
😂 1
Avatar
omochimetaru 6/12/2018 4:00 PM
こんなことあるんですね
😂 2
Avatar
protocol HogeProtocol { } struct Hoge: HogeProtocol { func setHoge() {} } struct Fuga: HogeProtocol { func setFuga() {} } enum Foo { case hoge case fuga func getHogeProtocol() -> HogeProtocol { switch self { case .hoge: return Hoge() case .fuga: return Fuga() } } } // use let hoge = Foo.hoge.getHogeProtocol() // HogeProtocol型 hoge.setHoge() // NG FoogetHogeProtocol() の返り値で各structの型を返したいのですが、HogeProtocol型になってしまいます。 各structの型を返す方法はありますでしょうか。
Avatar
@swiftbot protocol HogeProtocol { } struct Hoge: HogeProtocol { func setHoge() {} } struct Fuga: HogeProtocol { func setFuga() {} } enum Foo { case hoge case fuga func getHogeProtocol<T : HogeProtocol>() -> T { switch self { case .hoge: return Hoge() as! T case .fuga: return Fuga() as! T } } } // use let hoge: Hoge = Foo.hoge.getHogeProtocol() // HogeProtocol型 hoge.setHoge() // OK
🛠 1
Avatar
swiftbot BOT 6/15/2018 8:16 AM
Author icon
koher
protocol HogeProtocol { } struct Hoge: HogeProtocol { func setHoge() {} } struct Fuga: HogeProtocol { func setFuga() {} } enum Foo { case hoge case fuga func getHogeProtocol<T : HogeProtocol>() -> T { switch self { case .hoge: return Hoge() as! T case .fuga: return Fuga() as! T } } } // use let hoge: Hoge = Foo.hoge.getHogeProtocol() // HogeProtocol型 hoge.setHoge() // OK
Version:
swift-4.1.1-RELEASE
Output:
Error:
Avatar
@shunkun ↑これが良い設計だとは思いませんが、↑のようにできないことはありません。
8:17 AM
せめて func getHogeProtocol<T : HogeProtocol>() -> T? にして as? T にすべきだとは思いますが。
Avatar
ジェネリクスにするとできるのですね!ありがとうございます。 設計の問題ですかね...
Avatar
omochimetaru 6/15/2018 8:20 AM
protocol HogeProtocol { } struct Hoge: HogeProtocol { func setHoge() {} } struct Fuga: HogeProtocol { func setFuga() {} } enum Foo { case hoge case fuga func getHogeProtocol() -> FooHogeProtocolValue { switch self { case .hoge: return FooHogeProtocolValue.hoge(Hoge()) case .fuga: return FooHogeProtocolValue.fuga(Fuga()) } } } enum FooHogeProtocolValue { case hoge(Hoge) case fuga(Fuga) } @shunkun こうするのはどうですか
8:20 AM
switch foo.getHogeProtocol() { case .hoge(let hoge): // なにかする case .fuga(let fuga): // なにかする } これで型安全です
Avatar
型安全は魅力的なのですが、 enum Foo { case hoge case fuga } で、どっちかを最初に選んで使うので、選んだ後に場合分けが入ってしまうと使うの側のコードが増えてしまうなと言う印象なのです... (edited)
Avatar
omochimetaru 6/15/2018 8:23 AM
「各structの型を返したい」時点で場合分けは必要な気がします。
8:24 AM
protocolで返すなら共通の処理がその後ろに書けます。
8:25 AM
ちなみに、enum FooHogeProtocolValueHogeProtocol に準拠させれば、分岐消せますね。 (edited)
Avatar
omochiさんので大丈夫そうでした!
8:28 AM
教えてもらった方法でやって見ます!ありがとうございます!
✌ 1
Avatar
@shunkun >> これが良い設計だとは思いませんが
設計の問題ですかね...
ジェネリックにするとタイプセーフにならないので、の意でした。
Avatar
そうですね。一応、T が HogeProtocolに準拠したものしか取らないので少しは安全ではありますね。
Avatar
omochimetaru 6/15/2018 8:52 AM
caseとの組み合わせが違う場合もクラッシュしまっせ
😳 1
Avatar
設計の問題かと思って見直した結果、enumで返すメソッド持つのやめました😇
🙂 1
8:53 AM
たしかに let hoge: Fuga = Foo.hoge.getHogeProtocol() だとクラッシュですね...
Avatar
素朴な疑問なんですが、Storyboard で View を Freeform で編集する方法ってないんでしょうか?画面からはみ出すようなコンテンツ量になった場合死ぬしかない?
10:30 AM
Storyboard で VC 選択して metrics を Freeform にしても特に View の拡大とかできなさそうにみえる
Avatar
Kishikawa Katsumi 6/15/2018 10:36 AM
Freeformにしたら自由な大きさにできると思いますね。
10:37 AM
Xcode no
Avatar
巨大なVCを1storyboardで作ったらその時点で死んでるのでは… 表題は普通にできたと思う
😇 1
Avatar
Kishikawa Katsumi 6/15/2018 10:37 AM
のバージョンいくつですか?
Avatar
Xcode 9.4 ですね
10:38 AM
xib を編集するときはもちろん Freeform でサイズ変えられるんですが
Avatar
Kishikawa Katsumi 6/15/2018 10:42 AM
できますね。サイズの方(定規のアイコン)でFreeform にしてます? @Biacco42
🙏 1
10:44 AM
Avatar
できました!こっちで変えられるんですね…!
10:45 AM
これ、数値でしか変えられないですか…?
Avatar
Kishikawa Katsumi 6/15/2018 10:47 AM
そうかも。。。
Avatar
やはりそうでしたか…まぁ、実用上は問題ないといえばないですが…なるほど
10:47 AM
ありがとうございます
Avatar
xibだとドラッグアンドドロップ出来るけど、もしかしてsbだと出来ない?
Avatar
xib のような枠とかハンドルは出なくて試しにやってみたけれどできなかった
Avatar
VPPで購入してApple Configurator 2経由でデバイスにインストールすると、インストールしたアプリが起動しない(起動しそうだけどすぐにホーム画面に戻る)という現象で困っているんですが、同様の経験のある方いらっしゃいますか?
6:47 AM
同じアプリをApp Storeで購入してApple Configurator 2経由でデバイスにインストールしても、そっちは問題なく起動します。VPPとApp Storeで何か違うのかな…。
Avatar
Selectタグを含んだWebコンテンツをWebViewで開き、Selectタグ部分タップしてOS判断で出たPickerが制約エラーでるんですけど、これって回避方法とか何か情報持ってるかたいませんか?(iOS 11のみで起こる)
Avatar
iOSってキーボードは基本制約壊れてませんか
Avatar
omochimetaru 6/20/2018 5:26 AM
デバッガで見てるとメモリリークもしてるよね
Avatar
色々アレだよね
Avatar
@hironytic 解決されましたか?助けになるかはわかりませんが、VPP と Apple Configurator 2 でハマったことがあります。今思いつくのは、 VPP ストアで購入したアプリを最初にインストールしたデバイス以外にインストールしている または、私の場合は Apple Configurator 2 経由 で VPP アカウントを設定してインストールしたので、購入したアカウントの設定であるとするとそれが問題になっているのかもしれません。 ちなみに Apple Configurator 2 に VPP アカウントを関連づけると・・・ 『警告: VPP アカウントがすでに Apple Configurator 2 の別のインスタンスまたは MDM ソリューションに関連付けられている場合、それらの以前の関連付けによる App の割り当てがすべて取り消されます。』 ということなので、ご注意ください。
Avatar
@KNT 全く解決してません 😇 なので、情報はとてもありがたいです。 えーと、VPPストアで購入したアプリを最初にインストールしたデバイス以外にインストールしたらダメなものなんですか? VPPストアで10本とか購入して、Apple Configurator 2でそれぞれの端末に追加していく、っていう使い方でいいのかなと思っていたんですが。
Avatar
@hironytic すでに手離れしてしまっていて確認する術がないので、思いついたことだけですみません。私の場合、最終的には 購入アカウントではなく、VPP アカウントを Apple Configurator 2 に設定することで解決しました。
Avatar
あ、ぼくがVPPをちゃんと理解できてない気がします。
10:25 AM
購入アカウントとVPPアカウントって別なんでしょうか。
10:32 AM
ぼくがやったのは、VPPアカウントでVPPのストアにログインして、無料App(自社製品)を10本購入。で、Apple Configurator 2でそのVPPアカウントでサインインして、「追加」で購入したAppを選択してデバイスに追加なんです。で、いきなり、そのアプリの起動ができなかった 😢
Avatar
@hironytic なるほど・・・力になれずすみません。
Avatar
@KNT いえいえ、ありがとうございます。
10:45 AM
@KNT 解決した……かもです!
10:46 AM
追加先のデバイスでは、別のApple IDでApp Storeにサインインしていたのですが、通常、VPPで配布するときは、Apple IDなしでいいはずなので、もしかして逆にサインインしているといけないのかなと思い、デバイスではApp Storeからサインアウトしてみました。
10:47 AM
この状態で、起動しなくなっていたアプリはいったんアンインストールして、もう一度、Apple Configurator 2から追加を行ったところ、今度は起動しました!
Avatar
@hironytic おぉぉ、よかった!おかげで私も学べました。
Avatar
実際にはお客様のところで発生している問題なので、お客様のところでもうまくいけばいいのですが…
Avatar
悲報:お客様はサインインしてなかった(でも、サインインして行ったというメールもあって情報錯綜・・・)
11:41 AM
サインインは関係ないかもしれません。
11:44 AM
あと、ぼくの知らないところで、今日、検証端末のOSが11.3.1から11.4に上げられてたりとか。それによりデバイスが再起動したからうまくいくようになっただけ?とか(お客様はもともと11.4で発生している)。いくらでも憶測はできるのですが、原因はわからず。
11:45 AM
あと、再度サインインして配布しても起動しました。というわけで、今言えることは、ぼくは手元の再現環境を失ったということだけです 😢
😥 3
Avatar
@KNT お客様のところもサインアウトして配布したらうまくいったそうで、原因はさっぱりわからないんですがとりあえずクローズできました。ありがとうございました 🙂
😃 1
Avatar
@hironytic 私はなんの役にもたてませんでしたが、クローズしてよかったですw 原因不明なものの一つの解決方法としてあげられるので、またあれば私も注意してみます。
Avatar
Xcodeのスキーマを複数作成したとき、そのスキーマのアプリ画像(ファビコン)はどこで変更可能でしょうか。コンフィグレーションごとにスキーマを複数作成して、コンフィグレーションごとにアプリのアイコン(ASSETCATALOG_COMPILER_APPICON_NAME)を変更するようにしてるのですが、全てのスキーマのアプリ画像が同じアプリ画像になってしまいます。スキーマのアプリ画像をASSETCATALOG_COMPILER_APPICON_NAMEにそって切り替えることは可能でしょうか。
Avatar
Kishikawa Katsumi 6/22/2018 11:51 AM
たぶん無理です。Xcodeに機能リクエストすることになると思います。
Avatar
やはりそうですか、ありがとうございます 。
Avatar
unowned let hoge: Hoge という宣言をしているコードを見かけたのですが、これってどういう挙動のものなんでしょうか そのクラスにはインスタンスは保持されずに他で保持されてなければhogeは即解放されてしまう…?
Avatar
@noppe 「保持」というのがリファレンスカウント的な話だとそうですが、そのインスタンスへの参照を保持するための領域は確保されます。
4:31 AM
weak の場合は解放されたときに nil にしてくれますが、 unowned の場合はそういう安全機構がありません。
Avatar
リファレンスカウントは変更されずに対象インスタンスの参照だけを宣言するイメージでしょうか?
Avatar
代入してもリファレンスカウントが変更されないプロパティと考えるといいと思います。
4:33 AM
その代わり、参照先が解放されてしまっている危険性があります。
4:33 AM
なので、循環参照を避けたくて、絶対に解放されないことがわかっている場合に使います。
Avatar
ありがとうございます、確かに解放した後にアクセスしようとするとSIGABRT吐いちゃいますね…。 これがweakの場合はnilになっていると
Avatar
万が一解放された後でアクセスしてしまった場合は、実行時エラーだったか未定義動作だったかどういう言語仕様になってたか自信がありません。 (edited)
❤ 1
4:36 AM
Use an unowned reference only when you are sure that the reference always refers to an instance that has not been deallocated. If you try to access the value of an unowned reference after that instance has been deallocated, you’ll get a runtime error.
Avatar
unowned(unsafe) の場合は未定義ですね。普通の unowned はドキュメントの通り、実行時エラーが保証されています。
Avatar
omochimetaru 7/27/2018 4:39 AM
unowned(unsafe)っていつからあったんですか?
4:39 AM
最近見かける。
Avatar
-Ounchecked のときは普通の unowned でも未定義に・・・。 $ cat unowned.swift class A {} class B { unowned let a: A init(a: A) { self.a = a } } let b = B(a: A()) print(b.a) $ swift -Ounchecked unowned.swift unowned.A (edited)
Avatar
記憶の限りずっとあったと思いますよ。
Avatar
omochimetaru 7/27/2018 4:40 AM
マジか。知らなかった・・・
Avatar
This was part of the original weak design that there was never any particular reason to rush the implementation for. It's convenient to do this now so that we can use it to implement Unmanaged...
Avatar
omochimetaru 7/27/2018 4:40 AM
本当だ。
Avatar
2014/04/23 、 Swift 発表以前だ・・・
Avatar
omochimetaru 7/27/2018 4:41 AM
意外と知らない基礎知識あるんだよなあ
Avatar
unowned(unsafe) の有用性を認めるのであれば、 unsafePrecondition とかも認めないといけないような🤔
4:42 AM
そこを -Ounchecked でコントロールスタイルじゃないのかな・・・。
Avatar
-Ounchecked 自体deprecatedじゃないかな。。。
Avatar
omochimetaru 7/27/2018 4:42 AM
え!
Avatar
え、そうなんですか?
Avatar
omochimetaru 7/27/2018 4:43 AM
-OuncheckedはC言語に勝つために必須な気がする
4:44 AM
deprecated とは明言されていないか。
Avatar
omochimetaru 7/27/2018 4:44 AM
でも、ベンチマークから削除されてるのは、すごいことですね
Avatar
うーーん
Avatar
omochimetaru 7/27/2018 4:44 AM
Ouncheckedはパフォーマンス特化のモードだから、まさにベンチマークすべきモードだと思う
4:45 AM
それがSwiftのポテンシャルだから・・・
Avatar
-Ounchecked を使わないと、十分に安全性が確保されたパフォーマンスを追求するコードで一体どうやって precondition のチェックを無効化したらいいんでしょう?
4:45 AM
assert で書く?
Avatar
omochimetaru 7/27/2018 4:45 AM
それでもOsizeにするってことはOuncheckedを捨てていく意図を感じる
Avatar
どういう判断なんだろう?
Avatar
omochimetaru 7/27/2018 4:47 AM
フォーラムになんかあるかな?
Avatar
Hi, I’d like to propose to deprecate the -Ounchecked swift optimization mode. The -Ounchecked mode actually contradicts one of the main goals of swift: to be a safe language. In the past we didn’t see lot of significant performance differences compared to -O (there wer...
Avatar
omochimetaru 7/27/2018 4:47 AM
Hi, I’d like to propose to deprecate the -Ounchecked swift optimization mode. The -Ounchecked mode actually contradicts one of the main goals of swift: to be a safe language. In the past we didn’t see lot of significant performance differences compared to -O (there wer...
4:47 AM
あったわ
4:47 AM
同じだ。
4:48 AM
Hi, I’d like to propose to deprecate the -Ounchecked swift optimization mode.
4:48 AM
www
4:48 AM
とりあえず #swift に移動しましょう。
Avatar
たとえばキャッシュ用の private プロパティなどを Codable の対象から外す簡単な方法ってありましたっけ?
Avatar
cache用のフィールドを固めて無にエンコードする、を思いつきました
Avatar
omochimetaru 7/27/2018 8:35 AM
そのプロパティをCodableでない型にするか、CodingKeysを書くしかなさそう
Avatar
@tarunon それでもそのプロパティをキーとして書き出されませんか?
8:37 AM
@omochimetaru Codable でない型にしたら encode init(from:) を自前実装しないといけないのでは?
Avatar
omochimetaru 7/27/2018 8:37 AM
あ、そうか、全部Codableじゃないとダメか。 (edited)
Avatar
CodingKeysを書くしかなさそう
CodingKeys だけ書いたら encodeinit(from:) は自動生成されるんだっけ?
(edited)
Avatar
omochimetaru 7/27/2018 8:38 AM
CodingKeysだけ書いて、encodeとinit(from)はオマカセは、できたような・・・?
Avatar
実際のプロパティとの関連付けは名前で解決される??
Avatar
omochimetaru 7/27/2018 8:39 AM
そうそう。
Avatar
とりあえずやってみよう
8:40 AM
だめそう・・・
Avatar
omochimetaru 7/27/2018 8:41 AM
うわ、ほんとうだ
8:41 AM
全部caseが対応してるときに、キー文字列を変えられるだけか。
Avatar
@swiftbot struct Foo: Codable { private enum CodingKeys: CodingKey { case a } var a: Int private var _b: String }
🛠 1
Avatar
swiftbot BOT 7/27/2018 8:42 AM
Author icon
koher
struct Foo: Codable { private enum CodingKeys: CodingKey { case a } var a: Int private var _b: String }
Version:
swift-4.1.1-RELEASE
Output:
Error:
/usercode/main.swift:1:8: error: type 'Foo' does not conform to protocol 'Decodable' struct Foo: Codable { ^ Swift.Decodable:2:12: note: protocol requires initializer 'init(from:)' with type 'Decodable' public init(from decoder: Decoder) throws ^ /usercode/main.swift:6:17: note: cannot automatically synthesize 'Decodable' because '_b' does not have a matching CodingKey and does not have a default value private var _b: String ^
Avatar
うー、 encode, decode を自前実装しないといけないのか・・・。面倒だなぁ。
Avatar
多分ある程度うまくいく方法があるので続きは #swift (edited)
Avatar
TestFlightで内部のテスト配信したのですが、assertionFailureが有効になっているのか、該当行でCrashしてしまいます。 Appleのドキュメントを読むと、optimization levelが-Oの時には評価されないと記載されています。 ArchiveはRelease Build Configurationになっていたので、評価されないはずなのですが…。 下記が公式ドキュメントです。 https://developer.apple.com/documentation/swift/1539616-assertionfailure この辺り、ご存知の方がいたらご教授くださると嬉しいです
7:15 AM
Crash検知はcrashlyticsを利用しています
Avatar
-O なら assetionFailure は有効にならないはずです。
7:39 AM
プロジェクト設定(Build Settings)の、Swift Compiler - Code GenerationのOptimization Levelでは、Releaseが -O (Optimize for Speed)になってるんですよね。
Avatar
omochimetaru 7/31/2018 7:41 AM
とりあえずちゃんと -O による assertion の除去がされているか確認するために、 おしたら assertionFailure するだけのボタンをアプリに置いてみるなどはどうでしょう。
Avatar
@hironytic 念のため確認しましたがなってました…。 @omochimetaru ボタン置いて確認してみます!
🙂 1
Avatar
ボタン置いて確認したところ、assertionfailureは評価されませんでした。 ということは、元のコードに問題がありそうなので調査します。 アドバイスありがとうございました🙇‍♂️
Avatar
@swift-4.1.3 import Foundation var array = Array(repeating: 1, count: 100000) DispatchQueue.global().async { array.insert(3, at: 99999) print("inserted") } print("start") let total = array.reduce(0, +) print(total) print(array.count)
Avatar
start inserted 100003 100001
Avatar
あれ?
4:08 AM
@swift-4.2.4 import Foundation var array = Array(repeating: 1, count: 100000) DispatchQueue.global().async { array.insert(3, at: 99999) print("inserted") } print("start") let total = array.reduce(0, +) print(total) print(array.count)
Avatar
start inserted 100000 100001
Avatar
よし! わからん
4:09 AM
4.2で何かが変わったのかな???
4:09 AM
単なるタイミングの問題か
Avatar
dispatchMain()とかで待たないと、実行されない場合がありますよ。
Avatar
そもそもArrayはスレッドセーフじゃないから、 これだと何が起きてもおかしくないです
Avatar
横から質問ですみませんが、qos が global の queue ってひとつじゃないんでしょうか
4:15 AM
もし一つなら、global async は serial に実行されるのかな、と思っていました
Avatar
オブジェクトが1つでもglobal queueはconcurrent queueだったと思います。
Avatar
なるほど、であれば確かに順序は不定ですね
Avatar
それと、let total = ... の行については、そのキューの中では実行されてないです。
4:18 AM
Command line executableの場合、main() は生のmainです。 @norio_nomura のゆうように、dispatchMain を自分で呼ぶなどしないと
4:18 AM
DispatchQueueの支配するメインスレッドになりません。
Avatar
スレッドセーフでないから100003になる(ことがある)と思われるのに4.2でやると100000で安定してるので何か変わったのかと
4:26 AM
dispatchMain()知りませんでした
Avatar
@masakihori それでいうと、DispatchQueue.asyncの並列実行は、発火しても、スケジュールされるかどうかは運次第なので、asyncが実行される前にarray.reduceが終わってしまう可能性があります。
Avatar
@omochimetaru
Arrayはスレッドセーフじゃない
前にも聞いた気がするんですけど(履歴検索してもうまくひっかからなかったので)、これってどこかに仕様として明記されてましたっけ? Array の API リファレンスも The Swift Programming Language にも書かれてなさそう( thread で検索してみただけだけど)。標準ライブラリのコードから実態としてスレッドセーフじゃないということでしょうか?
(edited)
4:29 AM
スレッドセーフだと書かれてないものはスレッドセーフでないと考えるのが良いかもですが。
Avatar
デフォルトが「非スレッドセーフ」で、特に書かれてないから、そう考えてます。
👌 2
Avatar
ここで書かれたロジックがスレッドセーフではないだけで、Array自体はスレッドセーフなのでは?
Avatar
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
4:32 AM
The most important consequence of this is that two different array elements cannot be simultaneously accessed. This will interfere with certain common idioms for working with arrays, although some cases (like concurrently modifying different slices of an array) are already quite problematic in Swift.
Avatar
Kishikawa Katsumi 10/23/2018 4:33 AM
いや、Arrayはスレッドセーフじゃないですよ。
Avatar
少なくとも、arrayの異なるsubscriptにconcurrentにアクセスするのがダメ、という話は、OwnershipManifestoにも出てきます。
Avatar
Kishikawa Katsumi 10/23/2018 4:33 AM
デフォルトが「非スレッドセーフ」で、特に書かれてないから、そう考えてます。
^ この解釈があってると思います。
👌 1
4:33 AM
Arrayは複数スレッドから変更しようとしたら容易にクラッシュするのはすぐ確かめられます。
Avatar
「Swiftのデフォルトが非スレッドセーフである」という明確な言明があるテキストは知らないので探してみます。
Avatar
Kishikawa Katsumi 10/23/2018 4:35 AM
一般的にスレッドセーフにするのは余分なコストがかかるし難しいのでデフォルトがスレッドアンセーフというのは合理的だと思います。
4:40 AM
import Foundation let semaphore = DispatchSemaphore(value: 0) var array = [Int]() DispatchQueue.global().async { for i in 0...1000 { array.append(i) } print("end 1") } DispatchQueue.global().async { for i in 0...1000 { array.append(i) } print("end 2") } DispatchQueue.global().async { for i in 0...1000 { array.append(i) } print("end 3") } semaphore.wait()
4:40 AM
^ Botだとよくわからなかったけど、こういうコードはArrayはクラッシュします。
Avatar
全然見つからないですw
Avatar
すみません Swift42 bot 落としちゃったかも
4:54 AM
@swift-4.1.3 import Foundation var array = Array(repeating: 1, count: 100000) DispatchQueue.global().async { array.insert(3, at: 99999) print("inserted") } print("start") let total = array.reduce(0) { t, c in if t % 100 == 0 { print(".", terminator: "") } return t + c } print("") print(total) print(array.count)
Avatar
start ....................................inserted .................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... 100000 100001
Avatar
マルチスレッド怖い
Avatar
すみません Swift42 bot 落としちゃったかも 受け取ったコードは別プロセスで実行されるので、ボット自体が落ちることはあまりないです。
Avatar
僕がやってるやつはマルチスレッド関係ない気がしてきた
Avatar
受け取ったコードは別プロセスで実行されるので、ボット自体が落ちることはあまりないです。 あいや落ちてHerokuが復帰させてた… 😅 (edited)
Avatar
makeIterator というか Iterator の実装がみそ の気がする
Avatar
我的API始終返回[{},{},{}]一個Json數組,如何使用swift 4.2解碼它,如果有人已經有這種情況我正在聽。我的方法點擊了GET請求。 Wǒ de API shǐzhōng fǎnhuí [{},{},{}] yīgè Json shùzǔ, rúhé shǐyòng swift 4.2 Jiěmǎ tā, rúguǒ yǒurén yǐjīng yǒu zhè zhǒng qíngkuàng wǒ zhèngzài tīng. Wǒ de fāngfǎ diǎnjīle GET qǐngqiú.
Avatar
どなたか CoreBluetooth 周りに詳しい方おりませんでしょうか…?
Avatar
Deleted User 11/2/2018 7:04 AM
「The project "プロジェクト名‘’ is damaged and cannot be opened due to a parse error. Examine the project file for invalid edits or unresolved source control conflicts. Path: /Users/自分の名前/Code/iOSapps/プロジェクト/プロジェクト名.xcodeproj」 ローカルでmasterとマージさせた後xcodeproj/project.pbxprojのコンフリクトを解消して、いざプロジェクトを開こうとすると上記エラーを吐くのですが、どう解決すればよろしいでしょうか???
Avatar
Kishikawa Katsumi 11/2/2018 7:06 AM
マージした結果、正しいProjectファイルではなくなってる感じですね。 1. 直接project.pbxprojをテキストエディタで編集して直すか、
7:06 AM
2. マージする前の状態に戻してやり直す、とかくらいしかないかなあ。
Avatar
omochimetaru 11/2/2018 7:07 AM
コンフリクトがすべて解消してないのかもしれません、pbxprojをエディタで開いて 「====」で検索するとヒットしませんか?
Avatar
Deleted User 11/2/2018 7:08 AM
@omochimetaru コンフリに関しては全て解消しました。「====」で検索してもヒットはないです。
🙃 1
7:09 AM
@Kishikawa Katsumi 素早い回答ありがとうございます。もう何度もマージする前の状態に戻して、やり直しては繰り返しており詰まってしまったので質問させていただきました。
Avatar
Kishikawa Katsumi 11/2/2018 7:09 AM
project.pbxprojは難しいので、数行程度で何が起こっているのかわかってるくらいのDiffならマージ操作でなんとかなりますが、そうでなければ私は諦めて手作業でやりますね。
Avatar
omochimetaru 11/2/2018 7:10 AM
そうしたら僕なら、oursをチェックアウトしてから、マージしようとしてるtheirs側の変更をdiffで生で見て、手動で同じ事をxcode上でやり直します
Avatar
Kishikawa Katsumi 11/2/2018 7:10 AM
project.pbxprojに変更が入るということはファイル、ライブラリの追加・削除、ビルド設定の変更など限られているので、材料と変更のDIffがあれば手作業の方が楽です。
Avatar
Deleted User 11/2/2018 7:12 AM
なるほど、お二方リプありがとうございます☺️諦めて手作業でやってみようと思います。
🙂 1
Avatar
Deleted User 11/6/2018 1:37 AM
こちらGithub上のxmlファイルをコピーする形で手作業で直りました!ありがとうございました😄
Avatar
たぶんコンフリクト解消したあと、解消した変更差分をstageに移してcommitしていないのでエラー出てますね。GUIのGit Client使ってると似たようなことよくやります
Avatar
naomichiさんの
どなたか CoreBluetooth 周りに詳しい方おりませんでしょうか…?
がスルーされてるぽいけど、これは解決したんだろうか?
Avatar
New iPadProのネイティブ対応、色々確かめてるんですが、10.1で新規アプリ作っても黒帯表示されて詰んでしまいました。上手くいった方いますか?
Avatar
ネイティブ対応は、基本対応アイコンとSplashが揃ってる状態でビルドしたらいけるはずだけど…
8:38 AM
両方揃っててもダメってことです?
Avatar
新規アプリで作って、LaunchScreen.storyboardなんでSplashはOK、アイコンはなくてもiPhoneXRとかはネイティブ対応になるが、iPadだけが上下に黒帯出ちゃうんですよね
8:42 AM
他に何か足りないのかな
Avatar
アイコンありは試してないってこと?
Avatar
アイコンありも試したけど同じ。
Avatar
あらま
Avatar
うまくいってるプロジェクトがあるならそれ参照したい、新規プロジェクトはダメでした 😿 (edited)
Avatar
Kishikawa Katsumi 11/8/2018 8:49 AM
念のためなんですけど、Xcodeで作ったばかりの何も手を加えてないプロジェクトでもダメですか?
Avatar
そうなんです
8:50 AM
真っ白のLaunchScreenと一枚VCの上下に黒帯がある
Avatar
Kishikawa Katsumi 11/8/2018 8:50 AM
デバイスだけ?シミュレータも?
Avatar
シミュレーターで発生してる
8:50 AM
実機は試してないですが概ねそうなりそう
Avatar
Kishikawa Katsumi 11/8/2018 8:50 AM
それはなんだろう。Xcodeのセットアップが壊れてるとかそんな感じな気がする。
Avatar
自分の方では起きないな…帯でない…
Avatar
え。
8:51 AM
環境破壊かぁ、承知ですありがとうございます
8:51 AM
DerivedData消してみよう
8:51 AM
XcodeSelectもやっておこう
Avatar
Kishikawa Katsumi 11/8/2018 8:51 AM
問題の切り分けとして、Xcodeが作ったばかりのプロジェクトを11inchのシミュレータで開いた場合、
8:51 AM
8:52 AM
^ これが正しいはず。
Avatar
岸川さんと同じ表示だった
Avatar
Xcode再インストールで治りました。ありがとうございます!
😃 4
Avatar
Kishikawa Katsumi 11/8/2018 11:36 AM
😄
Avatar
@ありぜ さん、こちら一旦解決していました…!ありがとうございます。
🙂 1
👍 1
Avatar
let array: [Array<Any>] = [Array<Int>(), Array<String>()] は可能だが struct Hoge<T> {} let array: [Hoge<Any>] = [Hoge<Int>(), Hoge<String>()] はダメだということは分かったのですが、これは何らかのテクニックで解消できるのでしょうか? それともコンパイラが何かやってる?
Avatar
Kishikawa Katsumi 11/20/2018 12:27 PM
それともコンパイラが何かやってる?
こっちが正しいです。 SwiftのGenericsは原則としてInvariantですが、Standard Libraryの一部はCovariantになります。 自分で定義した型は今のところどうやってもInvariantにしかなりません。
Avatar
ありがとうございます
Avatar
セミモーダルを実装したいのですが、参考になるような実装例をご存知の方いらっしゃれば教えてくださると幸いです。 (edited)
Avatar
https://github.com/SCENEE/FloatingPanel この前見つけたもの @Deleted User (edited)
A clean and easy-to-use floating panel UI component for iOS - SCENEE/FloatingPanel
Avatar
@cookiezby ドンピシャです!ありがとうございます!!
Avatar
こちらFloatingPanelのようにスクロールで3段階に分かれるもの以外で2段階にViewを変えられるライブラリや参考になるような実装例ございましたら大変、恐縮ですがリプライくださいますと嬉しいです。
Avatar
README にある var supportedPositions でカスタマイズできそうな雰囲気ですが、それはダメでしたか?
Avatar
2段階ってAirPods繋ぐときのみたいな感じですかね? https://github.com/antoniocasero/Panels これかな
Panels is a framework to easily add sliding panels to your application - antoniocasero/Panels
Avatar
@nekonoki var supportedPostionsを.half と.fullの値だけ指定し.tipをnilにしてから[.full, .half]をreturn で返すと固まってしまうなど実装したいデザインに準拠できなかったです。
5:33 AM
@noppe noppeさんのApple MusicKit入門、購入し読ませていただいております。まさに、この2段階の切り替えです。補足すると、height:100のmodal viewをボタンをタップすると出し、詳細を見る場合、より大きくなる。そして消したい場合はdismissを押すか初期サイズのviewから下にスクロールするというものです。文章で分かりにくくてすいません。上記ライブラリ試させていただきます。noppeさん、ありがとうございます。
Avatar
読んでいただいてありがとうございますmm セミモーダルですが、その挙動だとSCENEE/FloatingPanel の方が近そうですね 🤔 これ系結構色んな人が作っていた気がするので他にもありそうです
swift 1
Avatar
もうちょっと頑張ってみます、皆様ありがとうございます😊
Avatar
@Deleted User なるほど 例えば、 insetFor(position:) で返す値を .tip: 0, .half: 100, .full: 400 initialPosition.tip とし コードで表示・非表示を行う場合は func show() { fpc.move(to: .half) } func hide() { fpc.move(to: .tip) } とすれば、それっぽい動きになりそうですね。 (このやり方だと隠れていても FloatingPanel 自体は存在する形になってしまいますが)
Avatar
supportedPositionsを[.full, .half]、insetFor(position:)でcase .full: return 105.0 ・ case .half: return 256.0・default: return nilでFloatingPanel自体はremovePanelFromParentのみで削除する方法と、教えてくださったFloatingPanel自体は存在する方法どちらがいいか検討しますね! @nekonoki さん、ありがとうございます
Avatar
このライブラリがとても興味深かったので使ってみたのですが、 iOSでは動きませんでした。。。(macOSでは動いた) 使われたことのある方いますか? https://github.com/johnno1962/Fortify
Making Swift more robust. Contribute to johnno1962/Fortify development by creating an account on GitHub.
7:43 AM
fatal errorだろうがcatchしてしまう、とんでもないヤツです。 死ぬ前にログを吐かせるのに使えるかなと思ったのですが、 iOSではfatal error後即座に死んでしまいました。
Avatar
これiOSの場合はなんかオプションを有効にしないといけなかった気が
Avatar
お、おー!そうなんですね!Xcode側の設定ですか?
Avatar
ですです
8:15 AM
Edit SchemeからDebug executableをアンチェックですね
8:16 AM
Avatar
ありがとうございます!さっそくやってみます 💨
Avatar
実機ではだめでしたがシミュレータで動きました! 一歩前進できました。ありがとうございます!
Avatar
はじめまして。 配列の比較について質問させていただきたいのですが、 let a = [1] let b = [1] if a == b {} // コンパイル通る if [1] == [1] {} // コンパイル通らない このように配列を比較したときに、 一旦定数に入れたものと、そうでないものとで結果が違うのは何故でしょうか??
Avatar
Kishikawa Katsumi 12/15/2018 7:11 AM
おもしろいですね。 問題を整理すると、 a, b は型が Array<Int> に確定しているので、 if a == b {} は問題ないのですが、 リテラルを直接書いた場合( if [1] == [1] {} )は、 演算子 == リテラルをどの型として評価すべきか1つに定まらないから、ですね。 ちなみに問題は == に配列リテラルを渡したときに、配列リテラルからインスタンスできる型が複数あるからですね。(IndexzSetとIndexPath?) 例えばFoundationをImportしなければそれは存在しないので、上記のコードもコンパイルできます。 (edited)
Avatar
@Kishikawa Katsumi 回答ありがとうございます!とても腑に落ちました! UIKitをimportしていたので外したところ、通りました Intではない他のstructを作成して、配列に入れてみるとコンパイルが通るのも、 Intではどの型として評価すべきか1つに定まらないが 他の型ではArrayに定まるからなんですね
7:45 AM
コードを書いていて気がついたことなのですが、 if [1] as IndexPath == [1] {} このように左側だけキャストしてもコンパイルが通るのは、 勝手に右側も合わせてくれるからなのですか??
Avatar
Kishikawa Katsumi 12/15/2018 9:17 AM
代入と違うところは演算子も関数扱いなので、右辺と左辺はそれぞれ関数の引数に与えるのと同じです。 なのでリテラルからどう型推論が解決されるかは演算子(関数)の引数がとりうる型にもよります。 ==static func == (Self, Self) -> Bool なので、どちらか一方が決まるともう片方も決まることになります。
👀 1
Avatar
回答ありがとうございます! どちらか一方をちゃんと指定すれば、もう片方は型推論で決まってくれるんですね
Avatar
importしてきたFrameworkのpublicなstruct, class, funcなどを全てwrapする方法はありますか? 今は以下のように一つずつtypealiasでwrapしようかと考えています。 import SomeFramework public typealias Dog = SomeFramework.Dog public typealias Cat = SomeFramework.Cat
Avatar
wrapするとは違いますが名前を全部展開したいのなら @_exported import SomeFramework という記述ができますよ、非公式仕様ですが
Avatar
ありがとうございます! まさに欲しかったやつでした・・・!
😃 1
Avatar
https://github.com/t-ae/memory-crash-test 最小構成作ったんですが上のパッケージをリリースビルドでテストを走らせるとクラッシュします。 この行をコメントインすることでクラッシュしなくなるのでどこかで不当にメモリが開放されてそうです。 https://github.com/t-ae/memory-crash-test/blob/master/Sources/memory-crash-test/Broadcast.swift#L22 printデバッグした感じではtestExampleの終了周りでクラッシュしてるみたいです。 https://github.com/t-ae/memory-crash-test/blob/master/Tests/memory-crash-testTests/memory_crash_testTests.swift#L5-L15 $ swift test -c release [3/3] Linking ./.build/x86_64-apple-macosx/release/memory-crash-testPackageTe… Test Suite 'All tests' started at 2019-03-29 18:38:34.556 Test Suite 'memory-crash-testPackageTests.xctest' started at 2019-03-29 18:38:34.556 Test Suite 'memory_crash_testTests' started at 2019-03-29 18:38:34.556 Test Case '-[memory_crash_testTests.memory_crash_testTests testExample]' started. broadcast: start broadcast: end will exit testExample Exited with signal code 11 誰かなにか分かりませんでしょうか? 環境 $ swift --version Apple Swift version 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3) Target: x86_64-apple-darwin18.5.0 $ swift package --version Apple Swift Package Manager - Swift 5.0.0 (swiftpm-14490.60.2)
Contribute to t-ae/memory-crash-test development by creating an account on GitHub.
Contribute to t-ae/memory-crash-test development by creating an account on GitHub.
Contribute to t-ae/memory-crash-test development by creating an account on GitHub.
9:42 AM
アップデート前は動いてたはずなのでswift5コンパイラのバグじゃないかなぁと疑っています。 (edited)
Avatar
swift-DEVELOPMENT-SNAPSHOT-2019-03-26-aでは直ってるみたいですね。
Avatar
じゃあとりあえず様子見ですね
12:08 PM
確認ありがとうございます。
Avatar
norio_nomura 3/29/2019 1:00 PM
swift-5.0-branchでは直ってないので、放っておくと5.1まで直らないのでは。
Avatar
報告だけでもしておいたほうがいいですかね。 原因が全く分かってないのがちょっとあれですが……
Avatar
@omochimetaru 先日のに関連してもう一つ質問よろしいですか? Routing <- Vapor <- MyProjectのように、MyProjectがVaporに依存し、VaporがRoutingに依存しています。 そして、 ParameterというprotocolがRoutingの中で宣言されています。 Vaporというpackageの中で先日お聞きしたような@_exportedやtypealiasは使われていなかったのですが、MyProjectで import Vaporとしただけで、Parameterという名前を使えるのが不思議です。 SwiftPMで依存しているライブラリの名前は全て展開されるということなのでしょうか? https://github.com/vapor/routing.git https://github.com/vapor/vapor.git
🚍 High-performance trie-node router. Contribute to vapor/routing development by creating an account on GitHub.
💧 A server-side Swift web framework. Contribute to vapor/vapor development by creating an account on GitHub.
Avatar
https://github.com/vapor/vapor/blob/master/Sources/Vapor/Exports.swift @_exported import CryptoKit @_exported import HTTPKit @_exported import RoutingKit @_exported import ServiceKit @_exported import ConsoleKit @_exported import Foundation
💧 A server-side Swift web framework. Contribute to vapor/vapor development by creating an account on GitHub.
11:25 AM
↑ここでexported importされているからだと思います。
Avatar
@omochimetaru あああ本当ですね!GitHub上で "@_exported"で検索したら出なかったのでないものと思い込んでいました。ありがとうございます!すごくスッキリしました!
Avatar
omochimetaru 4/2/2019 3:20 AM
@_exported で検索すると多分アットマークがユーザー名の意味とかになってしまいますね、exportedで検索したら出ました。
Avatar
本当ですね。いい学びになりました!ありがとうございます。
🙂 1
Avatar
vicktorManuel 4/13/2019 2:08 AM
What arquitectura is best
2:09 AM
Mvc , clean architecture, mvvm?
Avatar
There is no sliver bullet in the architecture, each of them has weakness and strength. If you want to know more information about each architecture, you can check this book, https://www.objc.io/books/app-architecture/ (edited)
iOS Application Design Patterns in Swift
👌🏾 1
Avatar
Frameworkの中でCocoa Touch FrameworkやCocoa Touch Static Libraryを使って切り分けているのですが、これらをUIKit.UITableView などのようにSubmodule化することはできるのでしょうか? http://nsomar.com/modular-framework-creating-and-using-them/ この記事を読んでみたのですが、理解できていません。 (modulemapというのはObjective-Cなどで書かれたFrameworkの内部を切り分けるために使われるものでSwiftオンリーで書かれたものにはあまり関係ないのかなと朧げに理解しています) (edited)
How to create and use modular framework in IOS and Macosx.
Avatar
omochimetaru 4/17/2019 2:53 AM
Swift自体にはsubmoduleの機構は無いという理解です。 modulemap自体にはsubmoduleの機構があって、Swiftはそれをサポートしてるから、 C/ObjCのモジュールを取り込むときに限ってSwiftはsubmoduleを扱える。
Avatar
お返事ありがとうございます。なるほどです。 それでは、下記のようにHogeという名前が競合しそうな時にはどのように整理するのがいいのでしょうか? MyFramework.Sub1.Hoge MyFramework.Sub2.Hoge
3:01 AM
MyFrameworkの中にexports.swiftのようなものを用意して import Sub1 import Sub2 public typealias Sub1 = Sub1 public typealias Sub2 = Sub2 みたいに書いたり import Sub1 import Sub2 public struct Sub1 { public typealias Hoge = Sub1.Hoge } public struct Sub2 { public typealias Hoge = Sub2.Hoge } みたいに書いたりできないかなーと模索しているのですが。structの名前とsub frameworkの名前をずらせばこれでも書けない事はないのですが、全部aliasを貼るのもすごく面倒なのでもっといいやり方があるのではないかと思っています。
Avatar
omochimetaru 4/17/2019 3:08 AM
そういう場合MyFrameworkのユーザ側では Sub1.Hoge と Sub2.Hoge で扱うか、 ソースファイルごとに import MyFramework fileprivate typealias Hoge = Sub1.Hoge とかやるしか無いと思います。 それかパッケージをわけてMyFrameworkSub1とMyFrameworkSub2を作る。 その上でMyFrameworkも作って、MyFrameworkSub1とMyFrameworkSub2をexportすれば、 ユーザ側で import MyFrameworkSub1 とできるようになります。
Avatar
やりたい事と合致するかはわかりませんが、classだけimportする、とかはできるようです。 import class UIKit.UITableViewController https://thoughtbot.com/blog/swift-imports
How to be a Swift importer (and possibly exporter).
Avatar
お二人ともありがとうございます。 @omochimetaru さんのコメントを見て気づいたのですが、 MyFrameworkのなかで以下のようにしておけば @_exported import Sub1 @_exported import Sub2 MyFrameworkのユーザー側で下記のようにSub1, Sub2を使えるのですね。 let hoge1 = Sub1.Hoge() let hoge2 = Sub2.Hoge() 名前の衝突が問題だったので、やりたかった事はこれで解決できました。ありがとうございます。 (@_exported importをすると、Sub1やSub2などの名前空間は消失してしまうのかと思っていました。)
Avatar
omochimetaru 4/17/2019 4:56 AM
そうですそうです。
Avatar
Kishikawa Katsumi 4/17/2019 4:59 AM
@_exported ってそんなに便利なものじゃないのでこの場合だと MyFramework と Sub1、Sub2をそれぞれ個別に、あるいはSub1、Sub2のフレームワークとして提供する方がいいと思いますよ。
Avatar
ありがとうございます。 意味の分解やまとめ方やレイヤーをいろいろ考えてFrameworkをまとめたり、バラしたりを繰り返しています笑
Avatar
Kishikawa Katsumi 4/17/2019 8:30 AM
基本的には使う側が依存関係も含めてセットアップして、使うものをその都度具体的に指定(=import)が良いと思います。 (依存のやつを本当に見せたくない・意識させたくないというのはあるとは思うんですけど、隠す場合衝突とか他の問題も出てくるので、この原則に従う方が(使う人のスキルも必要になるけど)大抵は良いはず。。。)
Avatar
結局岸川さんのご意見を聞いた後、検討した結果おっしゃる通りバラすことにしました。結果的にはこの方がスッキリしました。良かったです!
😄 1
Avatar
メインスレッドでDispatchQueue.main.async(execute workItem: DispatchWorkItem)を呼んだ場合のworkItemの実行タイミングはどのように決まるのでしょうか? DispatchQueue.main.asyncをメインスレッドでworkItemを実行する程度にしか考えていなかったので // on main thread print("1") DispatchQueue.main.async { print("2") } print("3") のようなコードの実行順序が1,3,2になることに気がつけずにハマってしまい気になりました。
Avatar
Kishikawa Katsumi 4/21/2019 4:44 PM
1, 3, 2は自然な順序にみえます。 1, 3は1つのスレッドで3の方が下にあるので1より後、2はこのメインループでキューに追加されるので1, 3より後の次のメインループ以降に実行される、キューに追加されたものはキューというからには先に追加されたものが先に実行される、だと思います。
Avatar
メインループでキューに追加される
ありがとうございます!キューの解説で理解できました 具体的に上の事象はviewDidLoadでmain.asyncした場合にlayoutSubViews相当のタイミングで呼ばれるということから興味を持ったのですが、viewDidLoad以降は連続してメインループでレイアウトあたりまで行なっていると考えると合点が行きました。
(edited)
Avatar
余談ですが、似たような話で JS の Promisethenresolve 済でも同期的に実行されない仕様なことに気づかずハマったことがあります。 console.log("1"); new Promise(resolve => { resolve(42); }).then(value => { console.log("2"); }); console.log("3"); 1 3 2 (edited)
Avatar
JavaScriptのPromiseを使った非同期処理の書き方、テスト、アンチパターンについて解説した無料の電子書籍
👍 1
Avatar
です。 Swift の Promise を自作したときは同期として実装していたので騙されました。 Swift の async/awaitasync -> Foo でも同期であり得るという認識。 (edited)
Avatar
上に挙げたリンクの少し下に書かれている、 非同期コールバックを同期的に呼び出してはいけない の部分は、わかりやすくていいなと思っているんですが、ただし多用すると遅くなる 😟
Avatar
Protocolに対してRxSwiftのpropertyを定義しているのですが、使うタイミングでProtocolのままだと使えず困っています。どうしたら解決できるかご存知ありませんでしょうか? public protocol AppConfigProvider: NSObject { var config: AppConfig { get set } } // MARK : - Rx properties extension Reactive where Base: AppConfigProvider { /// Reactive wrapper for `config` property. public var config: Observable<AppConfig?> { return base.rx.observe(AppConfig.self, "config") } }
7:49 AM
7:50 AM
使うタイミングではDI用に、Protocolで変数を宣言しています。 var environment: AppConfigProvider
Avatar
omochimetaru 4/22/2019 8:20 AM
一応 TypeErasureを定義すれば問題は回避できますが、それが正しいアプローチかどうか自信無いです。 ↓回避例 // Type Erasure public class AnyAppConfigProvider : NSObject, AppConfigProvider { public var config: AppConfig { get { return base.config } set { base.config = newValue } } private let base: AppConfigProvider public init<X: AppConfigProvider>(_ base: X) { self.base = base } } // 実際の具体的なAppConfigProvider public class ACP : NSObject, AppConfigProvider { public var config: AppConfig public init(config: AppConfig) { self.config = config } } // 利用時 var a: AnyAppConfigProvider = AnyAppConfigProvider(ACP(config: AppConfig())) print(a.rx.config) (edited)
8:21 AM
受け取る側で AppConfigProvider で受け取るのではなくて、 AnyAppConfigProvider で受け取るようにします。 代入するときは AnyAppConfigProvider.init<X> で明示的に包み込みます。
8:26 AM
Member 'slf' cannot be used on value of protocol type 'ProtoA'; use a generic constraint instead
↑この種のエラーメッセージが出るのは、 RxSwift.ReactiveCompatiblevar rx: Reactive<Self> のところで、 プロトコル型それ自身を Self として使おうとしているからです。
Avatar
なるほど、TypeErasureってこういうときに使えるんですね。 この場合、もしAppConfigProviderのpropertyが増えていったらその分AnyAppConfigProviderを定義する時にwrapするものが増えていくというイメージでしょうか?
Avatar
omochimetaru 4/22/2019 8:58 AM
そうなります。面倒なので避けたいですねえ。
Avatar
なるほどです。。。 今は、ちょっとダサいんですが下記のように対応しています。 public protocol AppConfigProvider { var config: AppConfig { get set } var rx_config: Observable<AppConfig> { get } } public class ACP : AppConfigProvider { public var configSubject: PublishSubject<AppConfig> public var config: AppConfig { return try! configSubject.value()} public var rx_config: Observable<AppConfig> { return configSubject } }
9:03 AM
本当は a.config a.rx.config みたいに分けたいのですが、難しいですかね・・・?
Avatar
@swift-5.0.3 struct Reactive<Base> {} protocol ReactiveExtensionCompatible { associatedtype Target var rx: Reactive<Target> { get } } extension ReactiveExtensionCompatible { var rx: Reactive<Self> { fatalError() } } struct Observable<T> {} import Foundation extension NSObject: ReactiveExtensionCompatible {} // ここまでRx struct AppConfig {} protocol AppConfigProvider: NSObject { var config: AppConfig { get set } } extension AppConfigProvider { var rx: Reactive<AppConfigProvider> { fatalError() } } extension Reactive where Base == AppConfigProvider { var config: Observable<AppConfig?> { fatalError() } } func useConfig(_ provider: AppConfigProvider) { _ = provider.rx.config } (edited)
Avatar
no output (edited)
Avatar
@usatie どうでしょう?
Avatar
omochimetaru 4/22/2019 9:19 AM
おー!
Avatar
ミソはAppConfigProviderのextensionでrxのオーバーロードを定義するのと、Base == AppConfigProviderでexistentialに対して生やすところです
👏 3
Avatar
これって、 rx のオーバーロード定義の fatalError() のところは実際には return Reactive(self) とする必要ありですか? (edited)
Avatar
そうです
Avatar
omochimetaru 4/22/2019 9:21 AM
2点目の方も必要?
9:21 AM
.rxのオーバーロードだけで行けそうな気がした
Avatar
self conformしないので無理だと思ったんですが
Avatar
omochimetaru 4/22/2019 9:23 AM
(外出中で今実験できない
Avatar
(僕も携帯で書いてました…
9:24 AM
@swift-5.0.3 struct Reactive<Base> {} protocol ReactiveExtensionCompatible { associatedtype Target var rx: Reactive<Target> { get } } extension ReactiveExtensionCompatible { var rx: Reactive<Self> { fatalError() } } struct Observable<T> {} import Foundation extension NSObject: ReactiveExtensionCompatible {} // ここまでRx struct AppConfig {} protocol AppConfigProvider: NSObject { var config: AppConfig { get set } } extension AppConfigProvider { var rx: Reactive<AppConfigProvider> { fatalError() } } extension Reactive where Base: AppConfigProvider { var config: Observable<AppConfig?> { fatalError() } } func useConfig(_ provider: AppConfigProvider) { _ = provider.rx.config }
Avatar
exit status: 1 with stderr:<stdin>:39:21: error: protocol type 'AppConfigProvider' cannot conform to 'AppConfigProvider' because only concrete types can conform to protocols _ = provider.rx.config ^
Avatar
なるほど!
Avatar
omochimetaru 4/22/2019 9:29 AM
ああ、そうか。
Avatar
@Yuta Saito おおおー!なるほどです!!!やってみます!
Avatar
compile通りました!ありがとうございます!
🎉 2
Avatar
このように書いて、コンパイルは通りました。 public protocol AppConfigProvider: NSObject { var config: AppConfig { get set } } extension AppConfigProvider { var rx: Reactive<AppConfigProvider> { return Reactive(self) } } extension Reactive where Base: AppConfigProvider { var config: Observable<AppConfig?> { return base.rx.observe(AppConfig.self, "config") } } a.rx.configを呼ぼうとすると下記のエラーが出てしまいました。 KVC-compliantにするためには何が必要なのでしょうか? Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<App.AppEnvironment 0x282777d20> addObserver:<_TtC7RxCocoaP33_F7515DBB13B60709A3CB25DD19EDD11D11KVOObserver 0x280d28690> forKeyPath:@"config" options:5 context:0x0] was sent to an object that is not KVC-compliant for the "config" property.'
Avatar
なんとなくこれは extension Reactive whare Base == AppConfigProvider にしていないから、KeyPath版の方にfallしたんじゃないですかね。== にしてみたらどうでしょう?
Avatar
(protocol型がObjC Classに対応していない予感
Avatar
今やってみたのですが、そうすると下記のエラーが出ます。 Ambiguous reference to member 'observe(_:_:options:retainSelf:)'
Avatar
違うのか。
Avatar
プロパティに@objcつけたらいけるんかな
Avatar
ただつけるだけだと下記のエラーが出てしまいますが、そんな気がします・・・! @objc can only be used with members of classes, @objc protocols, and concrete extensions of classes
10:08 AM
public protocol AppConfigProvider: NSObject { @objc var config: AppConfig { get set } var rx_config: Observable<AppConfig> { get } }
10:11 AM
しかし @objc protocolにしてみると Property cannot be a member of an @objc protocol because its type cannot be represented in Objective-CProtocol 'AppConfigProvider' is '@objc' and cannot have a superclass constraint が出てしまいます。 public @objc protocol AppConfigProvider: NSObject { var config: AppConfig { get set } var rx_config: Observable<AppConfig> { get } }
Avatar
objc protocolなら NSObjectじゃなくてNSObjectProtocolに適合すればOKぽい
Avatar
このように書いて、コンパイルは通りました。
これだと、AppConfigProviderを値に代入できないはず。。 observe を使いたい場合は (base as NSObject).rx.~~~ でできると思います
Avatar
ありがとうございます。以下のコードでやっと動くようになりました! public final class AppConfig: NSObject { public init() {} } @objc public protocol AppConfigProvider: NSObjectProtocol { @objc var config: AppConfig { get set } } extension AppConfigProvider { var rxoriginal: Reactive<AppConfigProvider> { return Reactive(self) } } extension Reactive where Base: AppConfigProvider { var config: Observable<AppConfig?> { return (base as! NSObject).rx.observe(AppConfig.self, "config") } }
10:28 AM
structにしたかったのですが、AppConfigもNSObjectにするとビルドが通るようになって動きました。
Avatar
あー、==じゃなくてもいいのは
10:30 AM
protocol extrnsionのSelf openか
10:31 AM
ん?いや、違うか
10:31 AM
objc protocol特有の自動self conformanceか
Avatar
なるほど!!!! 確かに! > @objcのself conformance
Avatar
objc絡むとめんどい
Avatar
NSObjectにしてObserveするとstructを使えず、AppConfigのpropertyを変更しただけだとObservableに流れてこないので、変更を通知するためにはインスタンスごと変更するなど、ちょっとコツが必要でした。そのため、名前をわかりやすいように分けるだけなら下記のような実装でもいいかなと思って、今はこんな感じで実装しています。 protocol AppConfigProvider { var rx: RxEnvironmentProvider { get } var config: AppConfig { get set } } protocol RxAppConfigProvider { var config: Observable<AppConfig> { get } } final class AppEnvironment: AppConfigProvider { private var rx: RxAppEnvironment var config: AppConfig { get { return try! configSubject.value() } set { rx.configSubject.onNext(newValue) } } } struct RxAppEnvironment: RxAppConfigProvider { let configSubject: BehaviorSubject<Entity.AppConfig> var config: Observable<AppConfig> { return configSubject } }
Avatar
どこに投稿すればいいかわからなかったのですが、Default Protocol Extension の優先順位ってどうやって決まってるんでしょうか? 下記の例の場合、やりたいことはできているのですがルールがよくわかっていないため不安でして・・・ @swift-5.0.3 protocol Foo { associatedtype Bar func hoge() } extension Foo where Bar: Decodable { func hoge() { print("Decodable.hoge") } } extension Foo where Bar == String { func hoge() { print("String.hoge") } } struct FooImpl1: Foo { typealias Bar = [String] } struct FooImpl2: Foo { typealias Bar = String } let foo1: FooImpl1 = FooImpl1() let foo2: FooImpl2 = FooImpl2() foo1.hoge() foo2.hoge()
Avatar
Decodable.hoge String.hoge
Avatar
StringもDecodableなので、どちらの実装が適応されてもおかしくない気がしています。
Avatar
omochimetaru 4/24/2019 7:41 AM
==のほうが強い、みたいな規則があります
7:41 AM
強さが同じものが複数ある場合、曖昧であるとしてコンパイラエラーになった気がします。
Avatar
なるほど・・・!
7:43 AM
@swift-5.0.3 import Foundation protocol Foo { associatedtype Bar func hoge() } extension Foo where Bar: Decodable { func hoge() { print("Decodable.hoge") } } extension Foo where Bar: Encodable { func hoge() { print("Encodable.hoge") } } struct FooImpl1: Foo { typealias Bar = String } struct FooImpl2: Foo { typealias Bar = String } let foo1: FooImpl1 = FooImpl1() let foo2: FooImpl2 = FooImpl2() foo1.hoge() foo2.hoge()
Avatar
exit status: 1 with stderr:<stdin>:20:8: error: type 'FooImpl1' does not conform to protocol 'Foo' struct FooImpl1: Foo { ^ <stdin>:5:10: note: multiple matching functions named 'hoge()' with type '() -> ()' func hoge() ^ <stdin>:9:10: note: candidate exactly matches func hoge() { ^ <stdin>:15:10: note: candidate exactly matches func hoge() { ^ <stdin>:24:8: error: type 'FooImpl2' does not conform to protocol 'Foo' struct FooImpl2: Foo { ^ <stdin>:5:10: note: multiple matching functions named 'hoge()' with type '() -> ()' func hoge() ^ <stdin>:9:10: note: candidate exactly matches func hoge() { ^ <stdin>:15:10: note: candidate exactly matches func hoge() { ^ <stdin>:31:1: error: ambiguous use of 'hoge()' foo1.hoge() ^ <stdin>:9:10: note: found this candidate func hoge() { ^ <stdin>:15:10: note: found this candidate func hoge() { ^ <stdin>:32:1: error: ambiguous use of 'hoge()' foo2.hoge() ^ <stdin>:9:10: note: found this candidate func hoge() { ^ <stdin>:15:10: note: found this candidate func hoge() { ^
Avatar
そもそも二つ競合してる時は、どちらも適応されないことになるのか
7:46 AM
@swift-5.0.3 import Foundation protocol Foo { associatedtype Bar func hoge() } extension Foo where Bar: Decodable { func hoge() { print("Decodable.hoge") } } extension Foo where Bar: Encodable { func hoge() { print("Encodable.hoge") } } struct DecodableBar: Decodable {} struct EncodableBar: Encodable {} struct FooImpl1: Foo { typealias Bar = DecodableBar } struct FooImpl2: Foo { typealias Bar = EncodableBar } let foo1: FooImpl1 = FooImpl1() let foo2: FooImpl2 = FooImpl2() foo1.hoge() foo2.hoge()
Avatar
Decodable.hoge Encodable.hoge
Avatar
entry point (_main) undefined. for architecture x86_64
11:54 AM
このエラー見覚えある方いませんか??
Avatar
iOSなら @UIApplicationMain がなくなってる とか?
Avatar
あります..
Avatar
Recently I downloaded Xcode 9 and created one sample iPhone app but the app is not able to build as it shows the following error: ld: entry point (_main) undefined. for architecture x86_64 I se...
Avatar
現在、Cocoa Touch Frameworkを使って責務を分割して、iOSアプリを作っています。アプリ本体以外のFrameworkにおいて、CocoaPodsで入れたFrameworkを使おうとすると No such module と言われてしまい、対処法がわかりません。 App : アプリ本体のFramework。他の全てのFrameworkに依存。 Feature1 : ある機能の画面やロジックなどが入ったFramework Feature2 : ある機能の画面やロジックなどが入ったFramework AppCore : AppFeature1Feature2などが依存するFramework こんな感じの構成でして、 AppからはCPのframeworkを使用できるのですが、その他のFrameworkでは使えなくて困っています。
5:25 AM
対処法がわかる方がいらっしゃいましたら教えていただけないでしょうか?
5:27 AM
Podfileはこのようになっています。 workspace 'App.xcworkspace' project 'Sources/App/App.xcodeproj' target 'App' do use_frameworks! pod 'Firebase/Core' pod 'Fabric', '~> 1.10.0' pod 'Crashlytics', '~> 3.13.0' target 'AppTests' do inherit! :search_paths end end
Avatar
すみません、自己解決できました。このように、Podfileを書くときに各Target内でどのprojectなのか明記してあげればよかったみたいです。 workspace 'App.xcworkspace' target 'App' do project 'Sources/App/App.xcodeproj' use_frameworks! install_pods target 'AppTests' do inherit! :search_paths end end target 'Feature1' do project 'Sources/Features/Feature1/Feature1.xcodeproj' install_pods target 'Feature1Tests' do inherit! :search_paths end end def install_pods use_frameworks! pod 'Firebase/Core' pod 'Fabric', '~> 1.10.0' pod 'Crashlytics', '~> 3.13.0' end
Avatar
突然失礼します🙇‍♂️どなたかお助けいただけると嬉しいです😭🥺 環境はXcode ver.10.2.1 (Swift 5)です。 現在 iOS アプリ作成中の超初心者です。🙇‍♀️ 画面遷移について質問です! (画像はストーリーボードの略図です) Delete sc. から、segue で一切繋がっていないlaunch sc. まで戻りたいのですが(コードで)、これって一気に行けますか? 段階を踏んで戻ればいけますか?? 補足 Launch sc. と cover sc. はsegue では繋がってないです。コードで遷移させてます。(図では繋がってますが、cover sc. から main sc.も時間で遷移するようにコーディングしてます) (edited)
Avatar
omochimetaru 5/22/2019 6:43 AM
presentが重なって遷移しているのであれば、dismiss一発でいけますよ https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss
6:43 AM
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack.
Avatar
@omochimetaru 重なってなくて、dismiss で一発で行けなかったクチです🥶
Avatar
omochimetaru 5/22/2019 6:47 AM
コードで遷移させてます。
これがどういう方法でやってるかで状況が変わってきそうです。 NavigationControllerのpushだったら、NavigationController自体はpresentのスタックにおいてある1段だけを維持してますが
6:47 AM
window.rootViewController = vc とかをやっていると、
6:48 AM
その時点で過去の遷移スタックがなくなってたりします。
Avatar
@omochimetaru Cover sc.→ main sc. へはコードで nextView = storyboard.instantiateViewController 使ってやってます! 他はストーリーボード上でsegue で繋いでます!
Avatar
omochimetaru 5/22/2019 6:54 AM
そのnextViewって present(nextView) で表示してますか? (edited)
Avatar
あ、です!
Avatar
omochimetaru 5/22/2019 6:55 AM
それなら全部遷移スタックに載ってそうなので、
6:55 AM
dismissを呼び出す対象のオブジェクトが間違ってるかもしれません。
6:56 AM
例えば上の図によるとInfo画面はNavigationControllerの中にあるので、 infoViewController.dismiss() とやってもうまくいきません.
Avatar
self.navigationController?.popToViewController(...)でやっても、結局行けるのがnavigation controller入れてるinfo画面までなので、それよりも前の最初のlaunch画面まで行ける方法があれば教えていただきたいです🙇‍♂️
Avatar
Kishikawa Katsumi 5/22/2019 9:19 AM
できるかできないで言えばできる(正確にはやる方法はある)、んですけど、画面の構成によってはメソッド1つ呼ぶだけ、だと無理かもしれません。 今までも情報をまとめると、おそらくPushとPresent(モーダル)の遷移が混ざってると思うので、 popとdismissを組み合わせてがんばって戻るか、 ちょっと設計を見直してPushあるいはPresentだけにする、としてもいいかもしれないです。 ちょっと余談ですが、画面遷移の方法と見た目は分離されているので、Pushでもモーダルのような表示(あるいはその逆)というのも可能です。
Avatar
segueの動きがどうなってるのかわからないので推測でしか言えないのですが、 self.navigationController?.dismiss() を呼ぶとどうなるんですか?
Avatar
@Kishikawa Katsumi 余談の、気になります😂 Popとdismiss、前回試したときは書き方が悪かったんでしょう、うまく動いてくれなかったのでまた考え直してみます😭 ありがとうございます!
9:41 PM
@lovee それはやったか記憶がないので今日やってみます!
🤗 1
9:41 PM
皆様助言ありがとうございます!!
Avatar
@lovee self.navigation controller?.dismiss呼んだ結果、何も起こりませんでした。
Avatar
あ、何も起こらないんですね。。。 self.navigationController?.dismiss()self がDelete sc.と表現されているViewControllerなら、Cover sc.のViewControllerまでは戻りそうな気がぼくもしてたんですけど。
Avatar
@hironytic ()の中って当然animated: trueなど書きますよね? Dismissで使う()の中身で書いてやった結果なにもならなかったです。
Avatar
omochimetaru 5/24/2019 5:48 AM
たぶん何か齟齬が生じていそうです、コードが公開できれば解決できると思います。
Avatar
@omochimetaru すみません꒰༎ຶ﹏༎ຶ๑꒱ありがとうございます! 画像送ります!! Self.naviC?.dismiss( )でならなかったので、一旦info画面まで戻るコードに戻してます。
Avatar
omochimetaru 5/24/2019 5:52 AM
いえ、「戻るコード」だけの問題ではなく、「他の画面の遷移がどうなっているか」も絡む問題なので、 Storyboardとか他の画面のコードとか、全部みないと多分わからないです。
Avatar
あーなるほど。 ちょっとまってくださいね…
5:54 AM
コード全部は難しいかと。 ストーリーボードのあげます!
Avatar
ああ、下方向の矢印がpresentで右方向の矢印がpushなのかと勝手に思ってたんですが、そういうわけでもないんですかね。少なくとも各画面の遷移に絡む部分がきちんとわからないと答えようがなさそうです。
5:58 AM
赤: delete sc. 黄: normal launch sc. 緑: cover sc. 青: login sc. です🙇‍♂️
5:59 AM
@hironytic 申し訳ありません… 矢印の書き方に普通はこう、みたいなのがあったのですね… 不勉強で申し訳ありません…
Avatar
あ、ごめんなさい、普通はこうというのはないと思います。ぼくが勝手にそう解釈してしまっただけです 🙏
Avatar
@hironytic あ、そうなのですね! 重ね重ねすみません😭
Avatar
omochimetaru 5/24/2019 6:02 AM
self.navigationController?.presentingViewController?.presentingViewController?.dismiss(animated: true)
6:02 AM
これだとどうなりますか?
Avatar
cover→normal L :presentモーダリー info→delete: show(e.g. push) で繋がってます。
6:03 AM
@omochimetaru ありがとうございます! やってみます!
6:09 AM
@omochimetaru cover画面まで戻りました!
Avatar
omochimetaru 5/24/2019 6:10 AM
self.navigationController?.presentingViewController?.presentingViewController?.presentingViewController?.dismiss(animated: true)
6:10 AM
もういっこ増やすといけます?
Avatar
ログイン画面から来てたらログイン画面には戻れます。 私も以前omochimetaru さんが仰っているようにpresentingVC?を増やすやり方やったんですけど、これだと、ログイン画面から来た場合はログイン画面に戻りますが、create account sc.からcover画面行ってdelete 画面に来てたらcreateA sc.に戻ります。 つまり、どこから来たかに依存しますね。ほかの画面でもモーダリーやnavigationC使ってる所があるので、そこから来てたらそっちに戻っちゃうと思います🙇‍♂️
Avatar
omochimetaru 5/24/2019 6:19 AM
はい、なので、AppDelegateのプロパティとかにloginVCをプロパティで持っておいて
6:19 AM
(UIApplication.shared.delegate as! AppDelegate).loginVC?.dismiss(animated: true)
6:19 AM
などとやると、どっからでも戻ってこれます。
Avatar
なるほど!!😍 didFinishLaunchingWithOptions 使うやつも教えていただいたので、omochimetaru さんの仰ってるやり方とdidF~のやり方と、試してみて設計によりマッチングする方で仕上げてみます!! 本当に皆様ご助言ありがとうございます!!助かりました🙏😭✨✨
🎉 2
6:26 AM
あと、同じアプリの別疑問なのですが、textFieldタップしたらkeyboardが出てくると思うのでそれを閉じたいです。 色んなところにtext fieldあって一個一個にUITextDelegate 書いて、override func touchesBegan と func textFieldShouldReturn など書いてってしていくのが面倒です。 そこでキーボード閉じる↑を書く別クラス作って、必要クラスで呼び出す方法で書きたいのですが、これって可能ですか?
6:27 AM
クラスのviewDidLoad に別クラスを呼び出す方法がわかりません💦 ご教授いただけると幸いです🙇‍♂️
Avatar
画面戻すのに関しては Unwind Segue を使うのが一番お手軽だと思いますよ。PushとPresent混在していても特に意識せずいけますし。 (edited)
Avatar
omochimetaru 5/24/2019 6:54 AM
そこでキーボード閉じる↑を書く別クラス作って、必要クラスで呼び出す方法で書きたいのですが、これって可能ですか? クラスのviewDidLoad に別クラスを呼び出す方法がわかりません
↑この文の日本語の解釈が正確にできなかったんですが、例えば下記のような実装は可能です↓ class ViewController : UIViewController { @IBOutlet var textField: UITextField! let keyboardCloseHelper = KeyboardCloseHelper() override func viewDidLoad() { super.viewDidLoad() keyboardCloseHelper.add(textField) } }
6:55 AM
キーボードを閉じる別クラス(KeyboardCloseHelper)を作って必要クラスで(ViewController)で呼び出す
Avatar
@rintaro !!👀 そういうのがあるんですね! 調べてみます! ありがとうございます😊
12:44 PM
@omochimetaru いつもありがとうございます🙇‍♂️ なるほど。 別クラス作って呼び出すにしても、そこまでコード書かないといけないんですね🤔 ありがとうございます!
Avatar
@omochimetaru めっちゃ因みになのですが… .add メソッドなかったです…
Avatar
omochimetaru 5/27/2019 4:43 AM
あ、KeyboardCloseHelperというクラスは標準ライブラリには存在しません、自作しよう、という意味です
Avatar
@omochimetaru はい。KeyboardCloseHelper は自作されているのはわかっていたので、そこは自分のクラス名にしてインスタンス化まではしました。 ViewDidLoad に書いた時に.add というのが存在しないみたいで、エラーが出ました。addChildView...ですかね?子ビューのなら出てきました。
Avatar
omochimetaru 5/27/2019 5:04 AM
KeyboardCloseHelperにaddメソッドを自作するのです。
Avatar
なるほど!!?!👀 そうことでございましたか👀 今日後ほど、もしくは明日やってみます😭
Avatar
Kishikawa Katsumi 5/27/2019 2:03 PM
キーボードを閉じるならtextFieldを保持していなくても self.view.endEditing(true) でそのビューに乗っているビュー全部に対して resignFirstResponder を呼んでくれるので、それを適当なタイミングで呼んだらいいと思いますよ。
Avatar
@Kishikawa Katsumi ふぉぉ! ありがとうございます!😳🥺
8:46 AM
諸事情によりまだキーボード閉じるのできてないので、また後日、結果ご報告させていただきます🙇‍♂️皆様本当にいつもありがとうございます!!😭
Avatar
SwiftPM で Swift のバージョンを指定するのってどうやるんでしょう?何もなしに generate-xcodeproj すると Swift 4.0 が指定されているようで、やり方を調べてみたのですが分かりませんでした 🙇 (edited)
Avatar
omochimetaru 5/29/2019 8:48 AM
Package.swiftの1行目のコメントの
8:48 AM
// swift-tools-version:5.0
Avatar
おぉ、コメントを書き換えるんですね、ありがとうございます。
Avatar
どっちかというと https://github.com/apple/swift-package-manager/blob/master/Documentation/PackageDescription.md の swiftLanguageVersions じゃないでしょうか? (edited)
The Package Manager for the Swift Programming Language - apple/swift-package-manager
Avatar
omochimetaru 5/29/2019 9:50 AM
おお。知らなかったです。
Avatar
おぉ、ありがとうございます!
1:48 PM
これまで一個の repository の中に複数の library を入れてたんですが、コード量も増えてきて Swift のバージョンが上がるたびにまとめて修正するのが結構大変なので repo ごと細かく分割してこうかなと思ってます。 この場合パッケージ名は、 SwiftyMathCore, SwiftyMathAlgebra, SwiftyMathTopology などという風に、プロジェクト名の prefix をつける感じにするのが良いんでしょうか? おすすめのやり方などあれば教えて下さい🙇
Avatar
omochimetaru 5/29/2019 2:28 PM
そうですね、僕はよくそういう命名をしてます。 Mathは自明なので SwiftyAlgebraとSwiftyTopology でも良いかもしれませんが。
😀 1
Avatar
こんにちは🌞 またまた質問です🙇‍♂ TextViewで textDidChangeNotification を使いたいのですが可能でしょうか? (Swift5) TextView ではなくても、文字を何行も入力できるものであればよいのですが…(イメージとしては、メールの内容部分を書く所です。)(本当はtextField でしたかったのですが、文字量に合わせて改行が難しいようだったのでTextView にしました) どなたか宜しくお願い致します🙇‍♂️
Avatar
使えるはずかと 🤔 一応UITextViewもtextDidChangeNotificationがありますので https://developer.apple.com/documentation/uikit/uitextview/1618609-textdidchangenotification
Avatar
なるほど…🤔 でしたら他の部分が違うのかもしれないです! ありがとうございます!!!
Avatar
先程の続きなのですが、うまく動かなかったので教えてください🙏 下手な関数で誠に申し訳ないのですが、textField(title)とtextView(detail)のある画面にON OFFが切り替わるdraftButton, registerButtonがあります。 ・title, detailどちらも空→ボタン2つともOFF ・title, detailどちらも記入→ボタン2つともON ・title, detailどちらかが空→draftButtonのみON の挙動にしたいのですが、現状: ・title 入れない限りdetailに文字入れてもボタンOFFのまま ・detailに文字ありでtitle入れる→ボタンどちらもON ・detailに文字ありでtitle入れて消して空にする→draftButtonのみON ・↑の状態からdetail消す→draftButton ONのまま という感じです… titleいれるまでif文内を走ってくれません。 どうしたら良いでしょうか(´°̥̥̥ω°̥̥̥`)どなたかご教授お願い致します○rz
8:00 AM
8:00 AM
Avatar
恐縮なんですが、正しいAPIがどれか、というより先にデバッグの手順について学んだほうが良いかもしれません。
  • 理想的な挙動は何か
  • 現状起きていることの正確な理解と分解
  • その差を埋めるために何が必要か考える 例えばfunctionが呼ばれないのであれば、繋ぎ込みが間違えているので、
  • どこまで動いているのか、途切れている箇所を特定する
  • 途切れている箇所が自分の責任なら直す
  • 違うなら代替となる手段を探す
このような事をご自身で試していく必要があります。
Avatar
@tarunon ありがとうございます。 「現状起きていることの正確な理解と分解」、特に分解が凄く苦手なのは把握しているので、そこら辺をもっと勉強します!🙇‍♂️
Avatar
デバッグはコーディング同様に色々なテクニックがあるのですが、学べるようにはなっていないので(美しいコードはgithubで見れるが、デバッグは否) 参考になるサイトとかあると良いんですけどね
😭 1
8:27 AM
textFieldとtextViewで共通した処理を書いていると思うのですが、最後の判定まで共通化せずに書くと、途中の関数の疎通確認がやりやすくなると思います
8:27 AM
まず問題を分解してみましょう
Avatar
@tarunon ありがとうございます! やってみます!🙏
Avatar
ぼくがやるとしたら、とりあえず buttonItemsStatus の先頭あたりでいったん titleTextField.textdetailTextView.text の値を、それぞれ別の変数に入れてみてデバッガで止めるなり、ログに出すなりしてその値がどうなってるか見てみるとかしますね。
8:44 AM
それぞれの値が自分が想定していたものになっているかどうかと、思ったタイミングで buttonItemsStatus が呼ばれているだろうか?というあたりですかね。
Avatar
@hironytic なるほどですね。🤔 ありがとうございます!!!🙏😭
Avatar
@hironytic @tarunon お二方のおかげで無事解決しました!!分解して細かくして見ていくの大切ですね…!!! 本当にありがとうございます!!🙏✨✨
🎉 3
👍 1
Avatar
classにdebugQuickLookObject生やすとXcode上でプレビューを表示する機能ありますけど これってstructでも同様にプレビュー表示したい場合なにか対応方法あるでしょうか? classに生やす場合@objc func debugQuickLookObject() -> AnyObject?で定義するため、structだとそもそも宣言できません。
8:40 AM
ObjectiveCとして - (id)debugQuickLookObject メソッドで実現されてるので無理そうじゃない?
Avatar
無理そうだなーとは思ってるんですがstruct用の他の方法が提供されててもいいんじゃないかと思ったので。
Avatar
omochimetaru 6/17/2019 8:42 AM
これとは別にSwift向けのREPL連携用のprotocolなかったっけ
Avatar
これはPlaygroundっぽいですよね? 今やりたいのはブレークポイント貼って止めたところでQuickLookするという用途なのでちょっと違いそうです。
Avatar
omochimetaru 6/17/2019 8:48 AM
そうですねえ
Avatar
@_specialize で複数の型パラメータを特殊化するのってできないでしょうか? 行列の計算を @_specialize(where R == Int, Double) のようにして、頻用されるものについては特殊化して高速化したいのが目的です。
Avatar
@_specialize(exported: true, kind: full, where K == Int, V == Int) @_specialize(exported: false, kind: partial, where K: _Trivial64) func dictFunction<K, V>(dict: Dictionary<K, V>) { }
10:36 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
10:36 AM
specializeアトリビュート自体を複数書くとできると思います。
Avatar
おぉ、ありがとうございます!
10:40 AM
型を丸ごと specialize するのもできるんですかね(いま電車なので後で試してみる予定です)
Avatar
前試したけどできなかった気がします、funcにつけまくらないといけないような
Avatar
なるほどなるほど。
Avatar
別の質問なんですが、() 演算子を定義する感覚で dynamicCallable を使いたいのですが、普通のメソッド呼び出しに比べて動的呼び出しのオーバーヘッドが出てしまったりするでしょうか?
10:53 AM
いま f.applied(to: x) のように書いてるものを f(x) としたい。
10:53 AM
f は関数をラップした struct です。
Avatar
それはオーバーヘッドが出ますね dynamicCallableじゃなくてstaticCallableが出るのでそれを待ったほうがいいです https://forums.swift.org/t/se-0253-static-callables/22243
The review of SE-0253: Static callables begins now and runs through April 5, 2019. Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as t...
Avatar
おぉ!!!
11:04 AM
まさにそれが欲しかった🤩
Avatar
ちなみに、Swift for Tensorflowにはもう入ってます
Avatar
早く使いたい😍
Avatar
不勉強すぎてお恥ずかしいのですが、ここの名前を教えていただけないでしょうか… 変更できなくてシュミレーターが表示されなくなってしまいした…꒰꒪꒫꒪⌯꒱
Avatar
あ、シュミレーター出すのはできました🙇‍♂️
Avatar
omochimetaru 6/20/2019 4:37 AM
そこは Scheme です
Avatar
ありがとうございます!!!!!
Avatar
UnsafeMutablePointer を alloc した後の initialize / deinitialize は、値型の場合でも呼ばないといけないんでしょうか?
5:18 AM
pointee に直接入れるのと何が違うのか分かってません🙄
5:20 AM
struct の中で参照型を保持してるような場合に、それをちゃんとやらないと参照カウントがおかしくなるとか?
Avatar
omochimetaru 6/21/2019 5:22 AM
呼ばないといけません
5:22 AM
Swiftのメモリモデルでは、メモリ領域は、「初期化済み」と「未初期化」があって、
5:23 AM
UnsafeMutablePointer.allocateしたメモリ領域は「未初期化」であり、
5:23 AM
.pointeeにアクセスしてよいのは「初期化済み」のときだけです。
5:23 AM
pointeeに直接入れるのと何が違うのかというと
5:24 AM
pointeeへの書き込みは「既存の値の破棄」と「新しい値の構築」の2つの手順を含むからです これは通常の変数への代入のときも同じことです
5:24 AM
initializeによる書き込みは、書き込み先メモリが未初期化であることを仮定しているので
5:24 AM
「既存の値の破棄」がスキップされて「新しい値の構築」だけが実行されます。
5:25 AM
もし、未初期化のメモリ領域 に対して、「既存の値の破棄」を行ってしまうと
5:26 AM
例えば、その型が参照型のstored propertyを含む場合に、 ランダムなアドレスに対してアクセス(参照カウンタのdecrement)する事になって、ランタイムクラッシュするなどの可能性があります。
5:26 AM
「struct の中で参照型を保持してるような場合」 ↑それであってます。
Avatar
ふーむ、なるほど。
Avatar
omochimetaru 6/21/2019 5:28 AM
つまり、Swiftの値型というのは、それのもつメモリ領域に対して書き込みをするときに、適切な関数呼び出しをセットにして様々な処理をしないといけない、ということです。
5:28 AM
C言語でmemcpyするみたいに、メモリ領域をそのままコピーできるような型の事を、 C++の用語で bitwise copyableとかbitwise takableとか言うんですが
5:29 AM
Swiftのstructはbitwiseではない、という言い方もします。
5:29 AM
ただ、実際にstored propertyがIntみたいな型しか持っていないときは、
5:29 AM
実際のところはbitwise copyableであるため、問題が起きない、という事はあります。
Avatar
ふむふむ、なるほど。
Avatar
omochimetaru 6/21/2019 5:30 AM
bitwise copyable以外にも、そうした性質を「trivial」って呼ぶこともありますね。
Avatar
よく分かりました!
5:35 AM
もう一つ質問させてください🙇‍♂️ alloc の方は引数で長さを指定するのに対して、dealloc は引数なしになってるんですが、これは alloc 時にメモリ何個分を確保したかを UnsafeMutablePointer の内部で保持してるからなんでしょうか…? 感覚的には dealloc 時も同じ個数を指定しないと正しく動作しなそうな気がして🤔 (edited)
Avatar
Kishikawa Katsumi 6/21/2019 5:35 AM
allocの引数って長さでしたっけ?
Avatar
omochimetaru 6/21/2019 5:36 AM
長さじゃなくて要素数ですかね
5:36 AM
質問の答としては内部で保持しているからです。 でも、保持する場所はUnsafeMutablePointerの内部ではないです。
Avatar
Kishikawa Katsumi 6/21/2019 5:36 AM
なるほど。
Avatar
omochimetaru 6/21/2019 5:37 AM
Swiftのallocateを解析してないので予想ですが、 こういったメモリアロケータは、一般的なテクニックとしては
Avatar
すみません、要素数です。
Avatar
omochimetaru 6/21/2019 5:37 AM
メモリ確保するときに、 要求されているメモリサイズに加えて、少し多めの領域をメモリ確保していて
5:38 AM
その多めの領域に、サイズとか、その他メモリアロケータ管理用の情報を仕込んでます
5:38 AM
その領域は先頭にあって、ユーザに返ってくるポインターは
5:38 AM
その先頭領域からオフセットされたストレージの部分を指しています
Avatar
ふむふむ。
Avatar
omochimetaru 6/21/2019 5:38 AM
言い方を変えると、返ってきたポインタのマイナスのオフセットのところに、メタデータがあるってことです。
Avatar
はー、なるほど。
Avatar
omochimetaru 6/21/2019 5:39 AM
メモリ確保のときに容量を与えて、解放時はポインターだけで良いのは、 C言語のmallocとfreeの時代から、そういうスタイルですね https://linuxjm.osdn.jp/html/LDP_man-pages/man3/malloc.3.html
Avatar
dealloc を呼ぶポインタは、返ってきたポインタを使わないといけないんですよね? 例えば capacity:10 で alloc して返ってきたポインタの、次のポインタに対して dealloc を呼んだりしたら壊れるという認識で合ってそうですか?
Avatar
omochimetaru 6/21/2019 5:40 AM
あってます。
Avatar
よく分かりました!!!
Avatar
omochimetaru 6/21/2019 5:40 AM
4つ分確保しておいて、後ろ2つ分だけ解放するとかはできません。 (edited)
Avatar
おっしゃおっしゃ
5:45 AM
ありがとうございます、とてもスッキリしました😌
😁 1
Avatar
毎度恐れ入ります🙇‍♂️ 色々調べたのですが原因がわからなかったので、もしどなたか他に調べた方が良い箇所あれば教えていただきたいです! TextView 内に placeholder 設置してます。 何故か、”Comment “が “Comme” + “ nt “ で改行されます😫 検証内容は↓ ・eとnの間に空白ある→❌ ・eとnの間に\n 入ってる→❌ ・6文字英単語”anchor”入れても改行されない ・8文字英単語”arguably”入れたら途中で改行される ・adjustFontSizeToFitWidth = true ・他のサイズ決めてるコードは写真の通り です… label幅の問題なのかなとも思いますが、sizeToFit() になってます… SizeThatFit()のほうでしょうか…
Avatar
label.numberOfLines = 1 にしてからもう一回 sizeToFit() してみましょうか? sizeToFit() はラベルのサイズを動的に調節するメソッドではなく、ラベルのサイズを呼び出された時点のコンテンツに合わせて調節するメソッドです
9:48 AM
ちなみに sizeThatFits(_:) メソッドは親ビューにこのメソッド呼ばれた時の返してあげたいサイズを返すメソッドですので、それ呼ばれても特にサイズの変更はありません
Avatar
@lovee ご返答ありがとうございます!!! やってみます!!
Avatar
並列可能な処理を非同期化してみようと思っているのですが、一つの配列に並列で値を書き込むということはできないんでしょうか?以下のコードは leave のとこで EXC_BAD_INSTRUCTION が出てしまいます。count1 にすると通るのですが。 var a = Array(repeating: 0, count: 10) let group = DispatchGroup() group.enter() for i in a.indices { DispatchQueue.global().async { a[i] = i group.leave() // EXC_BAD_INSTRUCTION } } group.wait() print(a) // [0, 1, ..., 9] と出て欲しい (edited)
Avatar
omochimetaru 6/23/2019 5:03 PM
だめです
Avatar
おぉ、ダメなんですね。
Avatar
omochimetaru 6/23/2019 5:03 PM
「SwiftのArrayの要素のindex違いに対して並列なアクセスができる」というのは
5:03 PM
「よくある間違い」として挙げられています
Avatar
なーるほど。
Avatar
omochimetaru 6/23/2019 5:05 PM
var a = Array(repeating: 0, count: 10) let q = DispatchQueue(label: "array") let group = DispatchGroup() group.enter() for _i in a.indices { let i = _i DispatchQueue.global().async { q.sync { a[i] = i } group.leave() // EXC_BAD_INSTRUCTION } } group.wait() print(a) // [0, 1, ..., 9] と出て欲しい
5:06 PM
↑対応としてはこうやってArrayへのアクセスを直列化するキューを別にもつのが多分簡単です タスクそれ自体は並列化してるので効果はでるはずです。
5:06 PM
(あとforのiをキャプチャするのが怖かったのでいったん_iに置いてみました
Avatar
なるほどなるほど。
5:07 PM
書き込むとこだけ同期化すれば、書き込む値を計算するところは並列可能ということですね。
Avatar
omochimetaru 6/23/2019 5:08 PM
そです!
Avatar
あれ、上のコードをそのまま貼り付けて実行してみたのですが、やはり leave のとこで クラッシュしてしまうようです。
Avatar
omochimetaru 6/23/2019 5:11 PM
enterが一回なのが変ですね
Avatar
あっ、なるほど!
Avatar
omochimetaru 6/23/2019 5:11 PM
forループの中で開始するときに呼ぶ
Avatar
できました!!!
5:14 PM
async って例えば 1万回 呼んだりしても、内部でよしなに計らってくれるんですかね?
Avatar
omochimetaru 6/23/2019 5:15 PM
はい、globalさんは良きにやる
5:15 PM
↑こういうのもありますよ
Avatar
これは同じ処理を繰り返す時に使うものですかね?
5:16 PM
ループの回数も受け取れるのか
Avatar
omochimetaru 6/23/2019 5:16 PM
いえ、並列にやる
Avatar
var a = Array(repeating: 0, count: 10) let q = DispatchQueue(label: "array") DispatchQueue.concurrentPerform(iterations: 10) { i in q.sync { a[i] = i } } print(a) // [0, 1, ..., 9] と出て欲しい (edited)
5:18 PM
できました!
5:18 PM
こりゃいいですね、enter /leave や wait もいらないんですね。
Avatar
omochimetaru 6/23/2019 5:19 PM
そですそです
Avatar
素晴らしすぎる
5:20 PM
同期は書き込みだけすればよくて、読み込みは並列にやっても大丈夫という認識であってますか?
5:21 PM
var a = Array(repeating: 0, count: 10) let b = Array(0 ..< 10) let q = DispatchQueue(label: "array") DispatchQueue.concurrentPerform(iterations: 10) { i in let x = b[i] * 2 q.sync { a[i] = x } } (edited)
5:21 PM
例えばこういう。
5:21 PM
あ、間違えたw 直しました (edited)
5:22 PM
let x = ... のところに、重い処理が入る予定。
Avatar
omochimetaru 6/23/2019 5:52 PM
読み込みはよくわかんないです 多分大丈夫だけど僕だったら同期とります
Avatar
norio_nomura 6/23/2019 9:34 PM
SwiftLintで書き込み時の同期を無くしたparallelMap実装を1年以上使ってます。 https://github.com/realm/SwiftLint/blob/740e398f9115f1f16048ea6979060f4e83a36b1c/Source/SwiftLintFramework/Extensions/Array%2BSwiftLint.swift#L56-L64 (edited)
A tool to enforce Swift style and conventions. Contribute to realm/SwiftLint development by creating an account on GitHub.
Avatar
enum Enum: Equatable { case a case b(Int) } let a = Enum.a print(a == Enum.a) let b = Enum.b(1) //print(b is Enum.b)??? assocvalue付きのケースについてある変数があてはまるか確認する式ってないんですっけ? assertに書こうとしたら詰まったんですが。 (edited)
Avatar
omochimetaru 6/25/2019 1:38 AM
式は無い
1:38 AM
if case文になる
1:38 AM
てかそれEquatableつけられたっけ?
Avatar
手元ではコンパイルできてますね
1:40 AM
@swiftbot enum Enum: Equatable { case a case b(Int) } let a = Enum.a print(a == Enum.a) let b = Enum.b(1) print(b == Enum.b(2))
🛠 1
Avatar
swiftbot BOT 6/25/2019 1:40 AM
Author icon
t.ae
enum Enum: Equatable { case a case b(Int) } let a = Enum.a print(a == Enum.a) let b = Enum.b(1) print(b == Enum.b(2))
Version:
swift-4.2.1-RELEASE
Output:
true false
Error:
Avatar
omochimetaru 6/25/2019 1:41 AM
個人的にはcaseプロパティ生やしてる
1:41 AM
インナータイプとしてCase型を定義して。
1:42 AM
そうすれば.case同士の==で書ける
Avatar
enumが二重になるつらみはありますね。 assertだけなので最適化で消えることを祈りつつif caseで書いておきます。
Avatar
@lovee 遅くなりましたが、number of lines = 1 にしたらできました! ご丁寧な回答ありがとうございます!!助かりました😭
🎉 3
1:49 AM
(会話遮ってしまって申し訳ありません🙇‍♂️)
Avatar
失礼します! 前回解決したと思われたplaceholder の件です🙇‍♂️ 別画面でまさかのplaceholder が見切れている問題を発見してしまいまして…(┐「﹃゚。) NumberOfLine を1にしようが0にしようが見切れております… Placeholder のクラスを作り、それを必要画面のtextViewで INOutlet weak var textView: PlaceHolderTextView! で呼び出して使っています。 Placeholder クラスはちゃんと呼ばれていますし中身も走ってますし、おそらくplaceholder のwidthがtext view のwidthとうまく繋がっていないのかなぁとは予想付けているのですが、ここ数日調べてみましたが見つけられず。。 予想される原因や解決方法等ご教示いただけると幸いです(´°̥̥̥ω°̥̥̥`) RxSwiftでやってます。
1:42 AM
Avatar
layoutSubviews で label の frame を更新するか、 AutoLayout を使うといいですよ
Avatar
@nanasi ご返答ありがとうございます!! 返答いただいてから、layoutSubviewsのほうで試行錯誤してやっております。中々うまくいきませんが🤣 昨日autolayoutの方でやっててうまく実行できなかったので諦めていたのですが、やり方さえ間違えなければいけるんですね! ありがとうございます!!!!
Avatar
とりあえず単純なものであれば、これで実現できるとおもいます (sizeToFit はこの場合不要です) class PlaceHolderTextView: UITextView { override func layoutSubviews() { super.layoutSubviews() placeHolderLabel.frame = bounds.insetBy(dx: 6, dy: 6) } }
10:05 AM
ただTextViewがプレースホルダより小さい場合は結局はみ出てしまうので、その場合はAutoLayoutでやったほうが簡単です
Avatar
@nanasi ありがとうございます!! 返信滞ってしまってすみません💦 勉強不足で申し訳ないのですが、良ければご教授いただけると幸いです。そもそも、なぜTextView よりもplaceholder が大きくなるのでしょうか?? Placeholder とtextViewのwidthを同じに設定するようにコードを書いているつもりなのですが…🙇‍♂️
Avatar
例えばTextViewを w: 240, h: 44 とレイアウトして、プレースホルダの文章がそれを超えるような長い文字列の場合、TextView自体は↑のコードではサイズが変わらないためです。
4:17 AM
なのでデザイン上そういったことがなければ問題はないです 👌
Avatar
あーなるほど(?) TextViewのサイズが変わらない=それを参照している(?)placeholder のサイズも変わらない という事ですかね!?! textViewのwidth よりplaceholder の文字量が多くて大きいので、もう一度auto layout で設定してみようと思います。 ありがとうございます🙇‍♂️
Avatar
TextViewのサイズが変わらない=それを参照している(?)placeholder のサイズも変わらない
というより (親の)TextViewのサイズが変わらない=(子の)placeholderのサイズはそれを超えるとはみ出てしまう といった感じですね
5:22 AM
なので親のTextViewのサイズが十分なら先のlayoutSubviewsでも問題は解決できます
5:24 AM
プレースホルダ付きのTextViewは大抵誰もが作ったことがあるものなのでGitHubで探して参考にしてみるのもいいかもです😀 (edited)
Avatar
んーなるほど。
(子の) placeholder のサイズはそれを超えるとはみ出てしまう
のはわかりました。 しかし、はみ出た場合ははみ出る直前で改行する ためにnumber of lines や size to fitのメソッドがあるのかと思ってました。。
5:59 AM
以前nanasi さんが送ってくださったbounds.insetBy()のメソッドで、textView 内に収まってはくれたのですが、上にも空白ができてしまい(insetByが中心点の~...メソッドなので仕方ないですよね🤣)、それが解決できなければやはりauto layout をしようと思います🙇‍♂️ いつも本当にありがとうございます!!!!
Avatar
number of linesは十分なサイズが与えられたときに何行表示させるかのプロパティなので、自身のサイズが小さい場合はそれに何を設定しても関係なく、そのサイズ内でクリッピングされます(デフォルトなら ...
6:16 AM
size to fitは親ビューに関係なく自身のコンテンツがちょうど表示される大きさにframeを更新するメソッドなので、TextViewが w: 240 だったとしてもプレースホルダの文章が長いならプレースホルダのラベルは w: 400 になったりします (edited)
Avatar
うわぁぁぁぁ どちらもそういう事だったのですね…!!!! ご教授いただきありがとうございます😭😭😭✨✨
😉 1
Avatar
上にも空白ができてしまい(insetByが中心点の~...メソッドなので仕方ないですよね🤣)
その空白がどのくらいのものかですが、6ptなら指定通りです insetByは中心点は関係なく、例えば CGRect(x: 0, y: 0, width: 100, height: 50).insetBy(dx: 5, dy: 5) とすれば {x 5 y 5 w 90 h 40}と内側に dx, dy分インセットした領域を返す関数です
6:32 AM
6ptなのはスクショにあったcreateLabelのoriginを持ってきたからです😇
6:33 AM
厳密に合わすとなったらAutoLayoutでfirstBaselineなど駆使する感じですね
Avatar
なるほどですね! 空白はこんな感じです🤣 思いっきり中心にきてます。 ということはcreateLabelの設定からいじるべきですかね🤔
Avatar
そういえばラベルは縦方向は真ん中寄せでしたね😅
6:46 AM
上のコードならinsetByのあとにplaceholderLabel.sizeToFit()を付け足せばうまくいきそうです
Avatar
うわぁぁぁぁ!!! ありがとうございます!! なりました!😭 スゴイ…👼
👏 2
Avatar
Taketo Sano 7/4/2019 1:34 AM
いつの間にか Array や Dictionary も conditional に Hashable に conform するようになってたんですね 😃 Array や Dictionary 型の Key をもたせたいときに、別に struct 作ったりしてたのが面倒でした 😃 (edited)
Avatar
omochimetaru 7/4/2019 1:35 AM
Swift4.2でconditional conformanceが入った時に対応されてた気がします
Avatar
Taketo Sano 7/4/2019 1:41 AM
結構前からあったんですね😂 is便利
Avatar
Taketo Sano 7/5/2019 3:42 AM
parameterized extension がほしくて震えます😖 実現の目処って立ってるんでしょうか?
Avatar
僕の観測範囲では立ってないと思います。 ↓参照 (edited)
3:42 AM
前の裏技は難しいケースですよね?
3:43 AM
複雑なジェネリックライブラリだとぶっ壊れそうですしね・・・。
Avatar
omochimetaru 7/5/2019 3:43 AM
Parameterized Extensions Proposal: SE-NNNN Author: Alejandro Alonso Review Manager: TBD Status: Awaiting Review Implementation: apple/swift#25263 Introduction Hello Evolution, this is my first draft at a proposal for Parameterized Extensions. I would greatly appreciate ...
3:43 AM
天才のAzoy少年が
3:43 AM
最近実装してて
3:43 AM
PItchも自分で投げてた。
Avatar
お、最近だ。
3:44 AM
これはうれしい、けど、今から実装されても最速で来年( 5.2 か 6.0 )かな?
Avatar
omochimetaru 7/5/2019 3:45 AM
5.1はもうXcodeBeta3だし最速でも5.2でしょうね〜
Avatar
ほぇー、すごい。
Avatar
すえたく 7/9/2019 12:45 PM
いきなり質問失礼します spotifyのSDKを使ったiosとspotifyとの連携について質問したいです。 今、iosアプリからspotifyが公開しているSDKを使って音楽を流そうとしています。(公式tutorial: https://developer.spotify.com/documentation/ios/quick-start/ ) (SDKのgithub: https://github.com/spotify/ios-sdk) 公式のチュートリアルを読みつつ進めているのですが、herokuを使ったクライアントIDのswap/tokenとrefresh/tokenの取得が理解できずにハマってしまっています。 特に、herokuとiosアプリとのやり取りの部分で、herokuでなにを設定すればいいのか、それに伴ってiosアプリ側でなにをすればspotifyとの連携ができるようになるのかがわかりません。 もしよければ教えてください (edited)
Create a simple iOS application that uses the Spotify iOS SDK to play a track and respond to changes in playback state.
Avatar
呼んでみましたけど、Herokuは単純にtoken swapに使ってるだけで、そのロジックはローカルでも持てるので必須ではないと読み取れます、あくまで strongly discourage (非常に非推奨)だけですので
Avatar
すえたく 7/9/2019 4:02 PM
@lovee 返信ありがとうございます! 確かにその通りなのですが、最終的にgithub等でアプリを公開することを考えいて、そのためにherokuを使ったtoken swapをしたいと思っています。。。
Avatar
@すえたく なるほど、それはまあ面倒な話ですね 🤔 どっちかと言うとiOS/Swiftの領域を超えてるような…最低限のServer-Sideの知識が必要になるので、多分herokuとかのチュートリアルを探したほうがいいかもしれないです(自分もherokuのデプロイはすっごい昔に一回だけ試してみただけで完全に忘れてるので… 😓
Avatar
すえたく 7/10/2019 8:06 AM
@lovee なるほど……一度heroku関連の情報漁ってみます!ありがとうございます!
Avatar
@すえたく Document読んだ感じ One-click with Heroku とあるので 下記リンクのDeploy to HerokuをクリックするだけでHeroku側の設定は完了するかと。 https://github.com/bih/spotify-token-swap-service#one-click-with-heroku
Swap tokens for using Spotify APIs and SDKs, made really simple 🔑 ⛓ - bih/spotify-token-swap-service
Avatar
補足すると、 Herokuサーバを用意してまでやりたいことは、 Client IDClient Secret をアプリに持たせると解読等された場合に悪用される可能性あるから、 Client Secret はサーバ側に持たせることで、サーバ経由のToken更新を行い、セキュアな状態にするためみたい
Avatar
すえたく 7/10/2019 2:17 PM
@ありぜ 返信ありがとうございます! なるほど…。そうなると、herokuで何かを設定するというよりは、アプリケーション側の設定(callback用のURL等)を適切に設定すればOK。。。? クイックスタートには/api/tokenや/api/refresh_tokenを入れることになってますが、それもheroku側が自動的に設定していることになるんでしょうか?
Avatar
@すえたく
そうなると、herokuで何かを設定するというよりは、アプリケーション側の設定(callback用のURL等)を適切に設定すればOK。。。?
あーすみません、heroku側で一部だけ設定してやる必要ありました。なので手順は、下記でした。 1. Deploy to Herokuをクリック 2. https://github.com/bih/spotify-token-swap-service#configuration の環境変数項目のRequiredを最低限設定する ---
クイックスタートには/api/tokenや/api/refresh_tokenを入れることになってますが、それもheroku側が自動的に設定していることになるんでしょうか?
/api/token/api/refresh_token はHerokuサーバに対して行います。 つまり、Heroku設定後、quick-startの続きにあるコードの [my token swap app domain] をherokuのアドレスに置き換えてiOSアプリを実装したらOKです。 仮にHerokuサーバのアドレスが https://swap.heroku.com/ であれば… // Swiftコード lazy var sessionManager: SPTSessionManager = { if let tokenSwapURL = URL(string: "https://swap.heroku.com/api/token"), let tokenRefreshURL = URL(string: "https://swap.heroku.com/api/refresh_token") { self.configuration.tokenSwapURL = tokenSwapURL self.configuration.tokenRefreshURL = tokenRefreshURL self.configuration.playURI = "" } let manager = SPTSessionManager(configuration: self.configuration, delegate: self) return manager }() のように書いて、quick-startを進めていけば大丈夫かと思います
(edited)
Avatar
すえたく 7/10/2019 3:32 PM
@ありぜ なるほど! 一度その方法で動かしてみます!ありがとうございます!
👍 1
Avatar
typealias した型に対して extension や conditional conformance するのって公式にはサポートされてないんでしたっけ?以下の書き方でコンパイルも通るし,こう書いて良いのなら書きたいんですが. protocol X { static func hello() } typealias IntArray = [Int] extension IntArray: X { // typealias した型に対して extension static func hello() { print("hello") } } [Int].hello() // OK [String].hello() // ちゃんとエラーになる: Referencing static method 'hello()' on 'Array' requires the types 'String' and 'Int' be equivalent (edited)
5:04 AM
typealias してる元の型が複雑な場合,そう書けた方が読みやすいので. typealias GridChainComplex = ChainComplex1<FreeModule<TensorGenerator<MonomialGenerator<_Un>, GridDiagram.Generator>, 𝐙₂>> extension GridChainComplex { // こう書きたい }
Avatar
omochimetaru 7/11/2019 5:06 AM
それはできた気がしますね
5:07 AM
公式サポートかどうかは調べたことないですが
5:07 AM
ただ似たようなのでダメなパターンが会って
5:07 AM
public typealias Single<Element> = PrimitiveSequence<SingleTrait, Element>
5:07 AM
こういう、エイリアス側にジェネリックパラメータがあるようなやつは
5:07 AM
うまく動かなかった気がする
Avatar
なるほどなるほど.
5:09 AM
ありがとうございます🙏
5:12 AM
ちゃんと動いてそうな感じはします🤔 protocol Helloable { static func hello() } struct Something<A, B> {} typealias Something_Int<B> = Something<Int, B> extension Something_Int: Helloable where B == Int { static func hello() { print("hello") } } Something<Int, Int>.hello() // OK Something_Int<Int>.hello() // OK Something_Int<String>.hello() // NG
5:14 AM
でも前にこういう書き方でもっと複雑なことやって Seg Fault 地獄に陥った気もするので,避けといた方がいいのかな🤔 (edited)
Avatar
omochimetaru 7/11/2019 5:15 AM
Something_Intもいけてる?
Avatar
はい,いけてます.
5:15 AM
(Xcode 11 beta 3 で動かしてます)
Avatar
omochimetaru 7/11/2019 5:16 AM
そのへん直してた頃があった気もするので今はいけるのかも。
Avatar
おっ,そうなんですね.
Avatar
macOS の selectAll(_:) の iOS版 メソッドって存在しますか??💦
Avatar
Kishikawa Katsumi 7/18/2019 2:58 AM
UIResponderがselectAllメソッドを持っています。 TextViewなどに呼べば動きます。 https://developer.apple.com/documentation/uikit/uiresponderstandardeditactions/2354200-selectall
Avatar
@Kishikawa Katsumi ありがとうございます!😭
3:05 AM
すみません、書き忘れておりました。 tableView内で使っています。 allowMultipleSelectionDuringEditing メソッドを使用していて、table view cell を複数選択することはできます。 やりたい事は、存在するtable view cell をボタンタップで一気に全選択することです。🙇‍♂️ select Allのメソッドだったらそれはできるのかなーと思い、iOS版で同じようなメソッドがあるか探しています。(現在 for in 文でできるか検証中です)🙇‍♂️
Avatar
Kishikawa Katsumi 7/18/2019 3:15 AM
TableViewでしたか。それは自分で書くしかないです。
Avatar
@Kishikawa Katsumi そうなのですね! ご教授くださりありがとうございます!!!✨✨
Avatar
Swift 5.1 だと Python.import って動かないですか?
4:29 PM
Swift REPL でやろうとしてます。
Avatar
omochimetaru 7/18/2019 4:29 PM
import Python書けば使えるような気が
Avatar
あれれ
4:29 PM
1> import Python 2> let numpy = Python.import("numpy") error: repl.swift:2:13: error: module 'Python' has no member named 'import' let numpy = Python.import("numpy") ^~~~~~ ~~~~~~ (edited)
4:29 PM
こうなってしまいまして🙄
Avatar
omochimetaru 7/18/2019 4:30 PM
あれー。モジュールはあるんですね。
4:30 PM
モジュールの中身をダンプするREPLコマンドがなんかあるから
4:31 PM
Pythonに何があるか確認するとよさそう
4:32 PM
なんだったかな・・・
Avatar
swift -frontend -replで起動して、インポートして:print_module <モジュール名>ですね。
11:46 PM
xcode-selectXcode-beta.appを選択していない場合、-sdkパラメータも追加で渡す必要があるぽい。
11:46 PM
こんな感じ。 $ DEVELOPER_DIR=/Applications/Xcode-beta.app swift -frontend -repl -sdk $(DEVELOPER_DIR=/Applications/Xcode-beta.app xcrun -sdk macosx -show-sdk-path) *** You are running Swift's integrated REPL, *** *** intended for compiler and stdlib *** *** development and testing purposes only. *** *** The full REPL is built as part of LLDB. *** *** Type ':help' for assistance. *** (swift) (edited)
Avatar
おっ、ありがとうございます!
Avatar
omochimetaru 7/19/2019 1:31 AM
:print_module Pythonしたら4000行ぐらい出てきた
1:37 AM
@_exported import Python.import_ これは見えるけど import_は無いなあ
1:42 AM
これPython.frameworkが見えてるだけでSwiftバインディングじゃないっぽいな
1:44 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
1:44 AM
S4TFからこのディレクトリのソースコピペしてきて、まずそれを読み込めば行ける気がします。
Avatar
importのあるPythonはSwift for Tensorflowにしかないと思います。Swift for Tensorflowを入れるのが早そうな気が。 https://github.com/tensorflow/swift/blob/master/Installation.md
Swift for TensorFlow Project Home Page. Contribute to tensorflow/swift development by creating an account on GitHub.
3:38 AM
S4TF入れるなら、numpyの代わりにTensorで済むかも?目的によりますが&numpyを使いたいわけではないかもですが。 https://www.tensorflow.org/swift/api_docs/Structs/Tensor
Avatar
iOS13やiPad OSからサードパーティ製クッキー周りの仕様変更ってあったんでしょうか。。。 WKWebViewにユーザーのクッキーを使ってコンテンツ表示していて、このコンテンツの中にはiframeでサードパーティ製のコンテンツも表示しています。 このiframe内にも仕込んだクッキーをセットしてるはずなのですが、iOS13やiPad OSでのみクッキーがセットされていない状況です。 macos版Safariがサードパーティクッキーを制限したときと同種のものと思っているのですが、そういった情報を検索してもでてこないので、困っている状況です。
Avatar
(入れ違いすみません) @koher さん、コメントありがとうございます、普通の Swift ではまだ Python.import はできないんですね。
Avatar
すみません、Xcode をアップデートしたらstoryboardがおかしくなるエラーが解決できずどなたかにお助け願いたいのですが、ここで質問してもよろしいでしょうか? Xcodeチャンネルもしくはその手の質問受け付けてません!という感じでしたら教えてください🙇‍♂️😭
Avatar
多分最新のXcodeだと、急ぎでは殆どの方が触ってないので自分で解決するしかないです。
2:53 AM
情報が出揃うまでバージョンアップを避けるのも手ですね。
Avatar
Kishikawa Katsumi 7/23/2019 2:54 AM
チャンネルはどっちでもいいのでどんなエラーが出てるのかを共有してください。
Avatar
流れてしまう前に @takenoko ちゃんと調査した訳ではないのですが、macos版Safariで過去に同じことがあったのであれば、OSのアップデートと共にWKWebViewにパッチが当てられていると考えるのが自然だと思います。(だいたい1,2世代遅れで反映されるイメージ)
😫 1
Avatar
会話の途中に申し訳ありません🙇‍♂️ 私のググり力の無さで既に既出エラーでしたら誠に申し訳ありません!!! Xcode のエラーメッセージです。 file:///Users/otoyamisato/Mydictionary/MyDictionary/Base.lproj/Main.storyboard: error: IB Designables: Failed to render and update auto layout status for NewNoteViewController (iIJ-cw-XLr): Failed to launch designables agent. Check the console for a more detailed description and please file a bug report at bugreport.apple.com. (edited)
3:09 AM
Avatar
IBDesignableが壊れてますね
Avatar
そうなんですよね…😭
Avatar
iPhoneXs かつ iOS12.4のSimulatorが見つけられないと書いてるように見えるのですが
Avatar
それの見つけ方がいまいちよくわかりませんでした…💧 Simulator も iOS devices から変えられなかったです。
Avatar
Failed to find a suitable device for the type iPhoneXs with runtime iOS 12.4 と書いてあるので
3:18 AM
Simulatorが見つからない場合にどうするのかは検索したら出てくると思います
3:19 AM
だいたいこの手合いは、経験則では、再起動、OS再起動、Xcode再インストールの順番で試すと治ることが多いです。
😳 1
Avatar
Pc再起動で治りました!!!😭 すいません!ありがとうござます🙇‍♂️🙇‍♀️
Avatar
エラーメッセージは、出てきたものを全て上から下まで読みましょう
Avatar
はい、すみません🙇‍♀️ お手数おかけしました💦
Avatar
OSのアップデートと共にWKWebViewにパッチが当てられていると考えるのが自然だと思います。
そうなのですね。。。たるのんさん回答ありがとうございます。
Avatar
norio_nomura 7/23/2019 4:07 AM
サードパーティークッキーの変更はセッションで言及されてますね。これが該当するものかどうかわかりませんが。 https://developer.apple.com/videos/play/wwdc2018/234/?time=548 (edited)
Safari and WebKit are continually evolving with new features, APIs, and cutting edge web standards. Learn about this year's biggest...
4:07 AM
あ、これ2018だった…
4:12 AM
あとはSafari Technology Previewのリリースノートを見てみるとか。 https://developer.apple.com/safari/technology-preview/release-notes/
Avatar
ざっくりした質問ですみません、 allowsMultipleSelectionDuringEditingメソッドで、タップをしたらチェックマークがつくのって、どういう仕組みなのでしょうか? https://developer.apple.com/documentation/uikit/uitableview/1614944-allowsmultipleselectionduringedi (edited)
3:22 AM
詳細がわかるページ等ありましたら教えていただけると幸いです。
Avatar
Kishikawa Katsumi 7/24/2019 9:24 AM
そういう風にUIKitが実装しているから、、、という答えになると思うんですけど、 聞きたいことは、同じようなビューを自分で実装したいから仕組みを知りたい、ってことですか?
9:24 AM
要するに選択したらチェックマークがつくようものを作るにはどうしたらいいか?という質問でしょうか。
Avatar
@Kishikawa Katsumi 返信遅くなりました💦
11:58 PM
>要するに選択したらチェックマークがつくようものを作るにはどうしたらいいか?という質問でしょうか。
11:58 PM
はい!そうです!!
Avatar
度々申し訳ありません💦 一応、全選択をするのはfor in文でselectRowメソッドを使用して解決致しました。💦 💦
5:11 AM
UIKitが実装しているものと同様のものを自作するのは100万年くらい早いので、そういう時はいろんなメソッドを駆使してやっていこうと思いますorz
Avatar
Swift (& C++) 製のプログラムを高速に走らせたいので EC2 でやるのがいいかなと考えているのですが、他にオススメの方法や環境などはあるでしょうか? (edited)
Avatar
GCP で試してみることにしました 💪
12:08 PM
インストールめっちゃ簡単ですね,もっと色々難しいことやらないといけないのかと思ってた 😆
Avatar
バイナリ配布があるので対応OSのLinuxなら簡単ですねー
Avatar
ありがたや 🙏
Avatar
純 Swift の package は実行できたんですが,下の C++ と混合してるのを build しようとすると謎の文字列を吐いて死んでしまいます…🙄 原因のわかる方いらっしゃいますか? https://github.com/taketo1024/ClosedRegion/blob/master/Package.swift $ swift build --verbose lsb_release -r /home/taketo1024/swift-5.0.2-RELEASE-ubuntu18.04/usr/bin/swiftc --driver-mode=swift -L /home/taketo1024/swift-5.0.2-RELEASE-ubuntu18.04/usr/lib/swift/pm/4_2 -lPackageDescription -swift-version 5 -I /home/taketo1024/swift-5.0.2-RELEASE-ubuntu18.04/usr/lib/swift/pm/4_2 -sdk / /home/taketo1024/ClosedRegion/Package.swift -fileno 7 which clang /home/taketo1024/swift-5.0.2-RELEASE-ubuntu18.04/usr/bin/clang -target x86_64-unknown-linux --sysroot / -fPIC -g -O0 -DSWIFT_PACKAGE=1 -DDEBUG=1 -fblocks -fmodules -fmodule-name=LinBoxWrapper -I /home/taketo1024/ClosedRegion/Sources/LinBoxWrapper/include -fmodules-cache-path=/home/taketo1024/ClosedRegion/.build/x86_64-unknown-linux/debug/ModuleCache -framework Accelerate -MD -MT dependencies -MF /home/taketo1024/ClosedRegion/.build/x86_64-unknown-linux/debug/LinBoxWrapper.build/LinBoxWrapper.mm.d -c /home/taketo1024/ClosedRegion/Sources/LinBoxWrapper/LinBoxWrapper.mm -o /home/taketo1024/ClosedRegion/.build/x86_64-unknown-linux/debug/LinBoxWrapper.build/LinBoxWrapper.mm.o : .
Contribute to taketo1024/ClosedRegion development by creating an account on GitHub.
Avatar
あ,Swift 5.1 でビルドしてみたら fatal error: 'Foundation/Foundation.h' file not found #import <Foundation/Foundation.h> ^~~~~~~~~~~~~~~~~~~~~~~~~ と出ました。Obj-C をビルドするのに何かがいるのかな🙄
Avatar
sudo apt-get install gnustep gnustep-devel gobjc/usr/include/GNUstep/ 下に Foundation/ が入りましたが,これはどうやって SwiftPM で指定するのかしら🙄 (edited)
Avatar
Kishikawa Katsumi 8/20/2019 1:45 PM
とりあえず "-I", " /usr/include/GNUstep" をcxxSettingsに追加したらどうなります?
Avatar
ありがとうございます,今それをやってました!
1:52 PM
In file included from /home/taketo1024/ClosedRegion/Sources/LinBoxWrapper/LinBoxWrapper.mm:8: In file included from /home/taketo1024/ClosedRegion/Sources/LinBoxWrapper/include/LinBoxWrapper.h:8: In file included from /usr/include/GNUstep/Foundation/Foundation.h:30: /usr/include/GNUstep/GNUstepBase/GSVersionMacros.h:361:16: fatal error: 'objc/blocks_runtime.h' file not found # include <objc/blocks_runtime.h> ^~~~~~~~~~~~~~~~~~~~~~~ 1 error generated.
1:53 PM
objc/blocks がないと怒られてます 😅
Avatar
Kishikawa Katsumi 8/20/2019 1:54 PM
libDispatchかな
1:56 PM
^ GCDのライブラリ
Avatar
A tiny shell script for installing GNUstep and libobjc2 automatically on Ubuntu 12. I recommend that you download this script to a distinct folder &quot;gnustep-installer&quot;. It will dow...
1:57 PM
とりあえず libdispatch 入れてみます
1:58 PM
ダメでしたw
1:58 PM
上の sh をブチ込んでみます✊
Avatar
omochimetaru 8/20/2019 2:10 PM
そもそも、Linux向けのSwiftはObjective-C対応してないですよ
2:11 PM
Avatar
omochimetaru 8/20/2019 2:11 PM
GNUStepとかでがんばったとしても、
2:11 PM
少なくとも、Swift言語のObjective-C Interopが無いです。
Avatar
ぬぉー
Avatar
omochimetaru 8/20/2019 2:11 PM
そういうことかあ。
Avatar
じゃあ Linux では Swift と C++ バインドできない?
Avatar
omochimetaru 8/20/2019 2:11 PM
C言語使ってバインドするしかないです。
Avatar
😂😂😂
Avatar
Kishikawa Katsumi 8/20/2019 2:13 PM
C++ -> C -> SwiftだからObjCをちょっと書き直せば行けそう。
Avatar
omochimetaru 8/20/2019 2:15 PM
やったことはありますけどまあがんばればいけますね
2:15 PM
メソッド全部C言語の関数でexportし直す必要があるので単純に筋力が必要です
Avatar
.h を C オンリーにすればいいんです?
Avatar
omochimetaru 8/20/2019 2:15 PM
量によってはスクリプトで生成したほうが早い。
2:16 PM
えーっと
2:16 PM
関数とかのシンボルに関しては extern "C" { } で包むのと
2:16 PM
C++のclassやstructは使えないので、前方宣言して名前だけ渡す。
Avatar
ふむふむ
2:17 PM
量はそんなにないです,基本的には Swift との間で C-type の struct に変換して配列ポインタをガーッと渡してるだけなので。
2:18 PM
ちょっと Obj-C 風に書き直したりしてましたが,無駄でしたね😂
Avatar
omochimetaru 8/20/2019 2:18 PM
それなら手書きで必要なものだけブリッジするので行けそうですね
Avatar
よっしゃぁ…💪
Avatar
omochimetaru 8/20/2019 2:18 PM
😅
2:18 PM
なんか仕組みとしては
Avatar
Contribute to taketo1024/ClosedRegion development by creating an account on GitHub.
Contribute to taketo1024/ClosedRegion development by creating an account on GitHub.
Avatar
omochimetaru 8/20/2019 2:19 PM
hファイルっていうのはヘッダーなので、本体となるcファイルかcppファイルにincludeされるわけですけど
2:19 PM
cファイルにincludeされてるときはC言語としてコンパイルされてて
2:19 PM
cppファイルからincludeされてるときはC++言語としてコンパイルされてて
2:20 PM
で、C++だとABIが全部C++仕様になっちゃうんだけど、 C言語と互換性のある状態にするために使うのが extern "C" { } です
2:20 PM
ただそこでややこしいのが、 extern "C" { } は C++の中で使うC言語対応させる文法なので
Avatar
ほほー
Avatar
omochimetaru 8/20/2019 2:21 PM
C言語自体にはextern C という文法が存在しないから、そのヘッダーをCから読めない。
2:21 PM
そこでどうするかっていうと
2:21 PM
C++のときは extern "C" になって、Cのときは無になるマクロを作る、っていうのをみんなやってます。
Avatar
https://stackoverflow.com/a/12994075/1249157 ここに書かれてることですかね
What exactly does putting extern "C" into C++ code do? For example: extern "C" { void foo(); }
Avatar
omochimetaru 8/20/2019 2:23 PM
まさにこれっぽい。
Avatar
おぉ-…
2:23 PM
#ifdef __cplusplus extern "C" { #endif // ここに Swift に expose する struct や関数を書く #ifdef __cplusplus } #endif
2:23 PM
って感じで合ってますかしら?
Avatar
omochimetaru 8/20/2019 2:24 PM
そうですね。
Avatar
ありがとうございます,やってみます!
2:24 PM
こんなの絶対一人じゃわからなかったw
2:27 PM
C++のclassやstructは使えないので、前方宣言して名前だけ渡す。
これが分からなかったのですが,これはどういうときに必要になるものですか?
2:27 PM
前方宣言すれば C++ の class や struct を Swift から使える?
Avatar
omochimetaru 8/20/2019 2:34 PM
名前だけ使えるようになります
2:35 PM
OpaquePointerとかUnsafePointer<Hoge>とか。 (edited)
2:36 PM
あとstructだったらメソッドがなければそのままSwiftから使えますね。
Avatar
名前だけ使えるというのはどういうことです…?
2:38 PM
Hoge は C++ の struct ?
2:40 PM
hoge.h #ifdef __cplusplus extern "C" { #endif void hehe(); #ifdef __cplusplus } #endif hoge.cpp #include "hoge.h" void hehe() { std::cout << "hehe" << std::endl; } これが動いたのであとは頑張れば行けそうです💪 (edited)
Avatar
omochimetaru 8/20/2019 2:40 PM
名前だけってのはポインタとかは使えるけどそれ自体は使えないって事です
2:41 PM
Hogeはcppのクラスか構造体。
Avatar
ふーむ…それができて嬉しいケースってあるんですか?
2:41 PM
Swift が C++ から受け取って,それをまた C++ に渡す場合とか?
Avatar
omochimetaru 8/20/2019 2:42 PM
Hogeのポインタを受け取る関数に対して、 間違ってFugaのポインタを渡すと型チェックでエラー検知できます
Avatar
なるほどっ
2:43 PM
例えば C++ から Swift へ smart pointer を渡すみたいなこともできる…?
2:43 PM
swift では直接それに触れず,また別の関数に回すだけ
Avatar
omochimetaru 8/20/2019 2:44 PM
そうそう、回すだけ。
2:44 PM
でもstd::shared_ptrとかは、それ自体がcppの型だから、swiftから受け渡しできません。
2:45 PM
shared_ptrのポインタ、なら扱えます。ややこしいのでやめた方がいいですが。
Avatar
なるほどw
2:46 PM
とりあえずは生 C 丸出しな感じで,大量の引数つきグローバル関数をたくさん生やそうと思います!
2:47 PM
色々と教えて頂きありがとうございました 🙇
Avatar
omochimetaru 8/20/2019 2:51 PM
🤚
Avatar
bool solve(size_t rows, size_t cols, const LBMatrixComponent *Acomps, size_t Acomps_cnt, const LBMatrixComponent *bcomps, size_t bcomps_cnt, LBMatrixComponent *xcomps, size_t *xcomps_cnt); 生々 C
Avatar
omochimetaru 8/20/2019 3:00 PM
あるある
swift 1
Avatar
Cでも_Nullable, _Nonnullとか使えるので、その辺りをちゃんと使うとSwift側でのポインタの扱いを簡単に出来たりします。
Avatar
まさにそれを今やろうとしてました! const Hoge *const *xcomps が Swift では UnsafePointer<UnsafePointer<Hoge>?>! となるようで、この内側の ? を取りたくて const Hoge *const _Nonnull *xcomps としたら求める形にできたのですが,Pointer is missing a nullability type specifier という警告がたくさん出てしまいました。 NS_ASSUME_NONNULL_BEGIN ... END で囲めば消せるようなのですが、これを使うには Foundation を import する必要があるらしいんですが、それ以外の方法はあるでしょうか?(Linux で動かしたいので Foundation free にしたい)
1:09 AM
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnullability-completeness" ... #pragma clang diagnostic pop これで行けました👍 (このやり方で大丈夫でしょうか?) (edited)
Avatar
omochimetaru 8/21/2019 1:09 AM
LinuxでもFoundationは使えますよ。
1:11 AM
Nullableは一つつけたら全部つけることを求められる仕様で(君この機能知ってるね?的な)、警告はプラグマで消すのもいいですが、全部つける方が望ましいです
1:12 AM
include先のヘッダーとかにはつけられないですが、 そういうライブラリはcpp側でincludeするようにするとか工夫して、 余計なものを露出しないヘッダーが作れます。
1:13 AM
Linux用のFoundationはObjCを使わずに書かれてるのです。
Avatar
norio_nomura 8/21/2019 1:13 AM
CoreFoundationはこんな感じですね。 #if __has_feature(assume_nonnull) #define CF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #define CF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") #else #define CF_ASSUME_NONNULL_BEGIN #define CF_ASSUME_NONNULL_END #endif
Avatar
うーむ,なるほど… この警告のためだけに Foundation を入れなきゃいけないのはちょっと抵抗が…🙄
Avatar
norio_nomura 8/21/2019 1:18 AM
CoreFoundationに倣って、ASSUME_NONNULL_BEGINとかを自前で定義してしまえば良いのでは。 (edited)
Avatar
#ifndef で同じものを定義する感じですかね
Avatar
omochimetaru 8/21/2019 1:32 AM
定義するのは#defineですね。
Avatar
あ、すみません、 #if __has_feature(assume_nonnull) #ifndef NS_ASSUME_NONNULL_BEGIN #define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #endif #endif こういう感じにするのかなと思ってました(将来的に衝突が起きると面倒なので) (edited)
Avatar
omochimetaru 8/21/2019 1:36 AM
ああそういう意味ですか、NS_はFoundation用のprefixなので、NS_をつけないのが望ましいですね。
1:36 AM
代わりにライブラリ固有のprefixをつけるのがベストです。他の関数名とかと同じようにしましょう。
Avatar
あ,なるほど,そういうことか!
1:37 AM
自前で同じ _Pragma を定義すればいいってことですね. (edited)
Avatar
omochimetaru 8/21/2019 1:37 AM
_Pragmaは単に #pragma に展開されるマクロだと思うので、
1:37 AM
_Pragmaを定義する必要は無いですね
Avatar
ありゃw
Avatar
omochimetaru 8/21/2019 1:37 AM
まあ、ClangとGCCの両方に対応したいなら定義しても良いですが。
Avatar
#if __has_feature(assume_nonnull) #define SANO_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #define SANO_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") #endif SANO_ASSUME_NONNULL_BEGIN bool solve(..., const LBMatrixComponent *const _Nonnull *xcomps, ...); SANO_ASSUME_NONNULL_END (edited)
Avatar
omochimetaru 8/21/2019 1:38 AM
個人的にはSwiftから使う時点で __has_feature(assume_nonnull) も絶対YESなのでいらないきがしますが
Avatar
↑ こうであってます?
Avatar
omochimetaru 8/21/2019 1:41 AM
#if __has_feature(assume_nonnull) #define SANO_ASSUME_NONNULL_BEGIN #pragma clang assume_nonnull begin #define SANO_ASSUME_NONNULL_END #pragma clang assume_nonnull end #endif SANO_ASSUME_NONNULL_BEGIN bool solve(..., const LBMatrixComponent *const _Nonnull *xcomps, ...); SANO_ASSUME_NONNULL_END (edited)
1:41 AM
こうだけど
Avatar
ほうほう,なるほど
Avatar
omochimetaru 8/21/2019 1:41 AM
#define SANO_ASSUME_NONNULL_BEGIN #pragma clang assume_nonnull begin #define SANO_ASSUME_NONNULL_END #pragma clang assume_nonnull end SANO_ASSUME_NONNULL_BEGIN bool solve(..., const LBMatrixComponent *const _Nonnull *xcomps, ...); SANO_ASSUME_NONNULL_END これでいいと思います。
Avatar
ふむふむ。
Avatar
omochimetaru 8/21/2019 1:41 AM
ここまでやるとマクロ定義してる意味もよくわからないから#pragma直接書けばいい気もする
Avatar
将来的に Swift と切り離して使う可能性も意識するなら __has_feature もつけといた方がいいって感じですかね。
1:42 AM
理解しました > pragma
Avatar
omochimetaru 8/21/2019 1:43 AM
そうですね。 assume_nonnull機能をもたないコンパイラにも対応したいならhas_featureが必要で
1:43 AM
clangじゃないコンパイラにも対応したいなら _Pragmaが必要ですね
1:43 AM
いずれにしても対応していないコンパイラだったら無にしたいってことです
Avatar
ほほー
Avatar
omochimetaru 8/21/2019 1:43 AM
clangじゃないコンパイラというとgccとかMSVC++とか。
Avatar
_Pragma は他のコンパイラでも定義されてるんですか?
Avatar
omochimetaru 8/21/2019 1:44 AM
ちゃいます
Avatar
それも #ifndef で定義する?
Avatar
omochimetaru 8/21/2019 1:44 AM
#ifdef __CLANG__ #define _Pragma(x) #pragma x #else #define _Pragma(x) #endif
Avatar
はぁはぁ,なるほど。
Avatar
omochimetaru 8/21/2019 1:44 AM
↑こういうイメージです(__CLANG__は今適当に書いた) (edited)
Avatar
理解しました!
Avatar
omochimetaru 8/21/2019 1:46 AM
でもそういえば #pragma onceはgccでもvcでも使えるな。 #pragma clang assume_nonnull beginは使えないと思いますけど(clangって入ってるし・・・)
Avatar
norio_nomura 8/21/2019 1:46 AM
_Pragmaを使わない#defineは利用時にエラーになるよ。 … .h:17:1: error: expected unqualified-id SB_ASSUME_NONNULL_BEGIN ^ … .h:6:33: note: expanded from macro 'SB_ASSUME_NONNULL_BEGIN' #define SB_ASSUME_NONNULL_BEGIN #pragma clang assume_nonnull begin ^ (edited)
Avatar
omochimetaru 8/21/2019 1:46 AM
ほう
1:48 AM
普通のマクロじゃなくて専用の言語機能だったのか・・・
1:48 AM
さっきの説明は間違ってました、すいません。
Avatar
おぉ,ありがとうございます。
1:51 AM
#pragma を #define に入れちゃいけない的な制約があるんです?
Avatar
omochimetaru 8/21/2019 1:52 AM
そうみたいですね。
Avatar
norio_nomura 8/21/2019 1:52 AM
定義だけなら問題なかったです。
1:53 AM
ああ、エラーをちゃんと引用してなかった。 (edited)
Avatar
結局こういう感じになりました: bool solve(..., LBVectorComponent **xcomps, size_t *xcomps_cnt); var xcomps_ptr: UnsafeMutablePointer<LBVectorComponent>? = nil var xcomps_c = 0 if LinBoxWrapper.solve(..., &xcomps_ptr, &xcomps_c) { guard let xcomps_ptr = xcomps_ptr else { fatalError() } let buff = UnsafeBufferPointer(start: xcomps_ptr, count: xcomps_c) defer { xcomps_ptr.deallocate() } return DVector(size: size.cols, components: buff) } else { ... (edited)
2:03 AM
呼び出し側から dealloc を呼ばないといけないので Mutable じゃなきゃいけなくて,はじめに nil を入れた状態で渡したいので _Nonnull にもできなそうでした。
Avatar
omochimetaru 8/21/2019 2:03 AM
xcomps_ptrの型は UnsafeMutablePointer<LBVectorComponent>?にしたほうが良いのでは
Avatar
_Nullable を明示してってことです?
Avatar
omochimetaru 8/21/2019 2:05 AM
むむ、その2つは独立な話ですね
Avatar
あれれ、
Avatar
omochimetaru 8/21/2019 2:05 AM
nullabilityの指定がC側でされていなかったとしても、Swift側は?を使いたい、!型は避けたい。
2:05 AM
それとは別に、C側で _Nullableは明示したい。
Avatar
あ,そっか,Swift 側で ! に暗黙キャストしちゃってたのか.
2:08 AM
Swift の方を直しました!
🙂 1
2:08 AM
少しコツが分かってきました😆
Avatar
C で並列処理をするための OpenMP というライブラリがあるようで、clang でビルドするときは clang -Xpreprocessor -fopenmp -lomp myfile.c という風にオプションをつけるとできるそうなのですが,swift build や Xcode からのビルドでこのオプションを設定するのはどうやったらいいか分かりますか?
Avatar
omochimetaru 8/21/2019 2:31 PM
-lompのところはlibompのリンク指定ですね
Avatar
はい,そちらは library search path への指定で行けました.
Avatar
omochimetaru 8/21/2019 2:32 PM
Xpreprocessorでプリプロセッサにfopenmpを渡してるところは、Xccでいけるかなあ?
2:32 PM
-Xcc -Xpreprocessor -Xcc -fopenmp
Avatar
swift build -Xcc -Xpreprocessor -Xcc -fopenmp これは通ってるっぽいです(°_°)
2:35 PM
swift build で -lomp 指定するのはどうしたらいいんでしょう?
Avatar
omochimetaru 8/21/2019 2:35 PM
-Xlinker -lomp
Avatar
おぉ
2:38 PM
ld: library not found for -lomp って言われてしまいます… export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/usr/local/lib してみたんですがダメでした。 (edited)
2:41 PM
swift run -Xcc -Xpreprocessor -Xcc -fopenmp -Xlinker -L/usr/local/lib -Xlinker -lomp これで実行はできました!…が並列処理は効いてなさそう🤔
Avatar
omochimetaru 8/21/2019 2:42 PM
-dか-vかなんかをつけるとswiftpmの内部のビルドコマンドが表示されるので
2:42 PM
それでC言語のコンパイルのところが望んだコマンドになっているかを確認する
2:43 PM
のが次のステップですかね、、
Avatar
/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -fobjc-arc -target x86_64-apple-macosx10.10 -isysroot /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -F /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -g -O0 -DSWIFT_PACKAGE=1 -DDEBUG=1 -fblocks -index-store-path /Users/taketo/Projects/spasm/.build/x86_64-apple-macosx/debug/index/store -fmodules -fmodule-name=spasm -I /Users/taketo/Projects/spasm/src/include -fmodules-cache-path=/Users/taketo/Projects/spasm/.build/x86_64-apple-macosx/debug/ModuleCache -Xpreprocessor -fopenmp -MD -MT dependencies -MF /Users/taketo/Projects/spasm/.build/x86_64-apple-macosx/debug/spasm.build/spasm_util.c.d -c /Users/taketo/Projects/spasm/src/spasm_util.c -o /Users/taketo/Projects/spasm/.build/x86_64-apple-macosx/debug/spasm.build/spasm_util.c.o ちゃんと -Xpreprocessor -fopenmp は入ってそう (edited)
Avatar
omochimetaru 8/21/2019 2:47 PM
中身はopenmpを使ってかいてるんですか-
2:47 PM
Avatar
はい
2:47 PM
試しに無理やり入れてみました.
2:47 PM
#pragma omp for for(int n=0; n<1000; ++n) { printf(" %d", n); } printf(".\n"); ↑ この謎の pragma を入れるだけで並列処理になるというw
2:48 PM
実行結果がバラバラなら効いてるはずなんですが,綺麗に 0 から順番に出てしまうんですよね.
Avatar
omochimetaru 8/21/2019 2:49 PM
なるほど。そのコードは-fopenmpを渡さない場合は正しくコンパイルエラーになるんですか? (edited)
Avatar
渡さないと直列になるんだと思います。
Avatar
omochimetaru 8/21/2019 2:51 PM
それだと
2:51 PM
コンパイラがそのオプションに反応したのかどうかすら
2:51 PM
コンパイル時に確認できないので厄介ですね
Avatar
そうなんですよねw
Avatar
omochimetaru 8/21/2019 2:51 PM
うーむ。
Avatar
あっ,できてるっぽいです
Avatar
omochimetaru 8/21/2019 2:58 PM
並列な結果が出ました?
Avatar
export OMP_NUM_THREADS=100 これを叩いてから実行したら, 1 65 49 33 13 4 17 77 97 3 9 81 5 73 68 2 69 67 66 45 61 57 41 53 52 37 51 29 36 50 35 21 25 19 20 18 34 6 16 84 46 48 63 59 60 58 56 55 44 54 43 42 40 39 32 38 31 30 28 27 26 24 23 22 15 14 98 99 11 12 8 93 89 10 7 85 80 82 83 76 78 79 75 74 71 72 70 62 64 47 96 95 94 92 90 88 91 87 86 と出ました😂
Avatar
omochimetaru 8/21/2019 2:59 PM
おお。
Avatar
めちゃめちゃデバッグしづらそうw
Avatar
omochimetaru 8/21/2019 2:59 PM
外から与えるのか。
2:59 PM
並列数。
Avatar
ウケますね
Avatar
omochimetaru 8/21/2019 3:00 PM
完全に元のforループとは異なる何かになっててウケる
😂 1
Avatar
というかもはや Swift の話じゃないですね,すみません 🙇
Avatar
omochimetaru 8/21/2019 3:00 PM
other-langチャンネルもありますよ
👌 1
Avatar
Xcode の方は Other C Flags で -Xpreprocessor -fopenmp と指定すればいけました👍
Avatar
上の話ですが、Swift PM にこう指定するだけで行けました(もうこの話は終わりにします) .target( name: "...", cSettings: [ .unsafeFlags(["-Xpreprocessor", "-fopenmp"]) ], linkerSettings: [ .unsafeFlags(["-L/usr/local/lib"]), .linkedLibrary("omp") ] ), (edited)
Avatar
あー、そっか、その方が便利ですね
Avatar
自作の command line ツールを走らせていて realloc failed: Cannot allocate memory と最後の言葉を残して終了したのですが、こういうメモリエラーをキャッチする方法ってあるんでしょうか? (アプリなら didReceiveMemoryWarning 系のものがあるけど)そもそも RuntimeException 的な仕組みがないのでどう対処したものかと🙄
Avatar
Kishikawa Katsumi 8/29/2019 6:52 AM
reallocが死ぬのは起こってしまったら基本的にどうしようもないですね。起こらないようにするというのが対策ですけど、実際めっちゃメモリを必要とする感じですか?それともリークとかがありそうですか?
Avatar
めっちゃ必要な感じです、対策の余地はまだまだあると思いますが。 Leak は instrument で調べてみましたが起きてなさそうです。
6:53 AM
memory 7GB の VM で走らせてるので、まずこれを増やそうとは思います。
6:54 AM
どこで死んだかだけでも知れたらいいなと思ったんですが,キャッチはできないんですかね。
Avatar
Kishikawa Katsumi 8/29/2019 7:26 AM
bad_allocとかが飛んでたら catch (...) { <= この ... は文字どおり ... です、とかで捕まえられるかも。 それかreallocを入れ替えるとか。
Avatar
realloc 入れ替えるのはビビりますw 了解です,ありがとうございます🙏
7:45 AM
Xcode の allocations って具体的にどの class / struct が容量を消費してるかまでは可視化できないですよね。
Avatar
Kishikawa Katsumi 8/29/2019 7:52 AM
C++に使ったことないですけどわかるんじゃないですかね。。。?
Avatar
omochimetaru 8/29/2019 8:03 AM
具体的にどの class / struct が容量を消費してるか
出ますよ
Avatar
ありゃっ?
Avatar
omochimetaru 8/29/2019 9:27 AM
インスタンスの数とかも出るので
9:28 AM
それで絞り込んだりをよくします
9:28 AM
どこで死んだか
9:29 AM
メモリ確保失敗したときはシグナルが飛んでるのでスタックトレースが得られてるはずです
9:29 AM
普通にやるとstderrに出てるんじゃないか・・・?
9:29 AM
Linuxだとシンボル名が出なくて関数アドレスが16進数で出るだけだったりしますが、
9:30 AM
そういうときは野村さんのライブラリで表示できたりするかも。DiscordのSwift botがまさにそれをやっている
Avatar
norio_nomura 8/29/2019 9:47 AM
DiscordのSwift botがまさにそれをやっている
あ、ボットには自動でSwiftBacktraceを有効にする仕組みは入れていません。ボットのスタックとレースは/usr/bin/swiftが請け負ってくれているので。
(edited)
9:49 AM
import SwiftBacktraceを出来るようにはしてありますが。 (edited)
Avatar
omochimetaru 8/29/2019 9:50 AM
ありゃ
9:51 AM
あ、C関数の中のクラッシュだとswift runtimeじゃないから出ないのかな・・・?
9:51 AM
コアダンプをどうこうするやつか
Avatar
norio_nomura 8/29/2019 9:55 AM
Linuxの場合は、実行ファイルが自前でスタックトレースを出力、プロセスが死んでからcoreを使ってスタックトレースを出力、lldb下で実行して出力、が取れる選択肢かな。
9:59 AM
dockerとかでcore出力を制限されていたりlldbを使えなかったりする場合は実行ファイルが自前で出力するしかないので、SwiftBacktraceを作りました。
Avatar
omochimetaru 8/29/2019 9:59 AM
あーなるほど、コアが出せない状況というのがあるんですね
Avatar
そう、ボットはHerokuで動いていますがcore出力もlldbも使えません。そのため、ボットが受け取ったコードの実行には使っていませんが、ボット自身のクラッシュを解析する用途としてはSwiftBacktraceを使っています。
10:13 AM
SSWGでも話題になったから、もう少し選択肢は増えてたはず。 https://forums.swift.org/t/crash-backtraces/25021
When we were discussing the Charter of the SSWG last year, one area several people mentioned they were interested in collaborating on is improving the experience of deploying Swift applications and managing them at scale. A critical part of that is ensuring that Swift has a ...
10:15 AM
僕のも含めいくつかのスタックトレース用ライブラリを評価した上で、IanPartridgeさんが新しいのを作ってたと記憶。
Avatar
おお
Avatar
いつもすみません。picker がXR以外、画面サイズに合うように表示されず原因もわからないのでどなたかご教示いただけないでしょうか?💦
10:35 AM
見辛いかもしれませんが、詳細は以下のリンクにあります🙏
10:35 AM
やりたいことiOS XR 以外の機種でも、pickerが画面に収まるように表示させたい。 現状RxSwift で書いており、基本的に storyboard を使用しています。picker は呼び出されてはいるのですが、XR以外の機種だと画
Avatar
pickerの横幅の制約が正しくない気がします。 このpickerはStoryboard上で実装していますか?codeで実装していますか? pickerにつけている制約はどういったものになっていますか? (edited)
11:13 AM
あぁ…これが原因な気が…widthの制約がついていないので、Storyboardで表示されている仮想端末が基準のサイズで初期化されるため、iPhone XRの横幅でpickerが作られて見切れているかと
autolayout での制約は、上下左右につけています。heightの制約はつけていますがwidthの制約はつけていません。
Avatar
ありぜさん、ありがとうございます!widthの制約をつけてしまうと、多画面での対応ができないのかな、と思ってつけなかったのですがいじってみます!!🙏
👍 1
Avatar
width弄ってみましたが、なりませんでした。
🙇 1
11:33 AM
左右を"="ではなく”不等号”にもしてみましたが、変化なしです...😢
Avatar
あっ画像見るとpickerの問題じゃなく、その下のUIView側の制約の問題でした…(doneボタンとかツールバーもはみ出してるの見落としてました) pickerの乗っているxibは、どうやって読みだしていますか? Storyboardの上にUIViewを配置してCustom Viewとしてですか? それともコードでxibをUIViewとして読み出し、addSubViewしている感じですか? (edited)
11:37 AM
<呼び出しているuiviewについて> autolayoutでの制約は、下・左右とheightにつけています。
これが機能していれば正しく表示されそうなんですが…制約が衝突して正しくない状態になっている??
Avatar
pickerの乗っているxibは、どうやって読みだしていますか? コードでxibをUIViewとして読み出し、addSubViewしている感じ
です!
11:40 AM
制約が衝突して正しくない状態になっている??
その可能性はあるかもしれません。 呼び出し先のUIView自体の制約の衝突はなさそうなのですが、ほかのものと衝突しているかもです!もう一度みてみます!ありがとうございます!!
Avatar
現時点で考えられる原因は…以下あたりかと 1. pickerの乗っているUIViewに対して制約のコードを記述し忘れている 2. pickerの乗っているUIViewに対して制約コードを記述している位置が悪く実行されるタイミングに問題がある 3. 前述した制約の衝突 (edited)
Avatar
xibのpickerの制約と呼び出し先のuiviewの制約が衝突しているのでしょうか? 呼び出し先の画面の制約はみた感じ衝突してないかなと思ったのですが... こちら、呼び出し先の制約です
11:44 AM
現時点で考えられる原因は…以下あたりかと
1. pickerの乗っているUIViewに対して制約のコードを記述し忘れている 2. pickerの乗っているUIViewに対して制約コードを記述している位置が悪く実行されるタイミングに問題がある 3. 前述した制約の衝突 なるほど...
11:45 AM
みてみます😭 ありがとうございます!!!
Avatar
やっと解決いたしました_:(´ཀ`」 ∠): autoresizing の制約の付け忘れでした。 お手数おかけいたしました🙇‍♂️
Avatar
コンパイル時に特定のファイルだけ optimazation を無効にすることってできるんでしょうか?
Avatar
Kishikawa Katsumi 9/10/2019 11:26 PM
Swiftはたぶん無理ですね。ファイルごとのCompiler Flagsをセットしても無視されてしまうし。。。
11:26 PM
Xcodeで、ってことですよね?他の方法もありですか?
Avatar
Swift PM を使ったビルドならアリです.
6:59 AM
あるいは特定の target 下だけ optimization を無効にする,でもいいです.
Avatar
Kishikawa Katsumi 9/11/2019 7:00 AM
ターゲットを分けられるならターゲットを分けるのがわかりやすいですね。
7:01 AM
Xcodeプロジェクトならビルド設定でコントロール可能、SPMは調べないとわからないですね。
Avatar
ふむふむ
7:14 AM
#other-lang に書いた C ライブラリとの連携で,別ターゲットとして埋め込んで使っているので,その部分だけ最適化をオフにすると正常に動作するようになるかなと思いまして🙄
7:19 AM
また別の質問なんですが,DispatchWorkItem って cancel 呼んでも止められる訳ではないんですね.「一つの処理に時間がかかりすぎてる場合に停止する(メモリとかも解放する)」って,プロセスそのものを分けないと無理なんでしょうか? let semaphore = DispatchSemaphore(value: 0) let mainTask = DispatchWorkItem { while true { print("working...") sleep(1) } } let bgTask = DispatchWorkItem { for i in 0 ..< 3 { print(i) sleep(1) } semaphore.signal() } DispatchQueue.global(qos: .userInitiated).async(execute: mainTask) DispatchQueue.global(qos: .background).async(execute: bgTask) semaphore.wait() mainTask.cancel() bgTask.cancel() print("canceled") sleep(10) // まだ working... が出続ける
7:21 AM
上の例なら mainTask の while 時に !isCancelled としたりできますが,僕が扱いたいのはここがループではなくてとても重くなる可能性のある長い処理です.
Avatar
Kishikawa Katsumi 9/11/2019 7:21 AM
すでに実行されてしまったのはそうですね。 isCancelled みたいなプロパティがあるのでそれを見て自分でキャンセルします。
Avatar
うーむ,なるほど.
Avatar
Kishikawa Katsumi 9/11/2019 7:23 AM
長い処理の間を適当に分けて、 if isCanceled { // cleanup etc. return } // 処理A if isCanceled { // cleanup etc. return } // 処理B ...
7:23 AM
^ のような感じですね。
7:24 AM
考え方でいうと。
Avatar
了解です!
7:25 AM
mainTask の中身は切り出しやすいものなので,上のようにしたければ subprocess として立ち上げる感じがよさそうですね.
Avatar
Kishikawa Katsumi 9/11/2019 7:27 AM
プロセスまで作るのはやりすぎかもしれないので、取りあえず関数やらオブジェクトくらいに分けて、前のタスクが正常に終わっていたら次、みたいなのでいいんじゃないですかね。
Avatar
ライブラリで走ってる異常にデカイ行列の処理を途中で止めるようなことをしたいので,サブプロセスを切ってしまった方が楽そうですw
7:30 AM
計算対象がたくさんあってそれらを順番に計算していきながら,時間がかかりすぎていたりメモリを食い過ぎていたりしたら中断する,というようなことをやろうとしています.
Avatar
CLI ツールが out of memory で勝手に落ちてしまうのが困るので(ログを残して正常に終了したい),iOS の memory warning のような仕組みを作りたいと思っています.メモリ情報を監視するスレッドを立てて,↓ の方法でメモリ情報を 1 秒おきとかで取得し続けるのがいいかなと思っているのですが,もっといい方法はあるでしょうか?(あと mach は linux では動かないですよね?) https://stackoverflow.com/a/30435804
I need to get Memory usage information like(available RAM, available internal storage).
Avatar
This article provides cross-platform functions to get the peak (maximum) and current resident set size of a process, and explains what works on what OS.
Avatar
上のライブラリを使って,こういう感じに実装することにしました: let semaphore = DispatchSemaphore(value: 0) var exceedMemory = false DispatchQueue.global(qos: .userInitiated).async { main() semaphore.signal() } DispatchQueue.global(qos: .background).async { while true { let mem = getCurrentRSS() if mem > self.config.maxMemory { exceedMemory = true semaphore.signal() } sleep(10) } } if semaphore.wait(timeout: .now() + timeout) == .timedOut { throw AppError.timeout(sec: config.timeout) } if exceedMemory { throw AppError.exceedMemory(limit: config.maxMemoryGB) }
Avatar
色々な型を Global に ExpressibleByIntegerLiteral 適合させると予期できない暗黙キャストが起きてカオスになるので、特定の型を fileprivate に ExpressibleByIntegerLiteral に適合できたらいいと思ったのですが、 conditional conformance があると fileprivate extension できないんですね… これは何故なのでしょう🙄 特に ExpressibleByIntegerLiteral な型を wrap する型を再び ExpressibleByIntegerLiteral にして、init では内部の型に丸投げする多くて,↓ こういう protocol を作って必要に応じて適合させられたらいいと思ったのですが…🙄 public protocol InheritingIntegerLiteralExpression: ExpressibleByIntegerLiteral where IntegerLiteralType == Inheritee.IntegerLiteralType { associatedtype Inheritee: ExpressibleByIntegerLiteral init(_ inheritee: Inheritee) } extension InheritingIntegerLiteralExpression { public init(integerLiteral value: IntegerLiteralType) { self.init(Inheritee(integerLiteral: value)) } } (edited)
1:45 PM
使うときは fileprivate extension Polynomial: ExpressibleByIntegerLiteral, InheritingIntegerLiteralExpression where BaseRing: ExpressibleByIntegerLiteral { typealias Inheritee = BaseRing } とするイメージ. (edited)
1:48 PM
conditional conformance つきだと extension にアクセス修飾子がつけられないのは前向きな理由があるんでしょうか? (edited)
Avatar
(Inherit というより Delegate の方が適切な気がしてきました)
Avatar
昔できたらいいのにな~と議論した記憶があるのですが、確か可能だと破綻するよね、という話題になった記憶があります。
2:15 PM
// ファイル A public func something<T: SomeProtocol>(_ value: T) { ... } // ファイルB private extension Foo: SomeProtocol { ... } something(Foo()) 最も単純な例はこれですかね、somethingの実装側からはFooのSomeProtocolに対する実装は見えていないはずなので、実行できなくなりそうです。(できると可視性がおかしなことになってくる)
Avatar
はー,なるほど.よくわかりました 🙇
Avatar
Xcode11のSwiftPMについて質問なのですが、SwiftPMでSwiftLintを導入して、Build Phaseでlintを実行するのは可能でしょうか? 現状は下記のような感じでCocoaPodsを使ってSwiftlintを入れているのですが、このためだけにCPを使うのがいやだなーと思って、SwiftPMを使いたいと思っています。 "${PODS_ROOT}/SwiftLint/swiftlint"
Avatar
Kishikawa Katsumi 10/2/2019 10:14 AM
Xcode 11のSwiftPMだと無理だと思います。CocoaPodsを使いたくないならHomebrewかMintを使っていれる、じゃないでしょうか。
Avatar
なるほど、そうなんですね。とはいえ、チームで共有したかったので、今の所はCPを使うのが一番目的には合ってそうです。 ありがとうございます!
Avatar
Thread safe な dictionary を作ろうとしているのですが,dead lock になってしまうようです.何がまずいかわかりますか? public class SynchronizedDictionary<Key: Hashable, Value> { private var dictionary: [Key: Value] = [:] private let queue = DispatchQueue(label: "hoge", qos: .default, attributes: .concurrent) public subscript(_ key: Key) -> Value? { get { queue.sync { dictionary[key] } } set { queue.async(flags: .barrier) { self.dictionary[key] = newValue } } } } var a = SynchronizedDictionary<Int, Int>() let n = 100000 DispatchQueue.concurrentPerform(iterations: n) { i in a[i] = i } print(a[n-1]) write のところは sync ではなく async(flags: .barrier) とした方が良いという記事をいくつか見てそうしてます.
Avatar
Kishikawa Katsumi 10/7/2019 2:08 PM
キューを concurrent にしたらダメじゃないですか?
Avatar
https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2 concurrent にした上で write を async(flags: .barrier) にすると write で sync を待たなくて済むのでより良い,というようなことが書かれてたもので🙄 正しく理解できてないのかもです.
Learn all about multithreading, dispatch queues, and concurrency in the first part of this Swift 4 tutorial on Grand Central Dispatch.
2:11 PM

経緯

普段使っているのに全体像があまり見えていないものとして Grand Central Dispatch (GCD)とOperationQueueが 自分の中にあり色々と調べてみました。 調べていけばいくほど新しいことがど...
Avatar
Kishikawa Katsumi 10/7/2019 2:12 PM
write/write が待つのはしょうがないけどread/writeとかread/readは待ちたくないと、そういう要件なんですね。
Avatar
write 処理は同期されるけど,write 呼び出しはすぐ抜けられる,という感じなのかと理解してます.
2:13 PM
deadlock なんじゃなくて単純に処理にめっちゃ時間かかってるのかも…🙄
2:15 PM
しばらく待ったら出力されました.そして両方 sync するように書き直したら一瞬で終わりましたw public class SynchronizedDictionary<Key: Hashable, Value> { private var dictionary: [Key: Value] = [:] private let queue = DispatchQueue(label: "shit", qos: .default) public subscript(_ key: Key) -> Value? { get { queue.sync { dictionary[key] } } set { queue.sync { self.dictionary[key] = newValue } } } } var a = SynchronizedDictionary<Int, Int>() let n = 100000 DispatchQueue.concurrentPerform(iterations: n) { i in a[i] = i } (edited)
2:16 PM
書き込みにそれなりに時間かかるようなケースじゃないとむしろオーバーヘッドになるってことなのかな…🙄 (edited)
Avatar
Kishikawa Katsumi 10/7/2019 2:18 PM
動かしてみました。これはデッドロックですね。
Avatar
うーむ…なんでデッドロックしちゃうんでしょう?
2:22 PM
ここにもほぼ同様のコードがあります: https://medium.com/@oyalhi/dispatch-barriers-in-swift-3-6c4a295215d6
Dispatch barriers can be used to speed serial queues for read write operations.
Avatar
Kishikawa Katsumi 10/7/2019 2:29 PM
.async(flags: .barrier) が良くわかってないんですよね。。。
2:30 PM
最初のコードでも a[i] = i print(a[i]) のようにgetが呼ばれるコードを後に足すと終了すると思います。
Avatar
そうなんですよね.print によるラグでうまいことデッドロックをすり抜けてるのかなと思いましたw
Avatar
並列処理の達人の方がいたら是非教えてください🙏
Avatar
omochimetaru 10/8/2019 2:08 AM
1つ目のコードについては
2:09 AM
concurrentキューなので
2:09 AM
投入されるタスク同士は並行に動いちゃいます
2:10 AM
Dictionaryに対する並行アクセスが、readだけでも並行アクセスしても大丈夫なのかがそもそもわからないので、get側のsyncだけでも怪しい気はしますが、それは別にしても
2:10 AM
set側のasync(barrier)は、バリアされたタスク同士の同時実行を防ぐものなので https://developer.apple.com/documentation/dispatch/dispatchworkitemflags/1780674-barrier
2:11 AM
書き込み操作同士は直列化されますが (edited)
2:11 AM
読み込み操作とは(多分)排他されないので (edited)
2:11 AM
Dictionaryに対して書き込みと読み込みを同時に行う可能性のあるコードになってます (edited)
2:12 AM
これは明確にDictionaryに対する違反なので暴走して未定義状態になってると思います。 (edited)
2:12 AM
2つ目のコードについては、デッドロックしてないと思います。
2:12 AM
nを10000x1から10000x10まで順番に増加させていくと (edited)
2:13 AM
だんだん処理時間が増加していって、6,7,8ぐらいで急激に増加してました (edited)
2:13 AM
なので、x10のときも時間がかかってるだけに思います。 (edited)
2:14 AM
急激に増加するのはおそらくDictionaryのrehashが発生するからだと思います。 (edited)
2:14 AM
ちなみに1つ目のコードに関しても、 個人的には書き込みをasyncで後回しにするのはあまりやらないほうが良いと思っていて
2:15 AM
その理由は、後回しにする事自体がDispatchQueue側のリソースを食うからです。
2:15 AM
めちゃくちゃたくさん使われるプリミティブなところでそういう処理を書くと、ちょっとしたスケジューリングのブレとかで、
2:15 AM
一瞬で10000タスクがDispatchQueueに乗って待機しちゃうことがありえます
2:16 AM
そうすると普通にそれだけの要素数の配列を読み書きするコストがDispatchQueue内部でかかるし、メモリも食うので、
Avatar
ふむふむ
Avatar
omochimetaru 10/8/2019 2:16 AM
爆弾を抱えてるようなロジックというか・・・
2:17 AM
普通にその場でsyncで書き込んでおくほうが、余計な予測不能要素が増えなくてよいかと。
Avatar
急激に増加するのはおそらくDictionaryのrehashが発生するからだと思います
set の async を sync にすると一瞬で終わるようになるんですが,rehash が原因だとしたら sync でも同様に遅くなりそう…?
Avatar
omochimetaru 10/8/2019 2:18 AM
一瞬で終わるようになる
こっちだと10000x7で20秒ぐらいかかりますね デバッグビルドですか?
Avatar
はい,そのはずです.もう一度やってみます.
Avatar
omochimetaru 10/8/2019 2:19 AM
あ、barrierの仕様読み間違えたかな、
2:19 AM
Work items submitted prior to the barrier execute to completion, at which point the barrier work item executes. Once the barrier work item finishes, the queue returns to scheduling work items that were submitted after the barrier.
2:19 AM
バリア中は他のタスクは走ってないからread/writeの同時実行は生じていないのか。
2:20 AM
concurrent queueをbarrierで同期するコストのほうが、serial queueより重いというのがあるかもしれません。
2:20 AM
内部的にserial queueがsyncされるとき、実際にスレッドリソースとかは使っていなくて
2:21 AM
キューの投入エントリが0個/1個だけのときは、mutexでロックするだけになるんですよね。
Avatar
sync にしたものを Debug build / n = 100_000 で 600 msec で終わりました.
Avatar
omochimetaru 10/8/2019 2:23 AM
なので2つめのコードはロックだけで動いていて、1つめのコードは、たとえreadが生じていなかったとしても、barrierのための同期のオーバーヘッドが高いとか・・・?
2:23 AM
start end: 0.481503963470459 Program ended with exit code: 0
Avatar
ふーむ,書き込みが一気に 100_000 個ブチ込まれるようなケースでは async barrier の方が高コストって感じなんですかね.
Avatar
omochimetaru 10/8/2019 2:23 AM
ああ、ぼくもそのくらいでした、いじってるうちにsetがasyncになってた。
Avatar
はい,print(a[n-1]) のところを消しても同じぐらいかかりますね.
2:25 AM
挙動が予期できないのは気持ち悪いし,僕のケースではこの方法は使わない方がよさそうですね.
Avatar
omochimetaru 10/8/2019 2:25 AM
あ、ひとつ発見しました
2:26 AM
concurrent queue + async(barrier)だと、
2:26 AM
async(barrier)の中身のタスクを実行するスレッドは、asyncを呼び出して投入したスレッドとは別になってますね
2:26 AM
つまり、asyncを呼び出した側はスレッドセーフな内部データ構造にタスクを登録してすぐに抜けていて
2:27 AM
asyncを処理する側は内部のスケジュールの後で同期を取ってほかを排他してから実行する、って挙動を必ず取るっぽい。
2:27 AM
syncの場合はsyncを呼び出したスレッドでそのままロックして待って、スレッドは切り替わらないので、
2:28 AM
やっぱり仕組み上のオーバーヘッドの差がかなりありそうです。
2:29 AM
concurrent+barrierでmulti-read/single-writeな構造を作るのが良いのはアプリとかで負荷のオーダーの見積もりが立つ場合だけじゃないすかねえ
Avatar
僕の理解では, public class SynchronizedDictionary<Key: Hashable, Value> { private var dictionary: [Key: Value] = [:] private let queue = DispatchQueue(label: "shit", qos: .default, attributes: .concurrent) public subscript(_ key: Key) -> Value? { get { queue.sync { dictionary[key] } } set { queue.async(flags: .barrier) { [weak self] in self?.dictionary[key] = newValue } } } } var a = SynchronizedDictionary<Int, Int>() let n = 100000 DispatchQueue.concurrentPerform(iterations: n) { i in a[i] = i } print("HELLO?") print(a[n-1]) 上のコードは HELLO? はすぐ出力されて,次の a[n - 1] の読み取りで待たされるはずだと思ったんですが,HELLO? も待たされるんですよね. (edited)
Avatar
omochimetaru 10/8/2019 2:29 AM
サーバーとかで使ったら、高負荷状況でDispatchQueue内部でのリソース枯渇とかが予測不能・デバッグ不能で詰みそう。
2:29 AM
それは普通に理解が違いますね
Avatar
おぉ
Avatar
omochimetaru 10/8/2019 2:30 AM
concurrentPerformというAPIは、全部終わるのを待ちます。仕様として。
2:30 AM
ああ、書き込みがasyncなのに、ってことか。
Avatar
はい.(コード全部入れ直しました) (edited)
Avatar
omochimetaru 10/8/2019 2:31 AM
単純にタスクの登録作業自体が終わってないんじゃないすかねえ。 (edited)
Avatar
ってことはやっぱ登録に時間がかかってるってことなんでしょうね.
2:32 AM
駆け込み乗車状態🚃 (edited)
Avatar
omochimetaru 10/8/2019 2:32 AM
キューの配列のexpandとかも生じちゃってそう
2:33 AM
配列がでかくなりすぎて。
Avatar
あー,なるほど.
Avatar
omochimetaru 10/8/2019 2:33 AM
試しにsetのasyncの内部でsleepをいれても
2:33 AM
n=10とかならすぐぬけてくる。
Avatar
なるほどなるほど.
2:33 AM
queue を作るとこは sync なはずですもんね.
2:33 AM
納得できました!
2:35 AM
確かに,n = 10 とかにして sleep(3) とかを入れると,HELLO? はすぐに出てそのあとの read で 3×10 秒 書き込み終了を待つ様子が観察できますね! (edited)
Avatar
omochimetaru 10/8/2019 2:36 AM
仕様理解はあってそうですね、n=10000とかになってくるといろんな見えなかったオーバーヘッドが育ってくるということで良さそう (edited)
2:37 AM
DispatchQueueのasyncで非同期処理で繋がったサービスメッシュみたいなことをうかつにやると
2:37 AM
fast-producer/slow-consumerのときにasyncで積んだタスクがどんどん積み上がっていってよくわからん負荷が増えていくみたいな沼が。 (edited)
Avatar
行列の要素セットにこれを使おうか検討してたんですが,やめた方が良さそうですね😂(特に行列のサイズが数十万とかの場合)
Avatar
omochimetaru 10/8/2019 2:40 AM
そうですね
Avatar
norio_nomura 10/8/2019 2:41 AM
syncの場合はsyncを呼び出したスレッドでそのままロックして待って、スレッドは切り替わらない…
以前調べた時は、syncが呼び出しスレッドで実行されるのはqueueに実行待ちのアイテムが無い時で、asyncでアイテムが登録されてるとasyncで登録されたアイテムが実行されるスレッドで実行されるのをsyncが待つ様な実装になってたと記憶。
(edited)
Avatar
omochimetaru 10/8/2019 2:43 AM
asyncの実行を全部待ち終えた後で、syncを呼び出したスレッドでsyncの処理をする?
Avatar
norio_nomura 10/8/2019 2:47 AM
あ、.concurrentだと違うのかな? (edited)
2:48 AM
プライオリティが変わらなければ、queueから取り出される順番は変わらないよね。
Avatar
omochimetaru 10/8/2019 2:49 AM
concurrentですか?そう書いてあるのを見た記憶あります。
2:50 AM
でも、取り出される順番が保証されてても、
2:50 AM
個別のアイテムのスケジューリングが並行なので
2:50 AM
その保証になんか意味あるのかは疑問です
2:50 AM
後から取り出されたほうが先に実行される可能性がありますよね。
Avatar
norio_nomura 10/8/2019 2:55 AM
asyncの実行を全部待ち終えた後で、syncを呼び出したスレッドでsyncの処理をする?
詳細な条件は覚えていませんが、呼び出したスレッドで実行する場合と、async用のスレッドで実行する場合があったかと。
Avatar
omochimetaru 10/8/2019 2:55 AM
なるほど。
2:56 AM
まあいずれにせよスレッド仕様の保証は無いと思って書かないといけないですね。
2:56 AM
思って、と言うか、無いので。
Avatar
素人質問で恐縮なんですが、Swift PM から GPL ライセンスの外部ライブラリに依存させる場合、こちらのライブラリも GPL にしないといけないんですよね?(バイナリだけでなく) (edited)
Avatar
GPLはそうだったと思います
6:39 AM
LGPLだと動的リンクならアプリ側は別ライセンスで良いこちらのライブラリはしなくても良いとも言える、みたいな感じだったかと。 (edited)
6:39 AM
あいや、明確にそうか。曖昧になるのはJava言語での解釈の話だ。
Avatar
ですよね、ありがとうございます🙇‍♂️
Avatar
UIScrollViewの上にtableViewをのせて一定のスクロール値超えたらスクロールする対象をscrollViewからtableVIewに切り替えたいのですが、切り替える時につっかかってしまいます。scrollViewの慣性をtableViewに伝えつつ切り替える方法はないでしょうか? override func viewDidLoad() { super.viewDidLoad() self.tableView.isScrollEnabled = false } ​ func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { ​ if scrollView == self.scrollView { tableView.isScrollEnabled = (self.scrollView.contentOffset.y >= 200) } ​ if scrollView == self.tableView { self.tableView.isScrollEnabled = (tableView.contentOffset.y > 0) } }
Avatar
@mtoyooka table viewの一つ目のsectionにscroll viewに入れたかった内容を入れて、二つ目のsection以降で元々table viewに入れたかった内容を表示するのはいかがでしょうか?
2:11 PM
僕はUIKitのエキスパートではないのでもっと良い方法があるかもしれませんが。
Avatar
@koher 回答ありがとうございます。 説明不足で申し訳ないです。最終的にはXLPagerTabStripを使って動画のようにしたいです。
Avatar
同じようなことを自社アプリでやっています。 私達の場合は、scrollViewの慣性をtableViewに伝えるのではなく、 tableViewのスクロール量をscrollViewに伝えています。 一定量までスクロールしたらscrollViewのスクロールを止め、tableViewだけスクロールするようなイメージです。 そうすることで、XLPagerTabStripのタブの部分を画面に残しつつ、タブの下部だけスクロールさせることが可能になります
1:37 AM
👍 2
Avatar
アル入れていじってみました TableViewの一番上に、辻褄を合わせるための固定幅のセルがあるんですか?
🙏 1
Avatar
contentInsetでもいけそう
3:05 AM
or header
Avatar
スクロールバーが一番上の領域の下側?に入り込んでいくように見えるので。
3:07 AM
それにレイヤーを重ねる形でScrollViewがあって、 そのまま重ねるか、タブだけ上に残る位置になるかを、ScrollViewのスクロール量で制御
Avatar
因みにScrollViewの中にTableViewを入れて、AutolayoutをTableViewとScrollViewのframeで合わせると、スクロールバーが減り込まなくなります
😀 1
Avatar
frameで合わせる
どういう制約?
Avatar
contentじゃなくて外側に制約を合わせると、スクロールしなくなります
3:32 AM
contentSizeにも影響を出さなくなる
Avatar
しばらく考えたけどどういう構成なのか全然わからない・・・
Avatar
アル入れていただいてありがとうございます。 まさに tableview contentInset でつじつまを合わせていました。 そのため、スクロールバーが少し妙な動きをしています😅
4:18 AM
そのまま重ねるか、タブだけ上に残る位置になるかを、ScrollViewのスクロール量で制御
これもおっしゃるとおりですね
Avatar
ああこれセルがあるんじゃなくてcontentInsetなんですね。
Avatar
そうなんです。上のプロフィール領域分、予め contentInset で確保しています
Avatar
なるほどなるほど。とても参考になります。
👍 1
4:21 AM
スクロールバーのところって、
4:21 AM
scrollBarInset?みたいなやつscrollIndicatorInset設定したら、滑り込まなくできませんか? (edited)
4:21 AM
それはそれで変なふうになるんかな
Avatar
あぁ、たしかにそんなプロパティがありましたね
Avatar
スクロールバーが自然な感じになりました 🎉
👏 3
4:31 AM
scrollIndicatorInsets をセットした↑
Avatar
おお
Avatar
これは思いつきませんでした。ありがとうございます 😃
✌ 1
Avatar
@koogawa 一定量スクロールする前はtableViewのisScrollEnabledをfalseにしているんでしょうか?
Avatar
@mtoyooka いえ、true のままですね。false にしてしまうと、おそらく scrollViewDidEndDecelerating が拾えなくなってしまうと思います
🙌 1
Avatar
@koogawa すみません、あまり理解しきれていないのでいくつかお聞きしたいことがあります ・tableViewをscrollViewに伝える場合、どのタイミングで何を伝えていますか? ・tableViewのスクロール量をscrollViewに伝えた場合、スクロールが2倍なりませんでしょうか?そのさいtableViewのスクロールをどのように止めていますか? (edited)
Avatar
@mtoyooka ButtonBarPagerTabStripViewController を継承した ViewController にて次のようにしています。スクロールは2倍にはなりませんでした。 実装例: class ExampleViewController: ButtonBarPagerTabStripViewController, UITableViewDelegate { (中略) override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { let child_1 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: "FRIENDS")) child_1.tableView.contentInset.top = kHeaderHeight child_1.tableView.delegate = self let child_2 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: "FEATURED")) child_2.blackTheme = true return [child_1, child_2] } (中略) override func scrollViewDidScroll(_ scrollView: UIScrollView) { let acutualY = scrollView.contentOffset.y + kHeaderHeight buttonBarView.frame.origin.y = 200 - acutualY } ※例なので 200 とか数値をそのまま埋め込んじゃってます (edited)
Avatar
SwiftPackageManger に入ってる ArgumentParser (コマンドライン引数パーサー)が便利なので使ってたのですが、パッケージ名が SPMUtility から TSCUtility に変わったようです🙄
Avatar
TSCってなんだ?
Avatar
Tools Support Core だそうですw
Avatar
ホゲー
4:24 AM
むむっ、もしかして、
Avatar
ArgumentParser 一個使うのに、このパッケージを丸ごと持ってこなきゃいけないのアレなんですよねw
Avatar
swift-driverプロジェクトでも使ってる?
Avatar
お、やっぱりそうだ
4:26 AM
Swift compiler driver reimplementation in Swift. Contribute to apple/swift-driver development by creating an account on GitHub.
4:26 AM
↑最近できたswift-driverプロジェクトと
4:26 AM
Contains common infrastructural code for both SwiftPM and llbuild. - apple/swift-tools-support-core
4:26 AM
↑そこから依存されてるtools-support-coreライブラリがありますね
4:26 AM
ArgumentParserもこの中に入っているので、
4:26 AM
SwiftPMに依存させず、tools-support-coreに依存させると良いかも? (edited)
Avatar
こんなのあったのか < tools-support-core
Avatar
3月からあったんですねえ。知らんかった。
7:47 AM
あれ?最初のコミットは3月だけどinitial commitと書いてあるコミットは9月だなw (edited)
7:49 AM
Contains common infrastructural code for both SwiftPM and llbuild.
Avatar
おぉ、なるほど、やってみます > tools-support-core に依存させると良いかも?
3:46 AM
withUnsafeMutableBufferPointer を使った書き換え処理で、内部でスライスを作って書き換えるのはダメだと知ったのでシェアします😕 var a = ContiguousArray(repeating: 1, count: 10) a.withUnsafeMutableBufferPointer { buff in for i in 3 ..< 6 { buff[i] *= 2 // 問題なし } } a.withUnsafeMutableBufferPointer { buff in var sub = buff[3 ..< 6] for i in 0 ..< sub.count { sub[i] *= 2 // EXC_BAD_ACCESS } } (edited)
Avatar
スライスはインデックスが0始まりではないからですね。
3:48 AM
a.withUnsafeMutableBufferPointer { buff in var sub = buff[3 ..< 6] for i in sub.indices { sub[i] *= 2 } }
Avatar
あーおッ
3:49 AM
index はそのままなのか、知りませんでした😇
3:49 AM
ありがとうございます!
Avatar
a[3..<6].withUnsafeMutableBufferPointer { buff in for i in 0..<buff.count { print(i) buff[i] *= 2 } } こういうのもできます。
Avatar
omochimetaru 11/8/2019 3:50 AM
This review ended on October 21st, but because of the LLVM conference, the Core Team didn't have an opportunity to discuss it until last week. Swift's indexing model is based on solid concepts that have held up well over the years, but the verbosity of expressing positions a...
3:50 AM
↑つい最近それを buff[.start + i] って書けるようにする案が審査落ちしました。
Avatar
なるほどw
Avatar
ToolsSupportCore の件ですが、Package.swift は let package = Package( name: ... dependencies: [ .package(url: "https://github.com/apple/swift-tools-support-core", .branch("master")) ], targets: [ .target( name: "...", dependencies: ["SwiftToolsSupport"] ), で、 ArgumentParser を使いたいとこで import TSCUtility でいけました🙌 (edited)
Avatar
omochimetaru 11/8/2019 6:54 AM
おお。
Avatar
DispatchQueue.concurrentPerform を使った並列処理で、各イテレーションの中で配列を作ると無駄が大きいからスレッド毎に使い回すようなことをしたいんですが、どうやるのがいいんでしょう🤔
Avatar
スレッドローカルストレージ?
Avatar
上の withUnsafeMutableBufferPointer を使ったやり方では、最初から let threads = 8 とか決めうちしちゃって、大っきな ContiguousArray 作ってスライスしたものを各スレッド(もどき)で使い回す、というようなことをしたのですが。
Avatar
Thread.current.threadDictionaryとか DispatchQueue.getSpecificとか。
Avatar
お、どちらも見たことないものです。調べてみます。
Avatar
一般的にはTLSって言葉で調べると出ます
Avatar
おー、なるほど、スレッド別に辞書を関連づけられるんですね。
10:17 AM
concurrentPerform の中から俺 Queue を指定するみたいなこともできるのかしら。
Avatar
concurrentPerformのクロージャの中がDispatchQueue的にどういう扱いなのかわからないんですが、現在のQueueって取得できないので
10:18 AM
この場合Threadのほうが良い気がしますね
Avatar
おぉ、なるほど、了解です👍
Avatar
少なくとも同じスレッドが同時に走ってる事は原理上無いので、それで目的は果たせそう。
Avatar
ありがとうございます😄
👍 1
Avatar
https://github.com/nvzqz/Threadly こんなの見つけました。
Type-safe thread-local storage in Swift. Contribute to nvzqz/Threadly development by creating an account on GitHub.
Avatar
それ昔なんかの依存先になってて使ったんですがビルドとかあんまりキレイになってなくて微妙な思い出
10:52 AM
あ、僕の1年以上前のPR残ってますね。
Avatar
おぉw
Avatar
ErrorプロトコルのlocalizedDescriptionを上書きたいのですが、うまくいきません。 以下では"hoge"と表示されてほしいのですが、"操作を完了できませんでした。"となってしまいます。 enum hogeError: Error { case hoge var localizedDescription: String { "hoge" } } func sayError(_ e: Error) { print(e.localizedDescription) } sayError(hogeError.hoge) sayErrorメソッド内でhogeErrorにキャストすれば実現できますが、 発生し得るエラーの種類が多いため、すべて列挙するのはあまり現実的でありません。 うまい解決方法はないでしょうか。
Avatar
@watanave import Foundation enum hogeError: LocalizedError { case hoge var errorDescription: String? { "hoge" } } func sayError(_ e: Error) { print(e.localizedDescription) } sayError(hogeError.hoge)
7:53 AM
Errorの代わりにFoundation.LocalizedErrorに準拠して、errorDescriptionの実装を与えると、 .localizedDescriptionが変更できますよ。
Avatar
ありがとうございます!感激です!🙇
Avatar
この謎の方法は
7:58 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
7:58 AM
Swift.ErrorをFoundation.NSErrorに自動変換する挙動に関係してて
7:59 AM
その証拠(?)に、
7:59 AM
import Foundationimport UIKitなどを書かなければ
7:59 AM
func sayError(_ e: Error) { print(e.localizedDescription) } ↑これがそもそもコンパイルエラーになります
7:59 AM
.localizedDescriptionFoundation.NSErrorのメソッドで、Swift.Errorには無いメソッドだからです。
8:00 AM
import Foundationすると、ErrorからNSErrorへの暗黙の変換が起こるようになって、呼び出せるようになる。
Avatar
おー本当だ! そんな型変換が行われてるなんでぜんぜん知りませんでした。
😁 1
Avatar
SwiftUIのTextに表示させる値に、非同期処理の繰り返し処理の結果を順次反映させたいのですが、どうすれば実現できるでしょうか。
Avatar
Kishikawa Katsumi 11/21/2019 7:22 AM
非同期処理の結果を保持する変数を @Binding@ObservedObject で用意して、TextのBindingにその変数を指定します。 これで変数として持っている状態がTextに自動的に反映されるようになります。 あとは非同期処理が完了するタイミングで適宜その変数を更新します。
😃 1
Avatar
Taihei Mishima 11/21/2019 7:40 AM
SwiftGenを導入しようと思ってcocoapodsでinstallすると, build時に下記のようなwarningが出るようになってしまいました. 解決方法が思い浮かぶ方いらっしゃいますでしょうか? ld: warning: Could not find or use auto-linked library 'swiftDarwin' ld: warning: Could not find or use auto-linked library 'swiftCoreFoundation' ld: warning: Could not find or use auto-linked library 'swiftObjectiveC' ld: warning: Could not find or use auto-linked library 'swiftDispatch' ld: warning: Could not find or use auto-linked library 'swiftCoreImage' ld: warning: Could not find or use auto-linked library 'swiftQuartzCore' ld: warning: Could not find or use auto-linked library 'swiftCoreGraphics' ld: warning: Could not find or use auto-linked library 'swiftCore' ld: warning: Could not find or use auto-linked library 'swiftMetal' ld: warning: Could not find or use auto-linked library 'swiftFoundation' ちなみに, 同様のMac, Xcodeの環境で新規プロジェクトを作成してSwiftGenをpod installした場合は上記のwarningは出ません. どこから手をつけたら良いか, どこの部分の理解が足りてなくて解決できないのかわからずという状態です. (edited)
Avatar
Twitterのprofileのようにheader?の部分をスクロールしても、tableViewに慣性が伝わっている?ように見せる方法はありませんでしょうか?
8:09 AM
Avatar
Kishikawaさん、回答ありがとうございました! いただいた情報から https://qiita.com/shiz/items/6eaf87fa79499623306a に行きつきました。 (edited)
  • 2019/7/17 @GestureStateについて追記しました。
  • 2019/7/19 BindableObjectがdidChange->willChangeなど変更されていたので修正しました。
https://...
Avatar
@Taihei Mishima エラーメッセージでGoogle検索などしてみましたか?或いはSwiftGenのgithubに同様の問題のissueは上がっていなかったでしょうか。 経験則としてはこのメッセージが出てくる時は、ライブラリのリンク周りで問題が起きていることが多いです。 検索で何も見つからなかったなら、新規のプロジェクトとフレームワークの設定周りで注意深くプロジェクトの差分を見比べると、答えが見つかるかもしれません。 (edited)
2:38 AM
@mtoyooka 丁度すぐ上の方で似た質問がありましたので、ここの過去ログを検索してみるとよさそうです。
Avatar
同じ人でした。 didScrollは慣性は通知されていない(指が触れてる間のみ流れている)関数になるので、他の実装も必要になります。 方法としては二つあると思います。 1. willEndDraggingを実装して慣性を計算する https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619385-scrollviewwillenddragging 2. scrollViewのsetContentOffsetをオーバーライドする/KVOで監視する 1番だと何かと細かい制御が難しくなるので2番がお手軽でしょうか。 (edited)
Avatar
はじめまして。swiftサーバに最近参加したにーの( @n_shhhin )と申します。 今現在バックグラウンドで加速度を取得したい状況で、Background系の開発に疎いので手助けが欲しいです。AppStoreにリリースするのは目的ではないので、プロトでできればいい程度に思っています そこで質問なのですが、 iOS13で導入されたBackgroundTaskは BackgroundTask、 ●Background Processing Tasks - 数分かかる処理 - 延期可能なメンテ処理やCoreMLによるトレーニングを想定 ●Background App Refresh Tasks - 30秒のランタイム - アプリを最新の状態に保つための用途を想定 - performFetchのAPI が代わりにdeprecatedに みたいな感じの仕様らしいのですが、background processの数分ってのは実際どれぐらい処理が続く感じなんでしょうか。 また BackgroundTask では実現できないなら他の案をご教授いただきたいです。 既存アプリのGoogleフォトとかはバックグラウンドで常に写真のアップロードを監視してたりするのでできないことはないと思うのですが、どうやってバックグラウンドで常時処理をするのかが気になりました。よかったらどなたか強い人回答お願いします。 https://github.com/nshhhin/Background-Accel-Swift
バックグラウンドで加速度を取るプログラムSwift. Contribute to nshhhin/Background-Accel-Swift development by creating an account on GitHub.
3:20 AM
一応wipなGitHubレポジトリも載せておきます。宜しくお願いします
Avatar
@わをさん 案内だけして放置してしまい申し訳ありません。 BackgroundTaskはおそらくiOS13から使えるようになったものだと思うのですが、registerをBackGroundProcessの中で呼ぶ事で処理時間を延長するテクニックが使えるのではないか?それを使えばある程度は自由に動かせるのでは?と予想しています。https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler/3180427-register 途切れた場合はsilent pushから起こす事も出来そうですね。 一方で、バックグラウンド処理はユーザーから認識しづらく、一定のリソースには制限がかかっている可能性があると思います。特に位置情報はかなり大きなアラートが出ています。 もし素直な方法でうまくいかない場合は、制限がかかっている可能性もあると思うので(加速度センサーのデータは位置情報に次いでそれなりにセンシティブな情報だと思います)、公式ドキュメントの制限の項を参照してみるとよいかもしれません。 現状もし加速度センサーがBGTaskから使えない場合は、まともな代替手段は無いものと思います。
4:38 PM
再起呼び出し
コードを見てみたらそういう感じの処理が書いてありますね、失礼しました
Avatar
@tarunon 返信ありがとうございます。なるほど参考にさせていただきます。
Avatar
SwiftPM の SystemLibrary 機能を使って C ライブラリを Swift から使おうとしているのですが,うまく行かずに困っています. ライブラリは: https://github.com/malb/m4ri これを使いたい Package の方で,targets に .systemLibrary( name: "Cm4ri", path: "Libraries/Cm4ri" ), を追加し, dependencies に "Cm4ri" を追加した上で, Libraries/Cm4ri/module.modulemap module Cm4ri [system] { header "/usr/local/include/m4ri/m4ri.h" link "m4ri" export * } を追加しました.コマンドラインから "swift run" すると通るのですが,generate-xcodeproj して実行しようとすると,include される m4ri.h の中で "'m4ri/mzp.h' file not found" というエラーが出てビルドできません😓 (edited)
Avatar
omochimetaru 12/6/2019 4:26 AM
swift runで通ってgenerate-xcodeprojで通らない場合、 (edited)
4:26 AM
生成されたxcode projのbuild settingsに問題があるので、
4:27 AM
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
4:27 AM
Package.swiftでunsafeFlagsとかheaderSearchPathを設定してやれば
4:27 AM
その設定がxcodeprojにも生成時にコピーされるので
4:27 AM
解決できることがあります。
Avatar
ふむふむ,やってみます.
Avatar
omochimetaru 12/6/2019 4:28 AM
SystemLibraryの構成として正しいかどうかは経験不足ですぐわかりません。
Avatar
headerSearchPath は絶対パス指定できないですよね,確か
Avatar
omochimetaru 12/6/2019 4:28 AM
unsafeFlagsしか使ったことないw
Avatar
Kishikawa Katsumi 12/6/2019 4:35 AM
私も最近のは詳しくないんですけどこれそもそもSystemLibraryにするものなんですか? Cm4riを依存ターゲットに指定するんじゃないのかな。
Avatar
system module ってのをやろうとしたら deprecated って出て,system library にせよと言われたので,こちらを参考にやってみました https://troubled.pro/2018/09/shim.html
With Swift 4.2 the Package Manager introduces System Library Targets.
4:41 AM
このライブラリは make install すると,/usr/local/include/m4ri/ ってディレクトリができて,そこにたくさんヘッダファイルが置かれるんですが,その中の m4ri.h だけを modulemap で指定してるからいけないのかなぁ🙄 (modulemap の仕組み全くわかってない) (edited)
4:43 AM
umbrella ってのを使えばできるのかも
Avatar
あれれ,新規 package 作ってやり直したら swift run でも動かなくなった orz
4:56 AM
https://github.com/taketo1024/shit サンプルプロジェクトをこちらに置きました
Contribute to taketo1024/shit development by creating an account on GitHub.
Avatar
Kishikawa Katsumi 12/6/2019 4:56 AM
ひどい名前 😓
4:57 AM
m4riってどうやってインストールしてます?
Avatar
https://github.com/malb/m4ri こちらを clone して, autoreconf --install ./configure --enable-openmp make make check make install しました. (edited)
Avatar
Kishikawa Katsumi 12/6/2019 5:00 AM
そうですよね。それだったら(Homebrewでインストールとかじゃなければ) make install のインストール先をプロジェクト内にしてしまって、
5:00 AM
そうするとmodulemapの解決も簡単だし。SystemLibraryじゃなくて単なるライブラリとして使えると思うんですよね。
5:01 AM
ちょっとやってみますか。 m4riが私の環境ですんなりビルドできなかったら解決は週末で。。。
Avatar
すみません,助かります 🙇
5:02 AM
brew install libomp libtool もしました.
Avatar
Kishikawa Katsumi 12/6/2019 5:03 AM
libtoolはautoconfですよね。
5:03 AM
libompはm4riが依存してますか?m4ri自体はOpenMPなしでビルドできます? (edited)
5:05 AM
ああ、READMEに載ってましたね。依存してるけどなしでもビルドはできるっぽいですね。
Avatar
あ,そうですね.なしでもできると思います.
5:08 AM
omp は並列処理のためのライブラリです.
Avatar
Kishikawa Katsumi 12/6/2019 5:17 AM
./configure --prefix=$PWD/dist make install ^ のようにすると$PWD/distにライブラリがインストールされます。
5:19 AM
OpenMPも有効にするなら ./configure --prefix=$PWD/dist --enable-openmp ビルドが終わるとdistは以下のようになります。 dist ├── include └── lib
5:20 AM
これはだいたい標準的なAutotoolsを使ったCライブラリのビルドの成果物で、 lib以下にライブラリ本体、includeにライブラリを使用するために必要なヘッダファイルがコピーされます。
5:21 AM
dist ├── include │   └── m4ri │   ├── brilliantrussian.h │   ├── debug_dump.h │   ├── djb.h │   ├── echelonform.h │   ├── graycode.h │   ├── io.h │   ├── m4ri.h │   ├── m4ri_config.h │   ├── misc.h │   ├── mmc.h │   ├── mp.h │   ├── mzd.h │   ├── mzp.h │   ├── parity.h │   ├── ple.h │   ├── ple_russian.h │   ├── ple_russian_template.h │   ├── solve.h │   ├── strassen.h │   ├── triangular.h │   ├── triangular_russian.h │   ├── xor.h │   └── xor_template.h └── lib ├── libm4ri-0.0.20140914.dylib ├── libm4ri.a ├── libm4ri.dylib -> libm4ri-0.0.20140914.dylib ├── libm4ri.la └── pkgconfig └── m4ri.pc
5:23 AM
^ 全部出すとこう。今回は必要なのはlibm4ri.aだけなんですけど、 ^ のdistディレクトリを自分のプロジェクトの中に入れてしまって (configureでそうなるようにして)SwiftPMからはそれを参照するようにすると、SystemLibraryとか気にせずに単にプロジェクト内にあるStatic Libを参照するだけ、となるはず。(というのを今試しています)
Avatar
おぉ,なるほど,これを丸ごと Package に入れる感じですね…
Avatar
Kishikawa Katsumi 12/6/2019 5:31 AM
. ├── Libraries │   └── Cm4ri │   ├── include │   │   └── m4ri │   ├── lib │   │   └── libm4ri.a │   └── module.modulemap ├── Package.swift ├── README.md ├── Sources │   └── shit │   └── main.swift └── Tests ├── LinuxMain.swift └── shitTests ├── XCTestManifests.swift └── shitTests.swift リポジトリの構成をこのようにするとして
5:32 AM
そうするとmodulemapは例えばこうなる module Cm4ri { header "include/m4ri.h" link "m4ri" } (modulemapはいろんな解があるんでいったん簡単なやつで試す) (edited)
5:35 AM
Xcodeだったらこれでビルドするやり方はわかるけどSwiftPMのやり方を調べ中。。。
Avatar
近い将来ソースコードを公開したいと思っているので,できれば外部のライブラリを参照する形にしたいのですが… 難しそうですかね…😔
6:00 AM
(なんで外部ライブラリを使うだけのことでこんなに苦労するのか…😔
Avatar
omochimetaru 12/6/2019 6:01 AM
なんで外部ライブラリを使うだけのことで
SwiftPMの設計哲学とC言語の慣習的な設計哲学が噛み合ってないから、と理解している
Avatar
Kishikawa Katsumi 12/6/2019 6:12 AM
Macの調子が悪くて一向に進まない。。。
Avatar
omochimetaru 12/6/2019 6:12 AM
ライブラリとして再配布するのであれば、system libraryで組むほうが今回は良さそうに思う
6:13 AM
バイナリとして取り込んじゃうとそれの管理が自己管理になっちゃうから
Avatar
Kishikawa Katsumi 12/6/2019 6:14 AM
今回のはどうせ手元でビルドするわけだからビルドスクリプトを含めて配布する方が私は良いと思う。
6:14 AM
ビルドスクリプト内でgit cloneしたらいいわけだし。
6:15 AM
どちらかというとグローバルにインストールしたくなくないですか?
Avatar
omochimetaru 12/6/2019 6:17 AM
そうですねえ、ローカルインストールのほうが望ましい ローカルインストールでもグローバルインストールでも使えてユーザーが決定できるのが理想
Avatar
make install のときに作られる pkg-config ファイルをコピーするとうまくいくのかもです(試し中)
Avatar
omochimetaru 12/6/2019 6:18 AM
末端のアプリプロジェクトのビルド時に、 -Xcc -Xlinker / もしくはunsafeFlags でローカルパスを指定したら、
6:18 AM
システムライブラリでもローカルを参照させるとか、
6:18 AM
コントロールできないのかなあ
6:19 AM
結局コンパイル時とリンク時にオプションが渡ってれば良い話だから。
Avatar
うーむ,なるほど > ローカルインストールの方が望ましい (edited)
Avatar
omochimetaru 12/6/2019 6:22 AM
今、SwiftPM CUI, SwiftPM generate-xcodeproj, Xcode SwiftPM Support, Xcode Package.swift open の4環境あるから (edited)
6:22 AM
その全部で安定してできる方法を探すのもしんどいんですよね。
6:23 AM
Xcode SwiftPM Supportの場合って、コンパイラ・リンカフラグを依存先に与える方法あんのかな。
6:24 AM
よく考えたら4環境だ
6:24 AM
ちなみに
6:24 AM
これ系で一番安定するのは
6:24 AM
CソースをそのままSwiftPMでコンパイルさせる、SwiftPMのC Targetを採用する事だと思ってます
6:25 AM
もともとのCライブラリとディレクトリ構造とか、include文の相対パスとかが、 そのまま打ち込めばいける場合と、それなりに手直しが必要な場合があって、
6:25 AM
万能な方法ではないけど
Avatar
https://github.com/taketo1024/shit/commit/28a5184eba2701167095a6daecccac451ef4aa42 とりあえずこの方法で swift run, Xcode の両方でビルドできるようになりました! systemLibrary を使う場合は pkgConfig ファイルを一緒に入れとく必要があるようです.
Avatar
Kishikawa Katsumi 12/6/2019 6:26 AM
お、なるほど
Avatar
SwiftやiOS開発の学習コンテンツでオススメとかあれば、教えてほしいです🧐 最近Udemyの英語コンテンツとかはトライしてみてるのですが...
Avatar
Kishikawa Katsumi 12/9/2019 4:44 AM
https://www.raywenderlich.com/ はいいと思います。
High quality programming tutorials: iOS, Android, Swift, Kotlin, Flutter, Server Side Swift, Unity, and more!
Avatar
ありがとうございます、まさにこういうの探してました...
Avatar
初めまして質問させて頂く「やました」と言います! よろしくお願いいたします! 現在SNSアプリでよく見かける、リストの途中に動画が挟み込んで自動再生するUI(Twitterアプリを参考)を作成しています! 以下の構成で作成しているのですが、動画セルを再利用した時に動画を途中から再生を行いたいのですが、Twitterアプリに比べると動画がスムーズ(URL設定→seekで指定時に側反映されないためDispatchで遅延処理をしている)に再生することができません...。 皆さんどうやってあんなにスムーズに途中から再生できてるんだ...!🧐 何か参考のサイトや、アドバイス頂けますと幸いです🥺 よろしくお願いいたします! # 構成 ├── UITableView │ └── VideoCell(UITableViewCell継承のCustomClass) │ ├── currentTime(動画再生時間を保持するメンバ) │ ├── VideoView(UIView継承のCustomClass) │ │ └── AVPlayer │ │ └── AVPlayerItem │ │ └── AVPlayerLayer # 作りたいもの Twitterアプリのタイムラインで表示される動画のUI # 機能 UITableView上で動画を再生・一時停止   1. スクロール時、動画のcellが画面内に収まっている場合は動画を再生   2. スクロール時、動画のcellが画面外に出ている場合は動画を一時停止 # やっている事 スクロール時に再生・一時停止の処理   1. ScrollViewのdelegate `scrollViewDidScroll` で最上部・最下部のCGPointを取得   2. 1で取得したCGPointからindexPathを取得   3. 2で取得したindexPathからcellを取得   4. 3で取得したcellのframeと画面上部、画面下部のcontentOffset.yを計算して、収まっている or 収まっていないを判定   5. 判定結果により、動画を再生 or 一時停止 # うまくいかない所 一度再生した動画セルが画面外に行き、再度画面内に来た時にスムーズに続きから再生されない   a. AVPlayerItemに動画URLを設定   b. AVPlayerのreplaceCurrentItemで設定   c. AVPlayerのseekで保持していた再生時間を指定(そのまま指定すると反応しない?のでDispatchで遅延実行しています)
Avatar
Kishikawa Katsumi 12/9/2019 3:42 PM
一部のセルが動画というだけならセルの再利用をやめて(セルは再利用してもいいけどその上のVideoViewの再利用はしない)みたらどうなります?
3:43 PM
全部のセルが動画ならしょうがないけど一部ならそれで状態の復帰とかしなくて良くなるし、普通に途中から再生されるんじゃないですかね。
Avatar
@Kishikawa Katsumi ご返信ありがとうございます! セルの再利用をしないなんて事が可能なんですか...!? 一部のセルが動画のイメージなため、確かに再利用をしなければ状態復帰の必要がなくなりますね。 再利用をしない場合って dequeueReusableCell を使用せずに、cellを生成すれば良いのでしょうか?
Avatar
Kishikawa Katsumi 12/9/2019 4:32 PM
VideoViewを別に持っておけばいいです。
4:33 PM
セルは再利用されるけど、VideoViewは生き続けるようにします。
Avatar
なるほど! 動画がいくつかある場合は、動画の数だけVideoViewを生成して配列で持っておいて、cellForRowのタイミングで当て込めば良い、って感じでしょうか?
Avatar
Kishikawa Katsumi 12/9/2019 4:44 PM
はい。動画のセルがそれほど多くならないならそれがいいと思います。
Avatar
おぉ!さっそく試してみます☺️ ご教授して頂きありがとうございました!
Avatar
それするなら動画のセルのreuseIdentifierを増やして再利用の頻度を減らした方が良さそうな気がしますがそうでもないです?
Avatar
Swift 初心者です。ある型の実装を限定することってできるんでしょうか。例えば、protocol Cat があって KawaiiNeko: CatCuteNaNeko: Cat は作ってあるけど勝手に KawaikunaiNeko: Cat は作られたくないんです。
3:27 AM
protocl じゃなくてもなんらかの表現でこの制約が与えられた良いのですが...
Avatar
できないです、protocolの代わりにenumを使うと良いと思います。
Avatar
enumは近そうなんですがちょっとキツい感じが。
3:28 AM
というのも、stored valueをswitchで取り出してなにかするみたいなfuncが大変なことになりそうで...
Avatar
enum Cat { case kawaiiNeko(KawaiiNeko) case cuteNaNeko(CuteNaNeko) } protocol CatProtocol { } struct KawaiiNeko: CatProtocol {}
3:28 AM
こうやっといてCatで受ける感じです。
Avatar
ああ、なるほど
3:29 AM
これは賢い
Avatar
enum Cat に対して CatProtocol のメソッドを全部実装しちゃえば、
3:30 AM
使う側でのswitchは回避できますね。
3:30 AM
定義はめんどうだけど。。
3:30 AM
CatProtocolがPAT(Self, associated type)ではないなら
3:30 AM
extension Cat { func asCatProtocol() -> CAtProtocol }
Avatar
そうなんです、誰か(作る側、使う側)がめんどうなことをしないといけないようですよね...
Avatar
↑これ作っておくと楽
Avatar
なるほど.
3:32 AM
試してみます...!
Avatar
誰か(作る側、使う側)がめんどうなことをしないといけない
Swiftにときどきありがち
Avatar
たくさん出てくるなら、自分で定義かいて自動生成するとか、 SwiftSyntaxで構文解析して自動生成するとか、
3:33 AM
そういう感じになってきますね・・・
Avatar
現在は自動生成ルートに向かう方向性になってます
Avatar
はや
Avatar
でも、そうする前に知らない、なにか素敵な解があるかなって思ったのでした。
Avatar
ああ、なるほど。。
3:35 AM
長期的にはforumで提案して言語仕様拡張で解決するのが一番いいやつですね。
Avatar
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
3:36 AM
プロパティ限定になっちゃうかもだけど。
Avatar
ふむー、できれば避けたい...
3:37 AM
ちょっと試してみます。ありがとうございます!
👍 1
Avatar
class でいいならopen classではなくpublic classでサブクラス化を抑制できそうですね
Avatar
たしかに。
Avatar
こんにちは。SwiftUI でButtonを設置せずに指定条件下(classでデータのやりとりをしており、ObservableObjectで監視?繋げて?ます)で自動で画面遷移する方法を探しています。 (edited)
7:53 AM
どなたかいいサイト等ご存知でしたら教えていただきたいです🙇‍♂️
Avatar
別途で教えていただき解決いたしました。申し訳ありません。お騒がせいたしました🙇‍♂️
Avatar
自己解決したときは、その方法を記載しておくと後の人のためになるのでオススメです
🙏 2
Avatar
https://github.com/t-ae/tensorboardS/blob/master/Sources/TensorBoardS/Writers/SummaryWriter.swift#L124-L149 ロガーの実装ですが、ログを書く関数内にtryがあります。 このような場合インターフェースとしてはどのようなものが好ましいと思いますか? 1. throwsにする ユーザー側で毎回ハンドリングが必要なのでロガーとしてはいまいちな気がします。 2. 中でcatchして別途設定したハンドラに渡す 今はこれになっています。ハンドラはエラーだけを取っていますが、コールスタック等の情報も入れたほうがいいのかと考えています。 (edited)
TensorBoard event writer for Swift for TensorFlow. Contribute to t-ae/tensorboardS development by creating an account on GitHub.
Avatar
omochimetaru 1/20/2020 4:20 AM
たしかにログを追加することでthrowsになるのは嫌だから2で良さそう
4:21 AM
do-catch { errorHandler() } が何度も出現してるから、実装は高階関数にしたほうが良さそうと思った あと合成する場合は一番上だけでcatch
Avatar
>合成する場合 合成ってなんでしょう?
Avatar
omochimetaru 1/20/2020 4:23 AM
addJSONTextの中でaddTextを呼んでるところは
4:23 AM
例外を投げる版のaddTextOrThrowを作ってそっちを呼び出したい。
Avatar
ああ、そうですね。ここdoがネストになってますね。
Avatar
omochimetaru 1/20/2020 4:24 AM
今回はギリギリ問題は起きないけど、 f1, f2, f3が f1 { f2, f3 } って合成されてるときに、 f2がエラーでもf3が実行されるなどは不自然に思う
Avatar
ユーザーが呼ぶ関数が非throwsであれば良いので、その関数でcatchしてハンドラに投げれば良いからinternal関数は全部throwsにして垂れ流しでも問題ない?
Avatar
インターナルは基本throwsにしてますね。
Avatar
omochimetaru 1/20/2020 4:27 AM
addTextはユーザにも見せたいだろうから、 public addTextとinternal addTextOrThrowが必要と思った (edited)
4:27 AM
それか俺だったら型を分けちゃうかも。
Avatar
ThrowableSummaryWriterのような?
Avatar
omochimetaru 1/20/2020 4:28 AM
そう
4:29 AM
それでSummaryWriterは全部 func addText(...) { wrap { try w.addText(...) } }
4:29 AM
のスタイルだけで書ける
Avatar
SummaryWriter自体にデータ処理する箇所が少なからずあるのでそれは良さそうですね。
Avatar
omochimetaru 1/20/2020 4:30 AM
try wrap(w.addText(:))(...) こういうのもできるかもw
4:30 AM
関数変換にする。 文字数が少し減るけど まあデバッグしづらいから自分はやらないかな。 (edited)
Avatar
とりあえずthrowsなクラスに分けてみます。
4:33 AM
あとコールスタックですけど、do中にtryが二個あった場合catchでどちらか判別できますっけ? Thread.callStackSymbolsで取るとcatchした関数までのコールスタックになっちゃうと思いますが。
4:34 AM
ユーザーの興味はどこのwrite関数の呼び出しかなのであんまり重要じゃない気もしますが (edited)
Avatar
omochimetaru 1/20/2020 4:35 AM
どちらか判別できますっけ?
できないと思う。例外を作る関数を一個ラップすればわかるようになるかな。
4:35 AM
ん、Thread.callStackSymbolsがエラーの型のinitの中にあるなら
4:35 AM
わかりそう
Avatar
JSONEncoderとかのなのでどうでしょう・・・ (edited)
Avatar
omochimetaru 1/20/2020 4:39 AM
あーなるほど。
4:39 AM
自前の例外じゃないのか。それだとcatchで作る事になって、ユーザの呼び出しポイントしかわからないね。
Avatar
https://github.com/t-ae/tensorboardS/blob/master/Sources/TensorBoardS/Writers/SummaryWriter.swift 分けてみました。最終的には自動生成したいところですね。
TensorBoard event writer for Swift for TensorFlow. Contribute to t-ae/tensorboardS development by creating an account on GitHub.
4:52 AM
今気づいたんですがこれ分けることによってコールスタック取るのがSummaryWriterの関数内までになっちゃいますね。
Avatar
omochimetaru 1/20/2020 5:00 AM
まあユーザーは関心無いのでは
5:00 AM
Loggerの内部実装に依存してる部分の情報は
5:01 AM
ユーザーからすると役に立たないし。
Avatar
@tarunon
自己解決したときは、その方法を記載しておくと後の人のためになるのでオススメです
すみません、今頃気がつきました🙇‍♂️
4:55 AM
01/15/2020 に質問して自己(?)解決した件について、今更になったのと質問内容がよろしくなかったりしたのでリンクのみで失礼いたします。 https://teratail.com/questions/235289 簡潔に言うと、 NavigationLinkのパラメータのisActiveの中身の書き方でした。
指定条件下で画面遷移するように実装したいSwiftUIで、coreBluetoothを使用したiOSを作成しております。画面はstoryboardを使わずSwiftUIのstruct XXX: Viewで作成しており、画面以外のデータ等はclassでObservableObjec
👏 1
Avatar
解決編の投稿ありがとうございます! Discordは過去の投稿の全文検索も使えるので、活用できると嬉しいですね☺ (edited)
Avatar
そうなんですね!いつもありがとうございます!!✨
Avatar
値型はCoWがあるとは言えループを伴うmutatingでは極端に遅くなる傾向があるので工夫が必要だと思います
4:36 AM
#swift でも良さそう。
Avatar
Taketo Sano 2/4/2020 4:37 AM
すみません, #swift に再投稿します🙇
Avatar
投稿へのリファレンスが貼れるようになってるので
4:37 AM
それでよさそう。お待ちを〜
4:38 AM
おそかったw
Avatar
Taketo Sano 2/4/2020 4:38 AM
おっとw
4:38 AM
原始的なやり方しか知らずすみませんw
Avatar
プロモーションオファーの調査をしているんですが、調べてもあまり分からず知見がある方がいましたら教えてほしいです 🙇
  • 過去にプロモーションオファー(初月無料)を利用したことのあるユーザーも、再度プロモーションオファーで初月無料で利用可能か また それは同じプロモーションオファーIDでも有効か
  • 初月無料(プロモーションオファー)を利用して解約後、◯ヶ月経過したら再度プロモーションオファーで初月無料で利用するといったことが可能か
イマイチいくつかの記事を見ても上記ができるのかどうかが分からず。。。 https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/implementing_subscription_offers_in_your_app
Avatar
Swift & SwiftUIを初めて触り SwiftUIのチュートリアルをやっていて不明な点があったので質問させてください! 質問: 以下のcategories, featured の変数宣言の仕方が複雑でどうなってるのでしょうか?宣言時にクロージャをつけると代入になる模様です。いまいち仕組みがわかりません、、 解説もしくは何かリファレンスになるリンクを頂けると嬉しいです。 struct CategoryHome: View { var categories: [String: [Landmark]] { Dictionary( grouping: landmarkData, by: { $0.category.rawValue } ) } var featured: [Landmark] { landmarkData.filter { $0.isFeatured } } ... }
Avatar
Kishikawa Katsumi 3/20/2020 5:36 PM
https://docs.swift.org/swift-book/LanguageGuide/Properties.html# ^ 参考にできるドキュメントとしては上記のPropertiesを読むと良いです。 Swiftは同じ意味でも省略が可能だったりして記述が異なる場合があり、今回のケースで理解に悩まれているのは省略によって別の記法と混同してしまっている、などが原因に見えます。 なのでまずできるだけ省略せずに書いてみます。
5:38 PM
struct CategoryHome: View { var categories: [String: [Landmark]] { get { return Dictionary( grouping: landmarkData, by: { $0.category.rawValue } ) } } var featured: [Landmark] { get { return landmarkData.filter { $0.isFeatured } } } ... }
5:38 PM
^ 省略されている部分を書き足しました。
5:40 PM
このcategories, featured はComputed Propertyと呼ばれるもので、Property(プロパティ、メンバ変数、インスタンス変数)の一種ですが、実際の値を変数に保持しているわけではなく、アクセスがあったときに書かれている処理を実行して動的に値を返すことができる、というものです。
5:42 PM
利用側は let home = CategoryHome() let categories = home.categories このように通常のプロパティと同じようにアクセスしますが、 Computed Propertyはアクセスされたときに書かれている処理(ここでは get { ... } の中カッコの部分)を実行して値を返します。
5:43 PM
詳しくは先のリンクのドキュメントを見ると良いですが、 Computed Propertyはgetset の両方を定義できて、この例ではget の場合だけが定義されています。 (edited)
5:44 PM
このとき、getしかない場合はget { ... } と書くのを省略できて、中カッコだけにできます。 (edited)
5:47 PM
struct CategoryHome: View { var categories: [String: [Landmark]] { return Dictionary( grouping: landmarkData, by: { $0.category.rawValue } ) } ... }
5:48 PM
さらに、処理がreturn 文1行しかない場合はreturnを省略できます。(これはComputed Propertyだけでなくメソッドやfunction、クロージャでも当てはまります。)
5:49 PM
struct CategoryHome: View { var categories: [String: [Landmark]] { Dictionary( grouping: landmarkData, by: { $0.category.rawValue } ) } ... }
5:49 PM
^ return まで省略すると、最初の例と同じになります。どういう構造の文法で書かれているかわかりましたでしょうか?
Avatar
早速で詳しい回答ありがとうございます!正体は computed Property だったのですね、、助かりました!
Avatar
MVVMの勉強をしたいのですが、参考になるサンプルなど紹介していただきたいです。現状としては「iOSアプリ設計パターン入門」を購入して、この本のMVVMの章のソースを写経しました。swift-zoominチャンネルで話題になっている https://github.com/refactoring-challenge/reversi-ios をMVVMで作る挑戦してみようかと思いました。
Contribute to refactoring-challenge/reversi-ios development by creating an account on GitHub.
Avatar
@ktanaka117 もし良いものがあればお願いします🙇‍♂️
9:44 AM
とりあえず、まずはアニメーションを諦めてみるとデータバインディングで簡単にできそうなので、その上でどうアニメーションに取り組むかを考えてみても良いかもしれません。
Avatar
@koher ありがとうございます。まず、コマを置くためのボタンを押した処理がどれなのか分からないので、その辺りから見てみます。 (edited)
Avatar
↓に解説のある https://github.com/refactoring-challenge/reversi-ios/blob/master/README.md#boardviewswift func boardView(_ boardView: BoardView, didSelectCellAtX x: Int, y: Int) ですね。
Avatar
おお!ありがとうございます😄
Avatar
Contribute to refactoring-challenge/reversi-ios development by creating an account on GitHub.
Avatar
なるほど、ありがたいです🙇‍♂️
Avatar
はじめまして。こちらでAVFoundation, CoreAnimationのことについて質問してもいいでしょうか。
Avatar
多分大丈夫
5:55 AM
#uikitとかのような気がしなくもないですが...
5:55 AM
あるいは#macos/#ios?まあ厳密じゃないと思うので...
Avatar
ありがとうございます。動画生成時にCALayer, CoreAnimationを適用してテロップのようなものを表示させたいのですがうまくいかなくて。後ほど投稿させてください。
Avatar
AVAssetWriterInput とかですかねー。
Avatar
動画の上に、CALayer, CoreAnimationを使い、動画に右から左へ1文字ずつ文字が流れるようにしたいと思っています。具体的には、(1)1文字ずつCALayerを作る。(2)CAKeyframeAnimation(keyPath : "position.x")で右から左に移動させるアニメーションを定義してCALayerに適用する。 、(3)そのCALayer達をAVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) でAVVideoCompositionCoreAnimationTool を生成し、AVMutableVideoCompositionのanimationToolに設定して、AVAssetExportSessionでexportする処理を書きました。これで実行すると、同じバイナリで動かしているのに、アニメーションが動作する場合とアニメーションが一切動作しない場合があり、これはどうデバッグしたものかと悩んでおりました。 (edited)
Avatar
AVVideoCompositionCoreAnimationTool かあ...
8:14 AM
exportには成功するんですか?
Avatar
exportは成功します。
Avatar
なるほど
8:17 AM
一般的なあれですが、動作したりしなかったりはなんかオブジェクトのライフタイムが切れちゃってるとか、そんな感じがしますね
8:17 AM
完全に同じ条件で実行するたびに挙動が変わる、ということなら。
8:21 AM
あと、多分調べられたと思いますが、これにいろいろハマりポイントが書いてあります (edited)
Avatar
ちなみに想像していたのは(1)iOSのリソースが足りなくて内部でエラーも出ず落ちている (2)アニメーションが早すぎてcoreAnimationの定義が無視されてる とか考えてました (edited)
Avatar
p56から
8:22 AM
AVAssetExportSession はバグ多いんですが、
Avatar
@niw ありがとうございます。この資料は初見です。
Avatar
エラーが出なくて書き出せてしまう、でも結果がヘン、で、compositionを指定してるっていうのだと、オリジナルのビデオにscaleが入ってる場合があったと思います (edited)
8:25 AM
asset sizeとnatural sizeが違うビデオですね
8:25 AM
有名なやつだと、Live Photo にくっついてるやつです
8:25 AM
あれは composition つけると export できない
Avatar
assetsizeとnaturalsizeが違うビデオ、がよく分かってないです。ちなみにベースとなるビデオは自前のコードで生成しています。(AVAssetWriter使用
8:34 AM
ありがとうございます 離席いたします
Avatar
だろしたらそこは問題ではないかも。サイズが違うってのは、録画時のピクセルと、表示する際のピクセルが一致してないビデオのことです。Live Photo についてるのは、高解像度な写真と同じサイズになるように実際の動画が引き延ばされるようなアファイン行列がヘッダーに入っていて、それをうまく処理できません。
Avatar
なるほど、Live Photoは元のアセットではないです
Avatar
calayer core animationをせっかく学んだのですが、解決しないようなら、一枚一枚画像を作ってそれを元にアニメーションにしようと思います
Avatar
@niw ググってもこのドキュメント一度もヒットしなかったのですが、この手のドキュメントをどうして知れたのですか。https://docs.huihoo.com/apple/wwdc/2011/session_415__working_with_media_in_av_foundation.pdf あと、PDFに書かれてるサンプルコードはどこかに公開されているのでしょうか? (edited)
Avatar
@niw 理屈がわからないのですが、CAKeyframeAnimationクラス等、アニメーションを司っているクラスのisRemovedOnCompletionをfalseに設定したところ、今のところアニメーションが有効に表現されるようになりました。 (edited)
Avatar
あー、それはそうしろと書いてありますね。removeOnCompletion が YES だと、CA的には終了時にモデルの値になるのですが、多分 composition はpresentationしかみないとかそういう制約があるのかも。
2:34 PM
ちなみに、サンプルコードは多分当時WWDCに参加した人のみがアクセスできたんだと思います。
2:34 PM
2011年とかだと、そういう運用だったとかだと思います。
Avatar
諸々ありがとうございました @niw
👍 1
Avatar
dicklessgreat 5/18/2020 2:24 PM
はじめまして。 Xcodeプロジェクトから出力した.frameworkをiOS開発のプロジェクトに埋め込むことができず困っています。 「iOSアプリ設計パターン」という本のサンプルコード をGitHubからダウンロードし、「GitHub.xcodeproj」を開き、特に設定は変更せずにそのままビルドしました。 出来上がった「Github.framework」をMedia⁩ ▸ ⁨アプリケーション⁩ ▸ ⁨Xcode⁩ ▸ ⁨Contents⁩ ▸ ⁨Developer⁩ ▸ ⁨Platforms⁩ ▸ ⁨iPhoneOS.platform⁩ ▸ ⁨Developer⁩ ▸ ⁨SDKs⁩ ▸ ⁨iPhoneOS.sdk⁩ ▸ ⁨System⁩ ▸ ⁨Library⁩ ▸ ⁨Frameworks⁩に配置しました。 このGithub.frameworkを使用したいプロジェクトをXcodeで開き、プロジェクトのGeneral → Framework, Libraries and Embedded codeにGithub.frameworkを追加しました ビルドすると、以下のエラーが出ました GitHub is not available when building for iOS Simulator. Consider using #if os(iOS) to conditionally import this framework when building for iOS. No such module 'GitHub' Xcodeを使ってライブラリをリンクさせたことがありませんので、何か基本的な事を間違えているのだと思いますが、どなたか教えていただけると幸いです。
swift 1
2:27 PM
すみません、一つ付け足しです。#import GitHub と書いた部分にエラーが出ました
Avatar
omochimetaru 5/18/2020 2:35 PM
1. システムのiPhoneOS.platform領域に配置しているのが変です。 取り込むフレームワークはシステムには入れずにアプリのプロジェクトのところに配置します。 ただ、これは慣習の話で、エラーとは関係ないかもしれません。 2.フレームワークがiPhone実機用にビルドされていて、 取り込んでいるアプリをiPhoneシミュレーター用にビルドしようとしていて、 そのエラーメッセージが出ているのかもしれません。 フレームワークが実機用にビルドされているときは、 アプリも実機ビルドしかできません。 フレームワークを実機とシミュレーターの両対応にする方法はありますが複雑で面倒なのでいったん省略。 (edited)
Avatar
dicklessgreat 5/18/2020 2:37 PM
ありがとうございます。確かにシミュレーターで動かそうとしていました。実機で確認してみます。
2:39 PM
実機でビルドしてみたところ、エラーが変化しました。 エラーがでた場所は同じです。 Could not find module 'GitHub' for target 'arm64-apple-ios'; found: x86_64-apple-ios-simulator, x86_64
2:39 PM
アプリのプロジェクトに配置して、シミュレーターで実行してみます。
Avatar
Kishikawa Katsumi 5/18/2020 2:42 PM
エラーの内容はおもめたさんが書いた通りなんですけど、このサンプルコードのGitHub.framework
Avatar
フレームワークを実機とシミュレータ両方に対応させるのは面倒なので、GitHub.xcodeprojをアプリのxcodeprojに追加するのが一番簡単な解決法だと思います。
Avatar
Kishikawa Katsumi 5/18/2020 2:45 PM
^  そうですね。このようにプロジェクトにプロジェクト参照の形で取り込んでしまうか、サンプルの14, 15にあるようにCocoaPodsを使うのが簡単だと思います。
Avatar
dicklessgreat 5/18/2020 2:47 PM
アプリのプロジェクトのところに配置してみましたが、結果はシミュレーターでも実機でも変わりませんでした。 kateinoigakukunさまのやり方もやってみます。プロジェクトにプロジェクトの追加・・・やった事ないですけど笑、ちょっと頑張ってみますw
Avatar
こんな感じの構成にすると Link Binary With Libraries セクションでGitHub.frameworkが選べるようになると思います。
Avatar
Kishikawa Katsumi 5/18/2020 2:49 PM
置き場所はどこでもいいです。プロジェクト外に配置すると、プロジェクトのディレクトリを移動したら参照先が辿れなくなるので、普通はプロジェクト内のディレクトリに置いて相対パスで参照する方が一般的、ということです。
Avatar
dicklessgreat 5/18/2020 2:51 PM
kateinoigakukunさま、ありがとうございます!やってみます。 Kishikawa Katsumiさま、わかりました。ありがとうございます。
👍 1
Avatar
omochimetaru 5/18/2020 2:51 PM
う〜んなんだろう。 フレームワークが実機armv7ターゲット限定でビルドされているけど、 アプリは実機arm64,シミュレーターx86_64でビルドしようとしている? あと、GitHubGithub で H の大文字小文字がときどきブレてるのが気になります。 家庭くんと岸川さんの書いてるように、 フレームワークファイルを手作りしないで済む方法(プロジェクト依存またはCocoaPods)のほうが無難です。
Avatar
dicklessgreat 5/18/2020 2:58 PM
omochimetaruさま すみません。ただの僕の書き間違いです。 サンプルコードから一切書き直していないので、そのままビルドは通る・・・はずなんですが・・・。
Avatar
dicklessgreat 5/18/2020 4:17 PM
すみません、格闘してみたのですが僕にはどうしてもビルドする事ができませんでした。サンプルコードが実際にどのように
4:19 PM
動いているのか確かめたいだけなので、.frameworkのビルドをiOSシミュレーター用に設定することはできませんか?もしできるなら、どこを設定すればいいのかも教えていただけませんか?
Avatar
Contribute to peaks-cc/iOS_architecture_samplecode development by creating an account on GitHub.
4:24 PM
これのことですかね
Avatar
dicklessgreat 5/18/2020 4:25 PM
はい、それです。 あ、ReadMe読んでなかった笑
Avatar
これのことなら、 GitHub.xcworkspace ひらけば何もせずにGitHub scheme一回ビルドしてから palygorundのやつ全部動くと思いますよ
Avatar
omochimetaru 5/18/2020 4:25 PM
Avatar
xcodeprojじゃだめ
Avatar
omochimetaru 5/18/2020 4:26 PM
↑のGeneric iOS Device のところをシミューレータにするとシミュレーター向けのビルドになります
Avatar
いま git clone --depth=1 https://github.com/peaks-cc/iOS_architecture_samplecode.git して試したので。macOS 11.15.4, Xcode 11.4.1。 (edited)
Avatar
dicklessgreat 5/18/2020 4:31 PM
niwさま すみませんちょっと今戦慄みたいなものが…笑全然知りませんでした笑
4:31 PM
使い方調べてみます。
Avatar
白いアイコンのほうです、青い方じゃなくて。
Avatar
dicklessgreat 5/18/2020 4:34 PM
はい、開くと…左側にプロジェクトの一覧が出てくるんですが…これをどう実行するんでしょうか?
Avatar
↑ omochimetaru さんのいうように、
4:34 PM
停止ボタンの右にあるやつが GitHub > Generic iOS Device
4:35 PM
になってたら、そこを iPhone 11 Pro Max とかに変えて
4:35 PM
いちど再生ボタンおして GitHub.framework をビルドしてください
Avatar
dicklessgreat 5/18/2020 4:35 PM
ああ!ビルドできました!! 後ろで他のXCodeプロジェクトが走っていました。
Avatar
で、そのあとは、左側の Playground の下にあるやつ
4:35 PM
いろいろ試してみてください
Avatar
dicklessgreat 5/18/2020 4:35 PM
それを消せばビルドできました。
Avatar
ああ、同時に同じものは二箇所でひらけません。
Avatar
dicklessgreat 5/18/2020 4:36 PM
なんですねぇ、それすら知りませんでした。 お騒がせいたしました。 (edited)
✅ 1
Avatar
dicklessgreat 5/18/2020 5:12 PM
xcworkspaceのことを知る以前にやっていた作業によってプロジェクトが壊れており、結局GitHubからもう一度ダウンロードし直してビルドし直せば問題なく実行できたという顛末でした。 上記作業のため少し遅くなりましたが、ご協力いただいた皆様、ありがとうございました。勉強を進めてみます。
💯 2
Avatar
delegateをイニシャライザでDIするのはアンチパターンですか
Avatar
omochimetaru 5/21/2020 4:35 AM
どういうコード?
Avatar
class SomeClass { private weak var delegate: SomeViewDelegate! init(delegate: SomeViewDelegate) { self.delegate = delegate } } (edited)
4:36 AM
エンター押しちゃった
4:37 AM
完了、こういう風にできるんだったらdelegateのしわすれぼうしできるかなあっておもいました
Avatar
omochimetaru 5/21/2020 4:38 AM
私は普通にやるよ。 Delegateよりクロージャのほうが良いと思うけど・・・ (edited)
Avatar
なるほど、(諸事情によりDelegate)
Avatar
omochimetaru 5/21/2020 4:38 AM
initなら忘れないというのも同意。 (edited)
Avatar
諸事情っていうのはだいたい説明コストですが(Delegateのほうが説明できる) (edited)
4:39 AM
ありがとうございます!
4:39 AM
クロージャの場合だとどんな感じになるんですかね
Avatar
omochimetaru 5/21/2020 4:40 AM
class SomeClass { init(cancelHandler: (() -> Void)?, submitHandler: (() -> Void)?) { } }
❤️ 1
Avatar
あ、そのままクロージャ渡すって感じですね
Avatar
イニシャライザで渡すのは別にアンチパターンだとは思わないですが、現実問題としてもし総合参照する設計なら、お互いのイニシャライザにお互いが必要になってきてデッドロックが発生する問題があるんですよね
Avatar
お互いのイニシャライザにお互いが必要
それは、それぞれのイニシャライザの引数にお互いを載せないとイカンくなるってことですか
Avatar
class Parent { var child: Child init(child: Child) } extension Parent: Autohority {} protocol Authority: AnyObject {} class Child { weak var autority: Authority? init(authority: Authoority) } こうかですね↑ (edited)
5:05 AM
Parent 作るのに Child 必要、でも Child を作るのに Authority として Parent が必要
Avatar
ふむう
Avatar
omochimetaru 5/21/2020 5:05 AM
循環関係はinitだけで作れないので、どっちかのプロパティをvarかつOptionalにして、 後から繋げる必要がありますね。
5:05 AM
それでも、initには引数として定義しておいて、 「循環で困ってから」プロパティでつなぐようにすれば
5:06 AM
そもそもつなぐことを忘れる心配は減らせると思う。
Avatar
そういうときは大体lazy varで解決できるのでは
Avatar
片方のTestable性が失われていますね
Avatar
そもそもdelegateパターンならほぼ確実にclassだし
Avatar
ん、なるほど
Avatar
omochimetaru 5/21/2020 5:06 AM
別にnilも許すように作っておけば壊れてはいないと思う。
5:07 AM
そもそもweakが出てくるからどっちかはOptionalになってそうだし。
Avatar
ですね
5:08 AM
class ViewController: SomeViewDelegate { private lazy var presenter = Presenter(delegate: self) } class Presenter { private weak var delegate: SomeViewDelegate! init(delegate: SomeViewDelegate) { self.delegate = delegate } } ちなこんなの作ってました ViewController の方のlazy varのprivateを外すといいのかな (edited)
5:10 AM
access level警察に怒られそうだけど
Avatar
omochimetaru 5/21/2020 5:10 AM
うん。
5:10 AM
別に、途中で変更できてもおかしくなくない?
Avatar
別に private つけて動くなら全部 private つけちゃえと思う
👍 1
Avatar
omochimetaru 5/21/2020 5:10 AM
「その時セットしてるオブジェクトに対して委譲される」という仕様なだけかと。
Avatar
presenter を替えてたらTestableにもできるから private はずしてもええかなっておもったです (edited)
Avatar
omochimetaru 5/21/2020 5:11 AM
button.tapHandler = { ... } を状態遷移に連動して書き換えるとかやらないこともないよ。
Avatar
なるなる
5:12 AM
それだったらdelegateよりも楽にできそう
Avatar
初めましてこんばんは。 RxSwiftを勉強中なのですが、書き方がわからなかったので教えて頂きたいです。 やりたい事は、2つの通信処理を直列に叩いて、それぞれのレスポンスの中の ある値に応じて処理をさせたいです。 具体的には、レスポンスはエラーが返ってこないことを前提として requestAを実行 -> responseAがエラーでなければrequestBを実行 -> ResponseA.isHoge==trueかつResponseB.str=="xxx"であれば処理をする 上記の流れで処理を行いたいです。ご教示頂けると助かります。 struct ResponseA { let isHoge:Bool } struct ResponseB { let str:String } func requestA() -> Observable<ResponseA> { //通信処理 } func requestB() -> Observable<ResponseB> { //通信処理 }
Avatar
omochimetaru 5/27/2020 1:54 PM
class ViewController: UIViewController { let disposeBag: DisposeBag = DisposeBag() @IBAction func onButton() { requestA().flatMap({ (responseA) -> Observable<Void> in requestB().map({ (responseB) -> Void in if responseA.isHoge, responseB.str == "xxx" { accept(responseA, responseB) } return () }) }).disposed(by: disposeBag) } }
1:55 PM
こんな感じです。
Avatar
早速ご回答頂きありがとうございます! rx以前の話でしたら恐縮なんですが1点質問させて下さい。 accept(responseA, responseB)の行は何をしてるんでしょうか・・・? ここにやりたい処理を実装するって意味合いで合ってますか?
Avatar
omochimetaru 5/27/2020 2:02 PM
はい。
であれば処理をする
↑の部分が func accept(responseA: ResponseA, responseB: ResponseB) { ... } だったとしたら、という擬似コードでした。
Avatar
納得しました! 早速試してみます。非常に助かりました!
👍 1
Avatar
教えていただきたいのですが、 struct DirectProduct<Left: Sequence, Right: Sequence> { let left: Left let right: Right } このようなstructをSequenceにしたいと思うのですが、この時Left, Rightの型によってIterator#next()の実装を変えたいと思うのですが、これは可能でしょうか? 考えているのはLeft,RightがCollectionの時とLeft,RightがCollectionでIndex == Intの時に実装を切り替えることです。 いろいろ試しているのですがうまくいきません。 方法があれば教えてください。
Avatar
こんな感じのことをやりたいですか? struct DirectProduct<Iterator, Element, Left: Sequence, Right: Sequence> where Left.Element == Element, Right.Element == Element, Left.Iterator == Iterator, Right.Iterator == Iterator { let left: Left let right: Right } extension DirectProduct: Sequence where Left: Collection, Right: Collection { func makeIterator() -> Iterator { if left.startIndex is Int, right.startIndex is Int { // return iterator } else { // return another iterator } } }
Avatar
試してみましたが extension ではできなさそうですね。 @swift-5.2.5 struct DirectProduct<Left: Sequence, Right: Sequence> { let left: Left let right: Right init(_ left: Left, _ right: Right) { self.left = left self.right = right } } extension DirectProduct: Sequence { func makeIterator() -> Iterator { print("makeIterator A") return Iterator(left, right) } class Iterator: IteratorProtocol { fileprivate let left: Left fileprivate let right: Right init(_ left: Left, _ right: Right) { self.left = left self.right = right } func next() -> (Left.Element, Right.Element)? { nil } } } extension DirectProduct where Left: Collection, Right: Collection, Left.Index == Int, Right.Index == Int { func makeIterator() -> Iterator { print("makeIterator B") return Iterator2(left, right) } class Iterator2: Iterator { override init(_ left: Left, _ right: Right) { super.init(left, right) } override func next() -> (Left.Element, Right.Element)? { nil } } } do { let p = DirectProduct([2, 3, 5], ["X", "Y", "Z"] as Set<String>) for (_, _) in p {} _ = p.makeIterator() } print() do { let p = DirectProduct([2, 3, 5], ["X", "Y", "Z"]) for (_, _) in p {} _ = p.makeIterator() }
Avatar
makeIterator A makeIterator A makeIterator A makeIterator B
Avatar
Collection 限定なら lovee さんの戦略は良さそうな気が。
Avatar
あー、分岐した後がうまくいかない?
Avatar
お、いけるかも?
3:00 AM
@swift-5.2.5 struct DirectProduct<Left: Collection, Right: Collection> { let left: Left let right: Right let iteratorType: DirectProductIterator<Left, Right>.Type init(_ left: Left, _ right: Right) { self.left = left self.right = right iteratorType = DirectProductIterator.self } } extension DirectProduct where Left.Index == Int, Right.Index == Int { init(_ left: Left, _ right: Right) { self.left = left self.right = right iteratorType = DirectProductIterator2.self } } extension DirectProduct: Sequence { func makeIterator() -> DirectProductIterator<Left, Right> { iteratorType.init(left, right) } } class DirectProductIterator<Left: Collection, Right: Collection>: IteratorProtocol { fileprivate let left: Left fileprivate let right: Right required init(_ left: Left, _ right: Right) { self.left = left self.right = right } func next() -> (Left.Element, Right.Element)? { print("DirectProductIterator") return nil } } class DirectProductIterator2<Left: Collection, Right: Collection>: DirectProductIterator<Left, Right> where Left.Index == Int, Right.Index == Int { required init(_ left: Left, _ right: Right) { super.init(left, right) } override func next() -> (Left.Element, Right.Element)? { print("DirectProductIterator2") return nil } } do { let p = DirectProduct([2, 3, 5], ["X", "Y", "Z"] as Set<String>) for (_, _) in p {} } print() do { let p = DirectProduct([2, 3, 5], ["X", "Y", "Z"]) for (_, _) in p {} }
Avatar
DirectProductIterator DirectProductIterator2
Avatar
@masakihori ↑これでどうでしょう? for では無理だったのでイニシャライザで型情報を埋め込みました。
Avatar
Iterator も実装してみた例です。 https://gist.github.com/koher/550ea1e9625e66758bac85eb5063196f
3:36 AM
スーパークラスにサブクラスでは不要なプロパティがあるのと、イニシャライザで makeIterator を無駄に呼んでるのが気持ち悪いですが・・・。
3:37 AM
共通の抽象スーパークラスを作ればいいのか。
Avatar
大分きれいになった気がする。
3:51 AM
こういうイテレータの実装だと LeftRight に参照型のコレクション渡されると壊れるけど。
Avatar
あー、説明がダメでした
4:14 AM
LeftとRightが両方Sequenceの実装に加えて両方がCollectionの時の実装を別に設けたかったんです
Avatar
↑の方法なら SequenceCollection でもいける気がしますね。
4:18 AM
SequenceIterator1Collection where Element == IntIterator2 が返されるようにしました。 https://gist.github.com/koher/550ea1e9625e66758bac85eb5063196f
Avatar
なるほど、分かりました
4:22 AM
Iterator.Typeをもってinitもoverrideしちゃうのか。なるほど
4:23 AM
ありがとうございます
🙂 1
4:29 AM
structの名前しか書いてないのに実装が僕が書いたものとほぼほぼ同じなのでちょっと笑いましたw
Avatar
多分こういうことがやりたいのかなとw
Avatar
SwiftUIを勉強中なのですが、「Unable to infer complex closure return type; add explicit type to disambiguate」というエラー文が解決できずに躓いています。このエラー文はどういったときに出るものなのか、教えていただけると助かります。
11:14 AM
Google翻訳で直訳すると「複雑なクロージャーの戻り値の型を推測できません。 明確にするために明示的な型を追加する」となるようです。
Avatar
Kishikawa Katsumi 5/31/2020 11:30 AM
コードが複雑すぎてコンパイルがいつまで経っても終わらないからコンパイラが途中で処理を中止してるんですね。 複雑すぎて、といっても見た目にはさほど複雑ではないコードでも起こるので大変です。 典型的には、クロージャを入れ子にしたり、Modifierをドットで繋いでメソッドチェーンをすると途中経過の戻り値や引数の型の関係をコンパイラがうまく推測できずに失敗するという事象です。
11:31 AM
解決するにはほとんどの場合、入れ子やメソッドチェーン(ドットで繋いで続けてメソッドを呼び出す)を分解してコンパイラに一つ一つの簡単なものとして与えるようにします。
11:32 AM
例でいうと import SwiftUI struct ContentView: View { var body: some View { VStack { Text("Hello SwiftUI Playground!") .font(.largeTitle) .foregroundColor(.blue) .padding() Button(action: {}) { HStack { Image(systemName: "suit.heart.fill") .foregroundColor(.red) Text("Let's Get Started!") .font(.headline) .foregroundColor(.white) } .padding(12) .background(Color.orange) .cornerRadius(8) } } } }
11:33 AM
^ こういう元のコードがあるとして、これは1つの大きなクロージャで中のクロージャは全部外側のクロージャの入れ子になっています。これがもっと多くの入れ子を含んだりするとそのエラーが起こります。
11:35 AM
なのでそうなったら、 import SwiftUI struct ContentView: View { var body: some View { let button = Button(action: {}) { HStack { Image(systemName: "suit.heart.fill") .foregroundColor(.red) Text("Let's Get Started!") .font(.headline) .foregroundColor(.white) } .padding(12) .background(Color.orange) .cornerRadius(8) } let text = Text("Hello SwiftUI Playground!") .font(.largeTitle) .foregroundColor(.blue) .padding() return VStack { button text } } } このように入れ子になっているクロージャを取り出していったん変数に格納してそれを同じように最後に組み合わせるようにします。 こうすると、もともと入れ子になっていた1つ1つのクロージャは簡単なクロージャでいったん型の推測が可能になるのでだいたい問題が解決します。無理な場合はもっと細かく分解します。
11:37 AM
SwiftUIでありがちなパターンだと、そのエラー以外でもどうせ10個以上のクロージャを入れ子に持つことはできないので、ちょっとした部品を作るだけでもすぐに制限に引っかかります。 なので上記の例にあげたくらいのコードになったらカスタムビューとしてコードを切り出すほうがうまくいきます。 ちょっとひとかたまりのコードができたら再利用するかどうかはあまり気にせず名前をつけてカスタムビューにしてしまうのがいいです。
Avatar
回答ありがとうございます!カスタムビューで分解したら、エラーは解決しました!ありがとうございます!
Avatar
初めまして。 printでDebug consoleに表示させようとしても何も表示されません。 表示させる方法を教えください。 お願いします。
10:04 PM
Avatar
omochimetaru 6/9/2020 10:06 PM
プレビューではなくアプリとして実行した場合は表示されますか? Xcodeの左上にある右三角のボタンです
Avatar
表示されました。
Avatar
omochimetaru 6/9/2020 10:09 PM
それならコードは正しそうです。 Preview Canvasにはデバッガがアタッチされないために表示されない、という仕様だと思います。詳しくないですが。 (edited)
Avatar
仕様ですか。 朝はやくにありがとうございました! (edited)
Avatar
すみません Xcodeのストーリーボードでエディタモード起動したんですが ViewController.swift とは違うのが出て ファイル検索かけても ViewController.swift がなかったのですがどうすれば良いですか;
1:09 PM
説明にはViewController.swiftが出ているんですが;; (edited)
Avatar
ここ右クリックするとデバッガにアタッチできるかと思います @ryota2357
Avatar
@kenmaz. デバッガにアタッチできて、ログも表示されました。ありがとうございます!
👀 1
👍 1
Avatar
Kishikawa Katsumi 6/14/2020 12:49 AM
@hogehoge もう少しそこに至るまでの手順を具体的に何をしたか、というのを教えてください。あと、現在の状況がどうなってるかをスクリーンショットで共有してもらえるとわかりやすいかも。
Avatar
アドバイス頂きありがとうございます ストーリーボードでボタン等のパーツを配置した後、 ViewController.swift にそれを関連付けしたく探したのですが ViewController.swift が見つからずいろいろ調べてました 先程、言語をSwiftUIからStoryboardに変更したところ自己解決できました ありがとうございました (edited)
Avatar
Kishikawa Katsumi 6/14/2020 12:57 AM
なるほど。SwiftUIを選ぶとデフォルトのコードが変わるのでViewController.swiftはセットアップ時に作られない、ってことですね。
Avatar
参考になります! (edited)
Avatar
こんばんは 座標の取得方法について質問させて下さい やりたいことは、指定したy座標の位置まで UIScrollViewを縦スクロールさせたくて、スクロール方法は scrollView.setContentOffset にスクロールさせたい 座標をCGPointで渡せばいいことまではわかったのですが xib内のUIコンポーネントの座標を渡してみたところ 常にその座標が(x:0.0,y:0.0)になってしまい 自分が想定しているところまでスクロール出来ず困っています 具体的に、スクリーンショットの Second Input Viewの黒字のタイトルと書かれている UILabelの上までスクロールさせたいのですが この座標を取得するにはどうしたら宜しいでしょうか? 黄色塗りされている部分がxibとなっております。 ご教示頂けると幸いです。宜しくお願いします。 (edited)
Avatar
Kishikawa Katsumi 6/14/2020 11:37 AM
let frame = secondInputView.titleLabel.convert(secondInputView.titleLabel.bounds, to: scrollView) print(frame) ^ このコードを追加して値を調べてみてください。
11:39 AM
要は titleLabel.frame はSuper Viewからの相対座標なので、secondInputViewから見た座標になります。 Scroll Viewでどの位置か、というのはScrollViewから見た座標に変換する必要があります。
11:39 AM
というのをやってるつもりなのが上のコードです。
11:39 AM
合ってるかどうか微妙なので実行した結果を教えてください。
Avatar
早速ご回答頂きありがとうございます! 出力は(20.0, 174.66666666666669, 63.66666666666666, 20.333333333333343) になり frame.origin.y を渡してあげたら、想定した位置までスクロールしました! 調べた中でconvertは出てきたんですけど、ややこしくていまいち理解が出来ずに 避けてしまったので、もう一度ドキュメントをよく見てみます。 非常に助かりましたありがとうございました! (edited)
Avatar
質問させてください! NewsPicksのようなタブをUIPageViewControllerで実現していて、viewcontrollersのUICollectionViewを持つUIViewControllerが複数あります。 そのうちの初期で表示されるVCのUICollectionViewのセルとして、横スクロールできるカルーセルのUICollectionViewを表示させたのですが、そのカルーセルをスクロールしようとするとUIPageViewControllerがスクロールされてしまいます。 また、一度UIPageViewControllerがスクロールされたあと、再度カルーセルをスクロールするとスクロールが可能になります。初期状態でもカルーセルをスクロール可能にする方法を知りたいです。 よろしくお願いいたします🙇‍♂️
Avatar
UIGestureRecognizerdelegate設定したいいんじゃないでしょうか? (edited)
3:31 AM
(これは逆もある)
Avatar
ありがとうございます! これは、カルーセルのUICollectionViewのGestureを制御するということですか?
Avatar
そっちを勝たせないといけないので
3:35 AM
そう言う感じにしないといけないんだと思います。
3:36 AM
UICollectionViewは(UITableViewとかも)コンテンツへのタップデフォルトでは遅らせるようになっていて(だからスクロール中にボタンとかに反応せずにスクロールがスムーズにできる) (edited)
3:37 AM
逆にそれが望ましくないケース、たとえば今回のような、コンテンツ側でジェスチャーを認識しないといけない場合などで支障が出ます。 (edited)
Avatar
こんにちは!1点質問させて下さい ViewController A → ViewController Bに画面遷移をする際に modalTransitionStylecrossDissolve を指定してpresent で遷移したときの フワッと遷移する際の、durationの値を変更することは可能でしょうか? また不可能な場合、代替策としてどのような実装がありますでしょうか・・・? ご教示頂けると幸いです。
Avatar
Kishikawa Katsumi 6/15/2020 5:26 AM
durationの変更はできないです。 viewController.modalPresentationStyle = .custom viewController.transitioningDelegate = self としてカスタムトランジションを実装するのが一般的な方法です。 クロスディゾルブくらいなら遷移元と先でalphaを1=>0/0=>1するだけなので実装も難しくないです。
Avatar
ご回答頂きありがとうございます カスタムトランジションですね。実装したことがないので 調べてチャレンジしてみます。詰まったらまた質問させて下さい・・・!
Avatar
@niw ありがとうございました。やってみます!
💯 1
Avatar
@飯塚 できる
7:08 AM
けど、だいぶキモい方法になります
👀 1
7:09 AM
@Kishikawa Katsumi さんの回答は多分正攻法として正しい
7:10 AM
端的に言うと、CATransactionで時間を遅らせます
7:10 AM
これは interactive transitionが内部でやってる実装で
7:11 AM
transactionの時間を進めたり戻したりしてトランジションをコントロールできます
7:12 AM
だいぶアレなので、まあ、自分でtransitionアニメーションを作った方が安心感はあります
7:14 AM
CATransaction.setAnimationDuration()あたりでまずは試してみると雰囲気わかるかも
Avatar
Kishikawa Katsumi 6/15/2020 7:22 AM
なるほど。たしかにそのあたりの方法でいうと、layer.speedを変えるという手もありますね。
Avatar
それですねー、それがまさにinteractive transitionがやってるやつ (edited)
7:26 AM
まああんまりおすすめはできないけれど、CoreAnimationを愛せれば
7:27 AM
これ系の手法でほとんどを手中に納められるので
7:27 AM
なかなか良いかなあと言う感じ
7:27 AM
ただし、UIViewのアニメーションは厄介なのでそれとの兼ね合いはなかなかキビしい
Avatar
Kishikawa Katsumi 6/15/2020 7:28 AM
そうか、interactive transitionはスピードゼロでアニメーションをスタートして時間を外から割合で与えるのか
Avatar
そうです
7:29 AM
いやそうでなくてもいいんだけど、implicitなのはそういう実装になってる
Avatar
こんばんはー githubのalarm-ios-swift(https://github.com/natsu1211/Alarm-ios-swift) を使って開発をしています。 しかし、ios13以降で設定したアラームのtableviewが反映されず困っています。 tableView.reloadDataをアラームのsave処理の場面で試したり、画面の再描画などを試しましたが結果は変わりませんでした。 同コードを使ったことがある方など、ご教授いただけるととても助かります。よろしくお願いします。
3:20 PM
ios12では通常通り動作します。
Avatar
Masashi Aso 7/1/2020 1:09 AM
iOS 13以降のSheetに関する問題に見えます。去年の https://developer.apple.com/wwdc19/224 あたりが参考になるかと。
iOS 13 combines powerful new multitasking and productivity technologies with a refreshed look and feel for all applications. Familiarize...
👀 1
👍 1
Avatar
https://qiita.com/lanches_hiromi/items/39c5d390b45943c0b1d8 モーダルが閉じたときに遷移元のviewWillAppear、viewDidAppearが呼ばれないのが原因ですかね....?
はじめに iOS13からシートモーダル表示(セミモーダル表示)がデフォルトスタイルになりました。 iOS13で新たなモーダルスタイルが登場したのをきっかけにモーダル画面について調べたことを 記載したいと思います。 そもそもモ...
Avatar
presentationをfullscreenにしたらいけました! ありがとうございます!
👍 1
Avatar
こんばんは textField及びtextViewを使用した際に、入力時に 入力欄がキーボードに被ってしまう際の、回避方法について ベストプラクティスをご教示頂きたく質問させて下さい。 回避する方法自体は、調べればいくつかパターンが出てきて ScrollViewを敷いてズラす方法や、キーボードの高さを計算して画面自体を上にズラす方法など様々あるのですが 画像のような、スクロールを前提としていなくて画面下部に textField及びtextViewが配置されているような画面を考えたときに、どのようにキーボードが隠れて入力できなくなってしまう 現象を回避するのが良いのでしょうか?ご教示頂けると幸いです。 (edited)
Avatar
ScrollView使うのが楽だと思います
Avatar
早速ご回答ありがとうございます 例えば縦長にスクロールを前提にしてない画面でも キーボードが被るようなレイアウトであれば下にScrollViewを敷いておくってことでしょうか?
Avatar
ちゃんと説明すると結構な長文になるんですが、幾つかの理由からキーボードの有無に関わらず「例え現段階ではScrollしない画面でもUIScrollViewを仕込んでおく」というのは有効なプラクティスだと考えています。 理由について代表的なものは以下のものでしょうか。 1. 端末サイズが多岐に渡るので、フルフルに使ったデザインでは4インチの端末でスクロールが必要になるケースが多い 2. スクロール無しでDynamicTypeに対応することが困難である 3. SafeAreaの取り扱いは手動でAutolayoutを設定するよりもcontentInsetAdjustmentBehavior = automatic, alwaysBouncesVertical = trueの組み合わせに頼ったほうが遥かに楽である もちろん、フルスクラッチのデザインでSafeAreaもDynamicTypeも関係ない!ということもありますので、100%適応可能である、というわけでは無いです。
Avatar
僕は使ったことがないのでよくわかってないですが、↓多分そういう目的で使えるライブラリなんじゃないかと思ってます。 https://github.com/niw/KeyboardGuide
A modern, real iOS keyboard system notifications handler framework that Just Works. - niw/KeyboardGuide
😆 1
Avatar
@tarunon なるほどですねScrollViewを敷いておくことのメリットはすごく納得できました! 具体的に、キーボードが出現時、入力部分に被らないようにスクロールさせるの部分は フォーカスされてるtextField及びtextViewの座標とキーボードの高さから どれくらいスクロールさせればいいかを計算して、計算した分scrollViewをスクロールさせるって流れになる認識であってますか・・・?
1:09 PM
@koher コメントありがとうございます! こちらは拝見させて頂いたことあります!ライブラリを使わずに 自分で実装してみようと思ったのですが、いざ実装してみると様々な実装方法があり ベストプラクティス的な物があれば知りたいなと思い質問させて頂いた次第です
🙂 1
Avatar
実際にはKeyboardの表示された領域を計算してその分contentInsetに足す、という作業になるんですが、これは結構大変なので、koherさんの上げてくれたライブラリを使うのが楽かなぁと思います。
1:17 PM
ちなみに、UITableViewController(UICollectionViewControllerもだったかな?)はキーボードに対するinsetを付与する機能が含まれているので、特段何もしなくても期待通りに動作します
Avatar
思った以上に複雑なのですね・・・。 使わせて頂くことを検討してみます!ご回答頂きありがとうございました!
Avatar
それつくったひとですが
3:36 AM
キーボードを正しく扱うのはすごい大変です
3:37 AM
A modern, real iOS keyboard system notifications handler framework that Just Works. - niw/KeyboardGuide
3:38 AM
ベストプラクティスは、これを使うことですね...
👍 2
3:39 AM
という冗談はさておき、状況によるとしか言えないのでなんともです。ScrollViewのinsetを変えるとかが基本ですが、そのinset画面にたいして絶対値になるので、正しく算出するのはかなり大変です。
Avatar
今や Xcode からポチポチっとやれば SwiftPM でライブラリ入れられますから、実務的にはほんとにライブラリ使うのベストプラクティスだと思うんですよね。
Avatar
引き続きalarm-ios-swiftで開発をしていますが、アラームにライブラリの曲を使用する機能の開発で、tableviewに曲が追加されず困っています。 以下の二つを参考にしました。 https://stackoverflow.com/questions/49384705/mpmediapickercontroller-closes-after-startup-swift https://chat.stackoverflow.com/rooms/167182/discussion-between-ppl-and-b2fq
When I click on the cell to open the MPMediaPickerController it opens when it starts up. class MediaViewController: UITableViewController, MPMediaPickerControllerDelegate override func tableView(_
Avatar
コードは以下のようになっています。 MediaViewController.swift import UIKit import MediaPlayer var printnumber: Int = 1 class MediaViewController: UITableViewController, MPMediaPickerControllerDelegate { fileprivate let numberOfRingtones = 3 var mediaItem: MPMediaItem? var mediaLabel: String! var mediaID: String! override func viewDidLoad() { super.viewDidLoad() } override func viewWillDisappear(_ animated: Bool) { //performSegue(withIdentifier: Id.soundUnwindIdentifier, sender: self) } ... func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection:MPMediaItemCollection) -> Void { if !mediaItemCollection.items.isEmpty { let aMediaItem = mediaItemCollection.items[0] self.mediaItem = aMediaItem mediaID = (self.mediaItem?.value(forProperty: MPMediaItemPropertyPersistentID)) as? String self.dismiss(animated: true, completion: nil) } } func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) { self.dismiss(animated: true, completion: nil) } } AlarmAddEditViewController.swift @IBAction func unwindFromMediaView(_ segue: UIStoryboardSegue) { let src = segue.source as! MediaViewController segueInfo.mediaLabel = src.mediaLabel segueInfo.mediaID = src.mediaID } (edited)
Avatar
んーこれだけではなんとも... UITabelViewDataSouce で調べてみてください
12:08 PM
あと、なんというか、参考にするのは apple.com が良いと思います。stackoverflow は個人の日記みたいなものなんで... ちょっと嘘が多い。 (edited)
👀 1
👍 1
Avatar
stackoverflowの内容が 「pick a song 押したけどUnbalanced calls to begin/end appearance transitions forが出てきて叶わん、なんとかしてくれ」 「 override func viewWillDisappear(_ animated: Bool) { performSegue(withIdentifier: Id.soundUnwindIdentifier, sender: self)消したら?」 「performSegue(withIdentifier: Id.soundUnwindIdentifier, sender: self)コメントしたらできたわ。ありがとう」 みたいな感じでした。 コメント化したらtableviewに曲が追加されず、func mediaPickerにperformSegue(withIdentifier: Id.soundUnwindIdentifier, sender: self)を追加したら func unwindFromMediaViewのsegueInfo.mediaID = src.mediaIDにnilが出てきた...という感じですね
12:22 PM
もう少し調べてみます
Avatar
MediaViewControllerUITableViewControllerとして作られているので、それ自身がUITableViewDataSourceになっています。
👀 1
12:26 PM
使い方はここの載っていますが、この辺は実装されていると考えていいでしょうか?
12:30 PM
MPMedoaPickerControllerで選択されたMPMediaItemを誰かがUITabelViewCellにしないと結果として表示されません...
👀 1
12:31 PM
その部分が ... で省略されている部分にあるのであればごめんなさい、この指摘は関係がないかも。 (edited)
Avatar
tableviewは大体実装されています mediaviewcontrollerがこんな感じです
12:35 PM
mediaviewcontroller全体がこんな感じになります
12:39 PM
MPMedoaPickerControllerで選択されたMPMediaItemを誰かがUITabelViewCellにしないと結果として表示されません...
@niw 多分それが出来てないかもですね....!
12:41 PM
mediaidをUITabelViewCellにすればいいのかな? (edited)
Avatar
そうですね。tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCellで、なにかしらする必要があります。
👍 1
12:44 PM
この中で表示したいものをcellに設定する感じかと思います。
Avatar
ありがとうございます、やってみますね!
Avatar
titleとかですね。
12:47 PM
mediaIDは多分なんか識別用の内部的なヤツで表示しても意味ないかも。 (edited)
Avatar
var title: String?って override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{} の中でどう書けばいいですかね....? var songTitle: String songTitle = mediaItem!.value( forProperty: MPMediaItemPropertyTitle ) as String とか試してるんですけどうまくいかなくて... (edited)
Avatar
cell.titleLabel.text = mediaItem.title じゃダメですかね
Avatar
こんばんは 私はcallkitを用いて音声通話アプリを作っています。 その上で原因がつかめない現象に遭遇してまして質問させていただきます。 まず、遭遇している原因までの実行手順を説明させてください。 • 実行手順 1, iPhoneの電源をoffにする 2, iPhoneの電源をonにする 3, 端末がオンラインになったタイミングで別端末から電源on/offにした端末に対して発信処理をします。 4, 着信側の端末がvoip pushを受信して Callkit UI(端末非ロックバージョン)を表示します。 5, 拒否ボタンをタップします。 ここまでが実行手順です。 その上で その拒否ボタンタップ時に実行されるデリゲートメソッド内で URLSessionを用いてAPI通信して いるのですがrequestが必ずタイムアウトしてしまいます。 電源onにしてからの初回起動直後に起きます。それ以外では起きません。 また、iOS12で同様の操作手順を実行しましたがrequestがタイムアウトになることはありませんでした。 OS差があることまでは特定出来ているのですが原因が掴みきれていません。 iOS13.5.1とiOS12.3ではURLSession周りでの仕様変更などありましたでしょうか?
Avatar
iOS 13では必ずvoip pushは同期的にreportNewIncomingCallなどを呼び出しコール画面を表示するのみに使いそれ以外の用途に使用できなくなっています 日本語の資料としてはここに詳しく書かれていました(Appleの公式ドキュメントもqiitaの方を参考にしてみてください https://qiita.com/sunskysoft/items/34665541d9bec438ee36
注意:この記事はAppleのドキュメントを参照して書きました。実際に実装していないので間違いがあるかもしれません。 VoIP Push は CallKit とともに!(iOS13) iOS 13 SDK でビルドしたアプリを i...
2:48 PM
なんでこうした措置がとたれたかはここに書いてあります https://japanese.engadget.com/2019/08/06/ios-13-voip-whatsapp-fb-messenger/
iOS 13では、アプリによるバックグラウンドでのVoIP(Vioce over Internet Protocol)が使えなくなります。たとえばこの機能を利用しているFacebookのMessengerやWhatsAppといったアプリに影響が出ることが予想されます。 米ニュースメディアThe Informati...
Avatar
ありがとうございます。 ですが、本件はvoip pushは正常に受信できており、reportNewIncomingCallをコールし、コール画面(callkit ui)を表示したあとに起きる現象についての質問です。
Avatar
なるほど。拒否ボタンを押した時の挙動なのですね。 iOS 12, 13のCallKit周りの変更だとvoip pushでバックグラウンド周りの規制が強くなったのでその影響かと思いましたが違うかもですね。 電源on直後かそうでないかではなく、フォアグラウンドでのvoip受けた時はAPI通信できてバックグラウンドでvoip push受けた時はAPI通信できないのであればドキュメント通りな気はします。 自分が開発した時はバックグラウンドでvoip push受けた時に裏でアプリが生きている状態か死んでいる状態かで違ってくるとかあった気もしなくもないですが具体的なことは忘れてしましました 🙇‍♂️ (edited)
Avatar
電源on直後(ネットワークは繋がってる状態)のアプリがkill status時にこの問題が起きておりまして、、 それ以降のkill status, foreground,backgroundでは再現しなくて悩んでおります。 😓
Avatar
Deleted User 7/9/2020 6:42 AM
質問です。 EnvironmentObjectで作成した配列をForm内のPickerで選択できるようにしたいのですが、動作がうまくいきません。 シミュレータで動かそうとすると、エラーが起きてしまいます。 エラー文 '''Thread 1: Fatal error: No ObservableObject of type HistoryEntity found. A View.environmentObject(_:) for HistoryEntity may be missing as an ancestor of this view.''' コード //Data.swift import SwiftUI import Combine class HistoryEntity: ObservableObject{ @Published var UserName:[String] = [] } //AddView.swift @EnvironmentObject var histroy: HistoryEntity var body: some View { NavigationView { Form { Picker(selection: $Selection, label: Text("name")) { ForEach(0..<histroy.UserName.count){ Text(self.histroy.UserName[$0]) } } } } (edited)
Avatar
Kishikawa Katsumi 7/9/2020 6:45 AM
histroy: HistoryEntity を渡してないと思います。 使ってる方のコード、SceneDelegate.swiftのコードを載せてください。
Avatar
Deleted User 7/9/2020 6:46 AM
let contentView = ContentView().environmentObject(HistoryEntity())
6:46 AM
書き忘れてました。。
6:49 AM
すみません。「使っている方のコード」というのは、どういった意味でしょうか。
Avatar
Kishikawa Katsumi 7/9/2020 6:50 AM
let contentView = ContentView().environmentObject(HistoryEntity())
この部分の話です。 ContentViewはどれですか?
Avatar
Deleted User 7/9/2020 7:00 AM
ContentViewの2つ下の階層にAddViewを作成しました (edited)
Avatar
Kishikawa Katsumi 7/9/2020 7:00 AM
コードを載せてください。
Avatar
omochimetaru 7/9/2020 7:06 AM
シミュレータで動かそうとすると
Preview Canvasの事?それともiPhone simulatorの事?実機では動くんですか?
(edited)
Avatar
Deleted User 7/9/2020 7:09 AM
//ContentView.seift struct ContentView: View { @EnvironmentObject var histroy: HistoryEntity var body: some View { NavigationView { List { ForEach(histroy.UserName, id: \.self){ user in NavigationLink(destination: HistoryView(name: user)){ Text(user) } } } } //HistroyView.swift struct HistoryView: View { @State private var isShowingSheet: Bool = false var name: String = "" var body: some View { List { VStack { Text("") } NavigationLink(destination: DetailsView()) { HistroyRowView() } .navigationBarTitle(name) .navigationBarItems(trailing:HStack { Button(action: { self.isShowingSheet = true }) { Text("") } .sheet(isPresented: $isShowingSheet){ AddView(isShowingSheet: self.$isShowingSheet) } } } }
7:10 AM
iPhone simulatorの方です
7:10 AM
実機では試せていません。
Avatar
omochimetaru 7/9/2020 7:13 AM
なるほど。Preview用のコードの方で.environmentObjectを忘れてるのかなと予想したんですが違いました。一見正しそうです、どこが間違っているのかわからなかった。
Avatar
Deleted User 7/9/2020 7:18 AM
「Form内でPickerを使うと画面遷移されるので、その遷移先ではEnvironmentObjectの値を取得できない」みたいなことって起きますか?
Avatar
Kishikawa Katsumi 7/9/2020 7:18 AM
Thread 1: Fatal error: No ObservableObject of type HistoryEntity found. A View.environmentObject(_:) for HistoryEntity may be missing as an ancestor of this view.''' これはどこで起こってるんですか?
Avatar
Deleted User 7/9/2020 7:19 AM
ForEach(0..<histroy.UserName.count){ ←この行に表示されています (edited)
Avatar
Kishikawa Katsumi 7/9/2020 7:25 AM
起動して初期表示はうまくいくけど、何か操作をしてそのあとでクラッシュする、ということで合ってますか?
Avatar
Deleted User 7/9/2020 7:29 AM
初期起動は問題なく、このボタンを押してAddViewを表示しようとするとクラッシュします Button(action: { self.isShowingSheet = true })
Avatar
Kishikawa Katsumi 7/9/2020 7:34 AM
AddViewにenvironmentObjectを渡してないからじゃないですか?
Avatar
Deleted User 7/9/2020 7:35 AM
//AddView.swift @EnvironmentObject var histroy: HistoryEntity これでは渡せていないということでしょうか
Avatar
Kishikawa Katsumi 7/9/2020 7:38 AM
それはEnvironmentObjectを受け取れるという意味ですね。 渡す、というのは let contentView = ContentView().environmentObject(HistoryEntity()) ContentViewに渡してるようなこういうenvironmentObjectのModifierを使ってる部分です。
Avatar
EnvironmentObject って自動的に共有されるんじゃないですっけ?
7:46 AM
SwiftUI was built from the ground up to let you write beautiful and correct user interfaces free of inconsistencies. Learn how to connect...
7:47 AM
(僕はいつも @ObservedObject 使ってるのであまり自信ないですが)
7:49 AM
もし実行可能な状態でコードを共有可能なら、共有してもらった方が早そうな気がします( .xcodeproj 含めて丸ごと GitHub に push とか)。
Avatar
Deleted User 7/9/2020 8:20 AM
https://github.com/KentaMaeda0916/FormInPicker GitHubを初めて使うので正しくできているかわかりませんが、これでいいのでしょうか。
EnvironmentObjectで作成した配列をForm内のPickerで選択できるようにしたいのですが、動作がうまくいきません。 - KentaMaeda0916/FormInPicker
Avatar
I'm building an app with SwiftUI. When I was trying to display a sheet (previously Modal), this error message appears: Thread 1: Fatal error: No observable object of type
8:22 AM
sheetはEnvironmentObjectを共有していないみたいですね。
8:23 AM
これが仕様なのかバグなのかわかりませんが…
Avatar
Kishikawa Katsumi 7/9/2020 8:26 AM
AddView(isShowingSheet: self.$isShowingSheet).environmentObject(self.histroy) なのでこう書くとまあ解決します。 サブビューなら伝播してくれるんですけど、sheetは別のビュー階層扱いなんでしょうね。
Avatar
ほんとですね。こちらでも同様でした。
8:30 AM
NavigationLink は大丈夫なのに .sheet はダメなんですね・・・。
Avatar
Deleted User 7/9/2020 8:32 AM
``` AddView(isShowingSheet: self.$isShowingSheet).environmentObject(self.histroy) ``` なのでこう書くとまあ解決します。 サブビューなら伝播してくれるんですけど、sheetは別のビュー階層扱いなんでしょうね。
@Kishikawa Katsumi
8:32 AM
これを追加したら解決しました!
8:32 AM
本当にありがとうございました!
🙌 1
Avatar
API 的にも、 NavigationLink は引数に渡すからつながってるけど、 .sheet はクロージャだから途切れてるのか。
Avatar
Kishikawa Katsumi 7/9/2020 8:34 AM
去年のWWDCでゆってたかもしれない。
Avatar
ところで、この HistoryEntityAddView から先で使わないなら、 AddView@EnvironmentObject じゃなくて @ObservedObject で持ってもいいかもしれませんね。
8:47 AM
struct AddView: View { @ObservedObject var histroy: HistoryEntity ... } Text("追加") } .sheet(isPresented: $isShowingSheet){ AddView(histroy: self.histroy, isShowingSheet: self.$isShowingSheet) }})
8:48 AM
histroyhistory の typo だと思いますが元のままにしてます・・・)
Avatar
Deleted User 7/9/2020 9:03 AM
誤字指摘ありがとうございます
9:05 AM
私の勉強不足で恐縮なのですが、@EnvironmentObject ではなく@ObservedObject を採用する意図はなにかあるのでしょうか
Avatar
@EnvironmentObject は複数の View の間で広く(暗黙的に)共有するためのもので、 @ObservedObject は必要なときに明示的に渡すものです。この場合、 .sheet@EnvironmentObject が途切れてしまうようなので、 AddView にだけ渡すのであれば @ObservedObject で十分かなと思いました。 AddView から先でも広く共有したい種類のものであれば @EnvironmentObject が良いと思います。
9:14 AM
@EnvironmentObject だからといって大きな不利益があるわけではないですが、必要なものは必要最小限のスコープで狭く使っておいた方が管理が簡単だと思うので、 @EnvironmentObject である必要がないのであれば @ObservedObject でもいいのかなと思いました。 (edited)
Avatar
Deleted User 7/9/2020 9:17 AM
なるほど。共有は必要最小限の範囲であるほうがいいということですね。 ありがとうございます!
🙂 1
Avatar
質問させてください。 SwiftUIでCoreDataに["A","B","C"]のような文字配列を保存したいのですが、やり方がわかりません。 一応解答らしき記事を見つけはしたのですが、なかなか解読できずにいます。 https://stackoverflow.com/questions/29825604/how-to-save-array-to-coredata 「If keeping it simple and store an array as a string」あたりだと思うのですが、 ・このコードをどこに書けばいいのか ・「xcdatamodel」でどの型を宣言すればいいのか 教えていただけると助かります。
I need to save my array to Core Data. let array = [8, 17.7, 18, 21, 0, 0, 34] The values inside that array, and the number of values are variable. 1. What do I declare inside my NSManagedObject...
Avatar
実際にproductionコードで使ったことは無いですが、こんな感じで Transformable 型の attribute を追加して、Custom Class に [Int] など指定すれば動きましたー
Avatar
あとはコードで file.foo = [1,2,3,4] みたいな感じで書けます
Avatar
String型の配列を保存したいので[String]を指定してみましたが、エラーが出てしまいました。。
Avatar
SwiftUIの練習がてらCoreDataで [String]を使ったサンプルアプリを作ってみました。 (edited)
3:37 PM
Contribute to kenmaz/SwiftUISamples development by creating an account on GitHub.
👍 1
Avatar
やりたいことに非常に近い形なのでとても参考になります! ありがとうございます!!
👏 1
Avatar
swiftの配列(Array)について質問させてください。 配列が確保するメモリザイスの初期値を設定する方法がわかりません。 c#では var capacity = 10; var a = new List<int>(capacity); の様なもののことです。 よろしくお願いします。
Avatar
@swift-5.2.5 var items: [Int] = [] items.reserveCapacity(10)
👍 1
Avatar
no output
Avatar
@ryota2357 こうですかね (edited)
Avatar
返信遅くなりました。すみません ありがとうございます!助かりました! (edited)
😆 1
Avatar
Deleted User 7/30/2020 2:19 PM
cocoapodsについて質問させてください。 https://github.com/tarunon/Instantiate こちらのGItをインストールしたのですが、画像のようなエラーが出てしまいます。対策方法を2時間ほど調べたのですが、見つけきれませんでした。同じパッケージで片方使えて、片方が使えないというのはあるのでしょうか。
Type-safe and constructor injectable InterfaceBuilder protocols. - tarunon/Instantiate
👀 1
2:19 PM
Avatar
これ pod 'InstantiateStandard' もいるかな?
2:25 PM
ワシじゃん
Avatar
Deleted User 7/30/2020 2:30 PM
もしかしてそもそもいらないものでしたか? Qitaの記事ではどちらもあったんで、ないとだめなものかと。。
Avatar
含まれてる関数を使わないのであれば、入れなくても大丈夫です
2:31 PM
何入ってたかな。些細なものだったと思うのでご自身で定義されても問題ない範囲かと
Avatar
Deleted User 7/30/2020 2:33 PM
なるほどです!InstantiateStandardの方をなしでもできる方法を探してみます!
2:33 PM
ありがとうございました!
Avatar
Deleted User 8/5/2020 1:53 PM
SwiftUIでFSCalendarを使おうとしていますが、動作がうまくいきません。 カレンダーの日付を選択したときの動作であるprint("selected")が出力されないので悩んでいます。 UIkit側のイベントをSwiftUIが受け取れていないことが原因だと思いますが、解決策はありませんでしょうか。 import SwiftUI import FSCalendar import UIKit class ViewController: UIViewController, FSCalendarDelegate, FSCalendarDataSource{ @IBOutlet var calender: FSCalendar! override func viewDidLoad() { super.viewDidLoad() calender.delegate = self } func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { print("selected") } } struct UICalender: UIViewRepresentable { func makeUIView(context: Context) -> FSCalendar { return FSCalendar() } func updateUIView(_ uiView: FSCalendar, context: Context) { } } struct CalenderView: View { var body: some View{ UICalender() } } struct CalenderView_Previews: PreviewProvider { static var previews: some View { CalenderView() } }
Avatar
もうちょっと丁寧に回答すると、ViewControllerのオブジェクトを生成出来ていないのが原因です。 UICalenderに宣言されているFSCalendar()はこの行で初めて作られるオブジェクトなので、ViewControllerに宣言されている @IBOutlet var calender: FSCalendar! とは別のインスタンスであり、したがってdelegateはどこにも登録されていません。 ViewControllerのprintを呼び出したいのであれば、UIViewControllerRepresentableを利用し、そこでUIStoryboardからViewControllerのインスタンスを生成して返す必要があります。
Avatar
Deleted User 8/5/2020 2:20 PM
https://qiita.com/giiiita/items/b2588a78cfda4ecef345 この記事を参考に import Instantiate struct ViewControllerWrapper : UIViewControllerRepresentable { typealias UIViewControllerType = ViewController func makeUIViewController(context: UIViewControllerRepresentableContext<ViewControllerWrapper>) -> ViewControllerWrapper.UIViewControllerType { return UIViewControllerType.instantiate() } func updateUIViewController(_ uiViewController: ViewControllerWrapper.UIViewControllerType, context: UIViewControllerRepresentableContext<ViewControllerWrapper>) { } } こちらを追加してみたのですが、Instantiate()に対して「Type 'ViewControllerWrapper.UIViewControllerType' (aka 'ViewController') has no member 'instantiate'」というエラーが出てしまいます、、
このはじめに SwiftUIからViewControllerを表示する時のTipsです。 ViewControllerとStoryboard 記事用に作成したViewControllerとStoryboardになります。 ...
Avatar
ViewControllerはStoryboardInstantiatableに適合していますか? 例えば extension ViewController: StoryboardInstantiatable {} の宣言が存在していないのでは
Avatar
Deleted User 8/5/2020 2:51 PM
https://qiita.com/usagimaru/items/3a32ee63d9e331c98da9 この記事を参考に extension ViewController: StoryboardInstantiatable{ typealias StoryboardInstantiatableViewController = ViewController static var storyboardName: String { return "Main" } } を追加してみましたが、printは動作しないままでした、、
StoryboardからViewControllerのインスタンスを得る仕組みとして <#クラス#>.fromStoryboard() という共通のAPIにまとめてみました。 macOS NSViewControl...
👀 1
Avatar
色んな所にprint文仕込んでみて、どこが動いてないか特定してみては
Avatar
Deleted User 8/5/2020 3:03 PM
var body: some View{ UICalender() }var body: some View{ ViewControllerWrapper() } に変更したら理想の動作になりました! 何度も質問に答えていただきありがとうございました!貴重なお時間を割いていただき、ありがとうございました!
👍 2
Avatar
やりたいことに非常に近い形なのでとても参考になります! ありがとうございます!!
@Deleted User な@うたkateinoigakukun#2184> swiftの配列(Array)について質問させてください。
配列が確保するメモリザイスの初期値を設定する方法がわかりません。 c#では var capacity = 10; var a = new List<int>(capacity); の様なもののことです。 よろしくお願いします。
@ryota2357 @Yuta Saito
Avatar
@4ske https://stackoverflow.com/questions/24124417/swift-init-array-with-capacity この記事あたりが参考になるのではないでしょうか。
How do I initialize an Array in swift with a specific capacity? I've tried: var grid = Array <Square> () grid.reserveCapacity(16) but get the error expected declaration
Avatar
Deleted User 8/11/2020 6:36 AM
6:39 AM
FSClarendarで日付を選択したときに、その日付に保存してあるDouble型のデータを呼び出したいのですがうまくいきません。NSPredicateが使えそうなのはわかったのですが使い方がよくわかりません。。 (edited)
6:40 AM
教えていただけないでしょうか。
Avatar
これって FSCalendar は関係なくて、 Core Data に保存されたデータを Date で検索して取得したいという話ではないですか? (edited)
Avatar
Deleted User 8/11/2020 8:17 AM
すみません。余計なとこまで書いてしまったみたいですね。まさにその動作を実装したいです。
Avatar
僕は Core Data を使ったことがないですが、何かの値をキーにして検索するというのはごく基本的な操作ですので、 Core Data の使い方を検索すればすぐに情報が出てきそうに思います。 FSCalendar と組み合わせて検索すると一気に情報が減るでしょうが、 Core Data 単独であればいくらでもありそうかと。
8:42 AM
簡単なユーザーデータを保存したりするにはUserDefaultsを使う方法もありますが、保存する項目が増えたときには扱いが面倒になることがあります。 Core Dataで保存しておけば、強力な機能が使えるのでよさげ。 おおもとのドキ...
Avatar
あ、 Date は年月日じゃなくて秒とかのもっと細かい情報を持っているので、同一年月日だとしてもデータが一致するとは限らないので注意が必要です。
8:52 AM
僕はそういう場合は年月日の文字列(たとえば "2020-08-11" とか)を保存するようにして、文字列で検索しますね。 Core Data でやったことはないので、 Core Data で何か良い方法があるかもしれませんが。
8:52 AM
ただ、 Time Zone とかをよく考えて設計しないと後々問題を引き起こすかもしれません。
8:54 AM
同じ時刻でもタイムゾーン(たとえば日本かアメリカ西海岸か)によって日付が異なることはありますし、カレンダーからの日付の検索というのをどのような仕様とするのか考えておかないと、想定外の挙動を引き起こしてしまうかもしれません。
Avatar
回答ありがとうございます! 記事を参考にやってみたのですが、不明な点があります。。。 ・return[]の行に「Will never be executed」と出ます。 ・fetchEmployees()を使いたいのですが、 DataController.fetchRecordEntity() の()内に何を入力すればいいかわかりません。エディタには(self:DataController)と表示されます。
Avatar
employee はこの Qiita の記事の例なので、まえけんさんのコードでは別の型になりますよね?
10:32 AM
DataController.fetchRecordEntity() はクラスメソッドを呼び出してしまっているので、 DataContorller のインスタンスを生成してインスタンスメソッドを呼び出す必要があるように見えます。(ただし、 Core Data を満足に使ったことがないのでわかってないですが)
10:34 AM
「Will never be executed」と出ます。
これは、その行に到達し得ないようなコードになっているから出ている警告です。それ以前の分岐などで、 return [] まで到達できないコードになっているのではないでしょうか?
Avatar
私の理解力が不十分なので、解決策にたどり着けません。。
Avatar
おそらく、一つ一つの要素に分解して、順を追って理解しないと、いきなり組み合わせられたものの意味を理解するのは難しいと思います。
11:10 AM
DataController.fetchRecordEntity() 一つにしても、インスタンスとクラスの関係がわかっていないと理解が難しいですし、
11:11 AM
「Will never be executed」と出ます。
にしても、どういう状況でその警告が出るのかを理解して、今書いたコードを照らし合わせて何が問題なのかを考えないといけないです。
11:12 AM
コードを書いていて直面する問題というのは、世界で一つだけの自分だけの組み合わせによる問題なので、それがそのまま当てはまる状況を調べようとしても、なかなかそのものは検索してもヒットしません。
11:14 AM
要素に分解して、それらをどう組み合わせてコードが動いているのかを考えて問題にアプローチしないと、なかなか難しいように思います。
Avatar
自分の理解度の低さをわきまえず、質問ばかりしてすみませんでした。1つ1つ分解して考え、1つずつでも理解していけるように地道に勉強していこうと思います。
Avatar
本人じゃないのでエスパーになってしまうんですが、オブジェクト指向プログラミングの一番基礎的な部分に引っ掛かりがあって理解を妨げているのでは?と思います。 オブジェクトとクラスの関係、関数内におけるコンテキストとか、オブジェクト指向プログラミングのメンタルモデルに対する理解を深めると近道になるかも。
Avatar
いえ、質問していただいて大丈夫なんですが、今起こっている問題を丸ごと理解しようとしたときに、分解しないと難しそうだなと思いましたということでした💦
Avatar
オブジェクト思考の基礎となるとswiftの教材は中々見つからないのですが、遠回りになるんですが CSの学部の大学の授業とかは見れるものが結構あると思うので、それらに手を出してみるのもいいかもですね。
Avatar
最近、オブジェクト指向プログラミング1について説明する機会が多く、これからもっと多くなりそうなので、文章にまとめることにしました。 オブジェクト指向とは何かという説明はたくさんありますが、 何のためにオブジェクト指向プログラミングが...
Avatar
ここは何を質問していただいても大丈夫なチャンネルなので遠慮なく質問していただければと思うのですが、色んな問題が絡まっていて、一つずつ理解していかないと何が起こっているのかを理解するのが難しそうだと感じたので↑のような回答になりました。質問しづらいように感じられたらすみません。
Avatar
@tarunon おっしゃるとおりオブジェクト指向の基礎がまだまだ曖昧な自覚があります。。。。まずは基礎を理解することから始めようと思います! @koher いろんなことが絡んだ問題を丸投げしたような形になってしまいすみませんでした。またどうしても躓いたときに、知恵を貸していただけると助かります! @omochimetaru 記事リンクありがとうございます!すぐに読みます! (edited)
🙂 3
Avatar
omochimetaruが貼ってくれたその記事は僕が書いたものなで、質問してもらえれば答えられると思います。
Avatar
Core Data の記事のコードですが、たしかにこれだと will never be executed の警告が出そうですね。 func fetchEmployees() -> [EmployeeMO] { let context = persistentContainer.viewContext let employeesFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee") do { let fetchedEmployees = try context.fetch(employeesFetch) as! [EmployeeMO] return fetchedEmployees } catch { fatalError("Failed to fetch employees: \(error)") } return [] }
2:02 PM
理由は、この関数は return fetchedEmployeesfatalError("Failed to fetch employees: \(error)") で必ず終了するからです。
2:03 PM
try context.fetch(employeesFetch)try がマークされているので、ここでエラーが発生したときに catch 節に入るということがわかります。なので、エラーが発生しなければ return fetchedEmployees 、発生したら fatalError("Failed to fetch employees: \(error)")fetchEmployees() は終了します。
2:04 PM
そのため、 return [] が実行されることはなく、コンパイラが will never be executed (決して実行されることがない)と警告しているのです。
2:05 PM
ちょっとこれは、この記事のコードが信頼できるレベルかあやしいですね・・・。貼った記事が良くなかったかもしれません。
2:05 PM
本当は Apple の公式ドキュメント https://developer.apple.com/documentation/coredata を見るのがいいのですが、
2:07 PM
結構断片的で、ざっとみた限りでは基本的なクエリと fetch について書かれている箇所を発見できませんでした。
2:12 PM
ただ、 tarunon さんの言うように、
  • オブジェクト指向の基礎
を身に付けることも必要ですし、↑のコードを理解するには
  • Swift の基本構文や標準ライブラリの基礎(たとえば、↑のコードの tryas! の意味は? fatalError で何が起こる? fatalError の戻り値の型の Never とは?どういうケースで will never be executed の警告が出るか)
  • Core Data の基礎
  • NSPredicate (これ自体は Core Data とは独立に Foundation に存在します)
についての知識も必要になります。
2:16 PM
さらに、 @Deleted User さんの最初のコードでは SwiftUI と UIKit のコードが混ざっており、 UIKit 側に SwiftUI の @Environment などが用いられているのですが、おそらく何かのコードをみようみまねで書いたのだと思いますが、それらについてどう書くべきかを理解するには SwiftUI について学ぶ必要がありますし、そのためには Property Wrapper や Combine の理解も必要になります。
2:17 PM
それらを一歩一歩分解して理解していくことは、遠回りに見えるかもしれませんが、近道じゃないかと僕は思います。
2:19 PM
僕個人の意見としては、とりあえず最初は SwiftUI を使わずに UIKit で書いた方が理解しやすいと思います。 SwiftUI は Swift の高度な機能が色々使われていて、真に理解するのはとてもむずかしいので。僕もよくわからないことがたくさんあります。
Avatar
Deleted User 8/12/2020 4:59 AM
@koher とても丁寧な回答ありがとうございます。 ・オブジェクト指向や基本構文等の基礎が固まっていないこと ・SwiftUIは出てきたばかりで参考記事が非常に少ないため初心者には厳しいこと は、重々承知しています。なのでまずは基本からすこしずつでも理解して行こうと思います。 貴重なアドバイスありがとうございます!
🙂 1
Avatar
上から(アプリ制作)攻めるのと、下から(そもそもどうしてSwiftは動くのか? っていうか、CPUとは...?)理解するのはどちらも大切です
5:01 AM
幅の広げ方が一方行だとどこかでキビしくなるんですよね。
5:02 AM
したすぎると流石に辛いけど、OOPとかいろいろ知ってると楽しいし、わかる感が広がって良いと思います。
Avatar
Carthageのようにframeworkをzipで固めて配布するっていうのをcocoapodsでしたいのですが、やったことある人いますか?
6:18 AM
もしくはやってるライブラリご存知であれば知りたいです
Avatar
Kishikawa Katsumi 8/15/2020 9:00 AM
Realmでやってましたよ。Realmの場合は.aだったのでvendored_libraryに指定しています。 Frameworkはvendored_frameworksっていうのに指定したらいいはず。
Avatar
ありがとうございます!参考にしてみます
Avatar
Kishikawa Katsumi 8/15/2020 1:07 PM
ただビルド済みのフレームワークを配布するだけならリポジトリに含めてしまうとパスを指定するだけで簡単。 ビルドに必要な依存関係だったらスクリプトを実行できる手段があるのでそれでダウンロードするなども可能。
Avatar
これってアンチパターンでしょうか? class Interactor { var name: String init(name: String) { self.name = name } } class FirstPresenter { var interactor: Interactor init(interactor: Interactor) { self.interactor = interactor } } class SecondPresenter { var interactor: Interactor init(interactor: Interactor) { self.interactor = interactor } } // メイン処理 let interactor = Interactor(name:"aaa") let firstPresenter = FirstPresenter(interactor: interactor) let secondPresenter = SecondPresenter(interactor: interactor) print(firstPresenter.interactor.name) // aaa print(secondPresenter.interactor.name) // aaa firstPresenter.interactor.name = "bbb" print(firstPresenter.interactor.name) // bbb print(secondPresenter.interactor.name) // bbb secondPresenterからすると、自身の知らないところでinteractorが更新されてて困るケースがあるというのは理解できます。 一方で、複数のPresenterで同じInteractorを共有したい場合は有用かなとも思ったのですが、皆さんはどうやって実現されているのでしょうか?
Avatar
複数のPresenterで同じInteractorを共有したい場合は有用かな
どんな時に、同じInteractorを共有したい感じでしょうか?🤔
5:17 AM
Interactor がどういう位置付けなのかがぱっとわからなかったのですが、あるデータだとしたら、Interactor自体を共有するのではなくって、Interactorを取得する構造体 (僕はよく HogeFugaDataStore とかの名前にします)にするのでも良いのかなと思いました! 投稿が初めてでして、不明点等あったら突っ込んでいただけると助かります! (edited)
Avatar
複数のPresenterで同じInteractorを共有したい場合
これ自体はよくあることなように思います。 VIPER 的にはプロトコルを挟むのが普通なのかもしれませんが。
5:38 AM
自身の知らないところでinteractorが更新されてて困るケース
これは、 FirstPresenter からの入力による変更によって SecondPresenter が何かを View に出力しなければならないのであれば、それが Interactor から SecondPresenter に通知される必要があるのではないでしょうか。
5:42 AM
それは InteractorOutput のメソッドを呼ぶような形かもしれませんし、 name が直接出力に使われるのであれば(たとえば Combine を使うなら) namePublisher にしておいてそれを購読するとか、もしくは Interactor 自体を ObservableObject にするとか、色々な方法があると思います。
Avatar
Interactor がどういう位置付けなのかがぱっとわからなかったのですが、あるデータだとしたら、Interactor自体を共有するのではなくって、Interactorを取得する構造体 (僕はよく HogeFugaDataStore とかの名前にします)にするのでも良いのかなと思いました!
上記発言、申し訳ありません僕の不勉強でした。 もう一度勉強してきます... 🙇
(edited)
Avatar
@h1d3mun3 僕も VIPER よくわかってないですし、色んな方の意見が得られるのは良いことかと思います🙂
🙂 1
Avatar
@h1d3mun3 ご意見ありがとうございます。 例が悪かったです。申し訳ないです。 やりたかったのは、特定のクラスのプロパティに保存された値を複数のPresenterで共有したい、ということでした。なので、別にInteractorじゃなくてもいいです。 FluxでいうStoreって、1つのシングルトンで管理された状態を複数のコンポーネントで共有する仕組みだと思いますが、あれを特定のPresenterでだけで使いたいってイメージです。
🙆‍♂️ 1
😄 1
Avatar
@koher 複数のPresenterから同一インスタンスの参照をもつこと自体はアンチパターンではなくて、もし変更されて困る場合は、それを検知できる仕組みを用意しなさい、ってことですね。 ただ、それって他のPresenterからも変更されることを知っていれば可能なんですが、知らなかったらやらないので、そもそもそういう構造にすべきではないのかな、と思いました。
6:17 AM
上図によると PresenterInteractor を保持するようですし(上記ページによるとプロトコルを介するのが普通なのかもしれませんが)、 Interactor は一つの View に紐づくわけではないですよね?そうすると複数の PresenterInteractor を共有してもおかしくないと思います。
6:19 AM
PresenterInteractor からの通知を受けて、それを View に適した形に変換して通知するものだと思うので、 Presenter からの入力(上図の asks for updates )を受けて Interactor が更新されたときに、必要に応じて InteractorPresenter に更新を通知する必要があると思います。
6:22 AM
Interactor から Presenter への通知については、 VIPER が Clean Architecture の派生であることから推測すると、依存の方向は View → Presenter → Interactor → Entity で Interactor は Presenter を知らないので、 DI を使うなどして、 Interactor が Presenter を知らなくても Presenter に通知を送ることのできる仕組みが必要かと思います。
Avatar
VIPERでやるという前提であれば、複数のPresenterがInteractorを共有するので、PresenterはInteractorの変更を検知できるような実装をしないとダメってことですね。納得です。 ありがとうございました!
🙂 1
Avatar
有識者の意見も聞きたいところですが、僕はそうかなと思います。
😊 1
Avatar
QRコードを読み取り,特定のワードを検出したら別のViewControllerに移動するということをしたく,様々なサイトを見て作成したのですがアプリ起動時に強制終了してしまいました。ビルド時には特にエラーが出ませんでした。原因の部分を教えください。
Avatar
-[x] info.plistにアクセス許可の設定はしてある -[ ] AVCaptureDevice.authorizationStatusは呼び出してある (edited)
Avatar
ソースコードを添付させていただきます
7:49 AM
5.43 KB
Avatar
全てのコード含まれてるか良くわかんないんですけど、少なくともこのコードの中ではauthorizationStatusは呼んでないですね
7:54 AM
あーAVCaptureDevice.requestAccessも必要だった
Avatar
アプリ起動時にクラッシュしているので、最初に処理しているMainViewController はどうなってるでしょうか?
Avatar
えっとInfo.plistに (edited)
7:55 AM
カメラ許可する画面にでる文書をいれておかないと
7:55 AM
Crashします
7:55 AM
なんだっけ、NSなんとかCameraDescriptionみたいなキー
Avatar
そこは設定済みらしいです
Avatar
なるほど
Avatar
PCが勉強会中継設定のままで間違えて書き込みがち
kusa 1
7:56 AM
まーでも無言クラッシュは権限周りの問題だよなという気はするので
7:56 AM
後は有り得るとしたらrequestAccess呼んでないんじゃないかなと思うんですよね (edited)
Avatar
コンソールに何が出てるか読めば良い気がするけれど...
7:57 AM
それがないとなんとも言えない感はある
Avatar
自分は、Projectの最初の呼び出されるStoryboard or ViewControllerが存在しないもののパターンかなと思ったけど、その場合エラーとかでたっけかね
8:00 AM
クラッシュしているので少なくともコンソールに何かしら情報出てると思うので、それ欲しいですね
Avatar
ですね。。
Avatar
MacとiPadを接続した状態で実機テストができず,コンソールから情報を取得できない状態です;;;すみません (edited)
Avatar
iPadで起動できるようになってないとか...
Avatar
Kishikawa Katsumi 8/27/2020 8:03 AM
プロジェクトを丸ごと共有してもらうのが一番早く解決できると思いますよ @WKWK
Avatar
アドバイスありがとうございます 個人情報等を隠した状態に変更しプロジェクトをアップロードさせていただきます
8:08 AM
あもしかしたら原因が分かったかもしれません
8:09 AM
プロジェクトのUITestsファイルの方のInfo.plistを設定してたのですがプロジェクト直下の方を設定しないといけないのでしょうか
Avatar
それはそうですね
Avatar
ありがとうございます
8:11 AM
原因が理解できました ご回答いただいた方々ありがとうございました 🙏
👏 1
👍 1
rtaGl 1
Avatar
昨日質問させて頂いた件でInfo.plistを変更した後起動しても前回と同様,落ちてしまいました。いろいろ改良してみたのですがダメでした;; プロジェクト自体をアップロードさせていただきますのでご確認いただけますと幸いです。
Avatar
別に他意はないけれど、例のvlunarabilityのあとはxcodepojを気軽にひらけなくてわりと気を遣う...
7:12 AM
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x105a060c0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key videoPreview.' terminating with uncaught exception of type NSException
7:15 AM
storyboardで
7:15 AM
指定するclassがViewControllerになってるけれど、実際は名前をQRcodeViewControllerに変えてるからそれが問題 (edited)
7:16 AM
7:16 AM
ここを変えてください
Avatar
了解です 本当にありがとうございます!
Avatar
ファイル名がViewController.swiftのままだし、一致する必要はないけれど、名前がいろいろあるとややこしいので整理したほうがいいと思います。あと関係ないけれど、インデントも... swiftlint とかかけると幸せになるかも。
Avatar
ファイルの整理もしたいと思います swiftlint学習して幸せになります()
Avatar
https://github.com/realm/SwiftLint これですねちなみに。自動でソースコードフォーマットしてスタイルを維持できます。
A tool to enforce Swift style and conventions. Contribute to realm/SwiftLint development by creating an account on GitHub.
Avatar
ありがとうございます
Avatar
初質問失礼します。 xcodeのアセットカタログで、アプリ内で使う画像をフリーサイトからDLして登録しようとしているのですが、いくつかの画像が『the file "○○.png"for the image set "○○"does not exist.』となって使えない状態になってしまいます。 全て同じサイトから同じサイズで取ってきてるものなのですが、原因としては何が考えられますでしょうか...。 https://icooon-mono.com/12563-%e3%82%ab%e3%83%ac%e3%83%b3%e3%83%80%e3%83%bc%e3%81%ae%e3%83%95%e3%83%aa%e3%83%bc%e3%82%a2%e3%82%a4%e3%82%b3%e3%83%b316/
Avatar
ファイル名かイメージ名の指定に誤りがあるような気がしますが、エラーってどこに表示されますか?
Avatar
このような感じです。。。
Avatar
@あきと 1x 2x 3x のところに画像をD&Dしてあげれば、本来でないです。 D&Dしてセットしたあとに画像のファイル名変更等するとその警告はでるので、ファイル名変更するなら変更後にD&Dするといいかと。
Avatar
丁寧にありがとうございます。実は他の画像も2x,3x埋めてないのもあるんです、、。ファイル名もD&Dしてからは弄ってないんですよね。 D&Dした後に弄ってはいけない事は知らなかったです、、勉強になりました。
Avatar
ひとまず設定が上手くできていないUnsigned の画像は選択してdeleteでいいと思います。 それでこの警告自体はきえるかと。
11:12 AM
D&Dした後に弄ってはいけない事は知らなかったです、、勉強になりました。
弄る場合は同じフォルダにあるjsonファイルの中身も書き換えてやる必要があります。 jsonファイルでそこらへんは管理されているので
Avatar
@ありぜ わかりました、本当にありがとうございます( .. ) (edited)
Avatar
pngだとラスター形式なので3種類画像埋めることになるんですが、ベクター形式(pdf)なら、single scaleにする事も出来ます
11:20 AM
見た感じai/eps形式もダウンロード出来るみたいなので、pdfに変換とかすれば楽が出来るかも
sorena 1
Avatar
ニュアンス違った風に伝わってそうだったので、こんな感じにでやってみたらいいかと。
11:24 AM
ちなみに同じ画像をDLして空のプロジェクトで設定して特に問題もなかったので、画像自体に問題はないです。
Avatar
@ありぜ 上手くいきました。ggってもなかなか解決できずにいてモヤモヤしていたので、ありがたいです。
👍 1
11:32 AM
@tarunon アプリアイコンはmeke appicon等を使って全て埋めるようにしていたのですが、アプリ内で使う画像については理解が浅かったです...。 PDF変換も試してみます、アドバイスありがとうございます。 (edited)
Avatar
昨日質問させて頂いた件でInfo.plistを変更した後起動しても前回と同様,落ちてしまいました。いろいろ改良してみたのですがダメでした;; プロジェクト自体をアップロードさせていただきますのでご確認いただけますと幸いです。
@WKWK こちらの件の続きなのですがカメラビューはお陰様で表示させることができました。 しかしながらQRコードを認識させようとしたところ認識できませんでした。 通常のカメラの方では読み取れています。 QRコードを作成したのは https://qr.quel.jp/design.php です。
絵(アイコン画像)や文字を真ん中に重ねた、デザイン性のあるQRコードを無料で簡単に作成できます。選べるアイコンは378種類あります。登録不要で累積発行数No.1の信頼性。商用利用でも無期限&無制限、そして無料。かわいい丸い模様のQRコードも人気です。
Avatar
カメラの使用時にQRコード読み取りを可能になる設定してますでしょうか? https://developer.apple.com/documentation/avfoundation/avmetadataobject/objecttype/1618819-qr
Avatar
こちらソースコードですがどこに入れればよろしいでしょうか
5.43 KB
Avatar
https://qiita.com/_asa08_/items/8562fe79ec6528a61b06 この記事でいう↓の記述が該当します。swift カメラ qrコード で検索すると記事がいくつも出てくるので、参考にしてやってみてください。 metadataOutput.metadataObjectTypes = [.qr]
簡単に実装したサンプルです。参考になると幸いです。 asa08/QRreader カメラを設定する import AVFoundationして、AVCaptureSessionをインスタンスを生成します。 private le...
Avatar
了解です! ご回答いただきありがとうございます
Avatar
画面遷移についてなのですが,Main.storyboardのA viewcontrollerのボタンからSub.storyboardのB viewcontrollerに遷移するにはどうすれば良いでしょうか
Avatar
storyboard reference で検索してみましょう
Avatar
質問失礼します。 cocoapodsを導入した際に.xcworkspaceが作成されると思うのですが、今まで開発を進めていた.xcodeprojでライブラリを使うにはどうしたらいいのでしょうか?
Avatar
CocoaPodsで作成された.xcworkspaceを開けば、今まで開発を進めていたxcodeprojにライブラリを取り込んだ状態で構成して開かれます。なので、xcworkspaceを開いてそのまま開発継続して問題ないです (edited)
1:57 AM
Avatar
Kishikawa Katsumi 9/20/2020 2:02 AM
xcodeprojを別に開いてるからですね。1度に1つしか開けないので、xcodeprojを開かずにワークスペースを開いて、ワークスペースに表示されるxcodeprojを使用します。
2:02 AM
CocoaPodsを使った場合は必ずワークスペースを開いて作業しなければなりません。CocoaPodsの仕組みによる制限です。
2:02 AM
CocoaPodsはワークスペースにいろいろ設定をするので。
Avatar
閉じたら、無事にナビゲーターエリアにstoryboard等が出てきました...! .xcworkspace内に.vcodeprojが入っていることは理解できていたのですが、ここから作業を進めようにも。。。となっていたところだったので本当にありがたいです。
2:06 AM
@Kishikawa Katsumi @ありぜ 本当にありがとうございました...!
🙆‍♂️ 1
Avatar
Kishikawa Katsumi 9/20/2020 2:06 AM
よくあるやつです。私も元のを開いたままワークスペースを開いてあれってなることがあります。
😚 1
Avatar
Deleted User 9/26/2020 1:18 PM
「どの端末でも画面表示サイズを10cmに統一する」というのは可能でしょうか。調べてみると、端末サイズを取得してそのサイズごとにオブジェクトサイズを変更することならできそうなのですが、他に良い方法はないでしょうか。
Avatar
中見てないですけどpixelsPerInchがとれるみたいですね。scaleとscreen sizeと合わせればなんとなくできそう?? https://github.com/lmirosevic/GBDeviceInfo
Detects the hardware, software and display of the current iOS or Mac OS X device at runtime. - lmirosevic/GBDeviceInfo
Avatar
omochimetaru 9/26/2020 1:36 PM
Detects the hardware, software and display of the current iOS or Mac OS X device at runtime. - lmirosevic/GBDeviceInfo
1:36 PM
それ以前調べたことあるんですけど
1:36 PM
iOSのAPIとしては存在しなくて
1:37 PM
全部のデバイスに対して事前にデータ持っておく必要があります。
1:37 PM
このライブラリもそうなってる。
Avatar
当然だけど未知のデバイスに関しては0になるんですね。
1:40 PM
iOSのAPIとして提供して欲しい
Avatar
お世話になっております iOS13で「becomeFirstResponder() をプログラムから呼んでもキーボードが立ち上がらない」という問題に直面しています。。タップイベントでキーボードが起動できた後なら問題ないのですが、初回だけ起動されず。 同じような経験をした方、または解決方法をご存知の方はいらっしゃいますでしょうか? こちらのstackoverflow(https://stackoverflow.com/questions/59582631/becomefirstresponder-is-not-showing-keyboard-until-touch-of-any-uitextfield-at-l )と同じ現象になんですが、解決策で提示されているIntercomを使っていないので解決できず困っている状況です。。
Possible solution at the end. I am developing a UIViewController with three UITextField. The function to open the keyboard when the screen is presented was working for 3 years non-stop, then after...
Avatar
UIViewControllerはfirst responderを自分でなんとかしようと努力してるから
4:04 PM
意味不明な挙動しますね
4:05 PM
その固有の挙動はあまり認識していないけれど、becomeFirstResponder()を読んでも必ずしもfirst responder になるとは限らないので (edited)
4:06 PM
それ自体はAPIとしては間違ってないんですけどね。
Avatar
なるほど、ご助言ありがとうございます! もう少し自分の方で調査してみます 🙇‍♂️
Avatar
こんばんは UIPickerViewについて教えて頂きたいです。 iOS14とそれ以前のOSでUIPickerViewのselectedRowの 背景色が違うようですが、この背景色を統一する方法はありますでしょうか? この部分の色を指定するようなプロパティが見つからず 解決方法が分からなかったので質問させて頂きました。 Xcode12.0.1 (12A7300)で実行してます。 コード側では何もしてません。 宜しくお願い致します。
Avatar
tintColor じゃないのかな?
Avatar
いつもお世話になってます。 体重管理アプリを作っているのですが、ユーザーが入力した体重等の情報を日付と紐付ける処理をしたいのですが、やり方が全くイメージできず悩んでます。。。
8:42 AM
8:42 AM
8:42 AM
8:46 AM
色んな画面の要素を同期するなら、Rxswiftをやったほうがいいと言われたのですが、今はswiftだけでも手一杯なので他に何かやり方あればと思いまして。。(良いものにしたいので、必要なら勉強する気力はあります)
Avatar
やり方が全くイメージできず悩んでます
何に悩んでいるのか詳しく書いた方が良いと思います。 画面デザインの見た目の事なのか、データの保存方法の事なのか、 UIの表示方法の事なのか
(edited)
Avatar
説明不足でした、すみません。デザインではなく保存方法ですね。 ユーザーがTextFieldやImageView入力した情報を投稿した日付と合わせて保存したいのです。
Avatar
なるほど。アプリの他の機能でデータを保存してるものはあるんですか?保存方法はいろいろあるのでそれに合わせたほうが良い
Avatar
上から2枚目の画面でのユーザーがTextFieldに入力する数字の情報と日付、上から3枚目の画面では画像の投稿とメモ欄、その日に体重入力画面で体重を入力していれば下に表示され、これも日付と関連づけしたいです。 他では、1枚目のNavigationVarの設定ボタンからユーザーが目標体重と身長を入力できる欄があるくらいです。 (edited)
9:41 AM
現状保存しているものは、特にないはずです。。 コード上は、各関連付けとPickerViewの中身、Date関数での日時の取得ぐらいしかやってないので。。
9:42 AM
後、カレンダー周りぐらいですかね。
Avatar
ふむふむ。Codableを使ってJSON形式で書き出してファイルとして保存するのはどうでしょうか?
Avatar
あと、まだ後回しにしてるのですが、1枚目の左下にグラフアイコンがあると思うんですけど、上から2つ目の画面でユーザーが入力した体重や体脂肪率をグラフ化みたいなこともしたいなと思ってます( .. )
9:47 AM
Codable!!ggってみます💦
Avatar
グラフはカスタムビューにCoreGraphicsで作画するのが手軽です。
Avatar
Codable、軽くggったのですが理解レベルが追いついてなくて多分2割も理解できてないので勉強しようと思います...!グラフ化についてもありがとうございます...!!!
9:57 AM
やるべき指針が見えてありがたいです。。本当にありがとうございます!
🙂 1
Avatar
@あきと 多分具体的なコードで一連の流れがわかった上で調べた方がわかりやすいと思ったので試しに書いてみました。 import Foundation // 年月日 struct YMD: Codable { var year: Int var month: Int var day: Int } // 日付と体重・体脂肪率の記録 struct Record: Codable { var ymd: YMD var weight: Double // kg var fatRate: Double // 0.0 - 1.0 } // 日々の体重の記録は↓のような [Record] として扱える let records: [Record] = [ Record(ymd: YMD(year: 2020, month: 10, day: 14), weight: 55.2, fatRate: 0.121), Record(ymd: YMD(year: 2020, month: 10, day: 15), weight: 55.4, fatRate: 0.124), Record(ymd: YMD(year: 2020, month: 10, day: 16), weight: 55.5, fatRate: 0.123), ] // JSON ファイルから [Record] を読み込んで追加し保存する一連の処理 do { // ファイルから JSON 形式のバイト列を読み込み let data: Data = try Data(contentsOf: URL(fileURLWithPath: "path/to/records.json")) // JSON から日々の体重の記録を復元 var records: [Record] = try JSONDecoder().decode([Record].self, from: data) // 今日の記録を追加 let record: Record = Record(ymd: YMD(year: 2020, month: 10, day: 17), weight: 55.6, fatRate: 0.125) records.append(record) // JSON 形式のバイト列に変換 let newData: Data = try JSONEncoder().encode(records) // ファイルに保存 try newData.write(to: URL(fileURLWithPath: "path/to/records.json"), options: .atomic) } catch { // エラーハンドリング } (edited)
👏🏼 2
😍 1
2:54 PM
↑の RecordYMD のように Codable に適合した型であれば JSONEncoderJSONDecoder を使って JSON 形式のバイト列に変換・復元することが簡単にできます。
Avatar
@koher ええええええ....!?!?いいんですか。本当にありがとうございます。。。めちゃくちゃ助かります。。。
Avatar
これをコピペして使うというのではなく、これを元に一行ずつ何をやっているのかを確認し、さらにより一般的に Codable が何をするのかということを学ぶと理解が深まると思います。(このコードを使っていただくこと自体は問題ありません。) (edited)
Avatar
はい、質問内容自体もそうだったのですが何から手をつけていいのかすらわかっていない状態だったので本当に助かります。
🙂 1
Avatar
こんばんは。実際のスマホ画面でのViewサイズをどの機種(画面サイズ)でも10cmに統一したいのですが、方法をなかなか見つけることができません。画面サイズを取得し、そのサイズごとにViewのサイズを変更しようと考えています。実際の表示サイズを画面の解像度等から計算することは可能でしょうか。
Avatar
可能だと思いますが、端末によって画素密度が異なるので、端末ごとにそれを踏まえた計算を入れて表示してやることになるので、あまりおすすめできません。 10cmに統一したい理由ってなにかあるんでしょうか? その内容次第では、別のスマートなやり方を提示できるかも。
Avatar
Kishikawa Katsumi 10/27/2020 1:29 PM
https://github.com/marchv/UIScreenExtension/blob/master/Sources/UIScreenExtension/UIScreenExtension.swift ありぜさんのおっしゃる通りで、PPIが違うので簡単じゃないです。このようなコードでやってることを見るとわかります。
An extension to UIScreen that offers information about the pixel density (or point density) of iPhones and iPads. - marchv/UIScreenExtension
1:30 PM
逆にいうと、上記のコードのようにリリース済みの全部のデバイスについてPPIを調べたらできます。 (edited)
Avatar
返信ありがとうございます。現在制作中のアプリが精神科治療で使われているVAS評価というもので、その評価用の先の長さが10cmと決まっており、それをスライダーで再現しようと考えています。https://www.jspm.ne.jp/guidelines/pain/2010/chapter02/02_02_02.php#:~:text=VAS%E3%81%AF%E3%80%81100mm%E3%81%AE%E7%B7%9A,%E8%A9%95%E4%BE%A1%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
がん医療を中心としたPalliative Medicineの専門性を確立するための学際的かつ学術的研究とその実践、その教育を行う学会
Avatar
Kishikawa Katsumi 10/27/2020 1:34 PM
なるほど。ということは定規アプリを作るのと同じ、、、ですね。 ということなのでデバイスごとのPPIから計算する必要がありますね。
1:36 PM
デバイスごとのPPIはまあWebを調べたらいくつか出てくると思うので見比べて正しいものを参照すればいいと思います。
Avatar
func sliderWidth(SliderWidth: CGFloat, SidewaysAlert: Bool) { if UIScreen.main.nativeBounds.width == 750 {//4.7inch self.SidewaysAlert = true self.SliderWidth = 657.7 }else if UIScreen.main.nativeBounds.width == 1125 {//5.4 5.8inch side self.SidewaysAlert = true self.SliderWidth = 438.5 }else if UIScreen.main.nativeBounds.width == 1242 {//5.5 6.5inch side self.SidewaysAlert = true self.SliderWidth = 326.4 }else if UIScreen.main.nativeBounds.width == 828 {//6.1inch side self.SidewaysAlert = true self.SliderWidth = 489.6 }else if UIScreen.main.nativeBounds.width == 1170 {//6.1inch side self.SidewaysAlert = true self.SliderWidth = 346.5 }else if UIScreen.main.nativeBounds.width == 1248 {//6.7inch side self.SidewaysAlert = true self.SliderWidth = 315.8 }else if UIScreen.main.nativeBounds.width == 768 {//7.9 9.7inch self.SliderWidth = 1142.4 }else if UIScreen.main.nativeBounds.width == 1536 {//7.9 9.7inch self.SliderWidth = 571.2 }else if UIScreen.main.nativeBounds.width == 1620 {//10.2inch self.SliderWidth = 541.6 }else if UIScreen.main.nativeBounds.width == 1668 {//10.5 11.0inch self.SliderWidth = 526 }else if UIScreen.main.nativeBounds.width == 1640 {//10.9inch self.SliderWidth = 535 }else if UIScreen.main.nativeBounds.width == 2048 {//12.9inch self.SliderWidth = 428.4 } } 実機にデモアプリを入れてサイズを確かめ、実機とシミュレータのサイズ比率から計算してみたのですが、実機で検証したもの以外はうまくいきません。 (edited)
1:40 PM
なるほど。ということは定規アプリを作るのと同じ、、、ですね。 ということなのでデバイスごとのPPIから計算する必要がありますね。
@Kishikawa Katsumi その線で検索してみます!ありがとうございます!
Avatar
simulatorは、拡大縮小とかできるので、サイズにズレがでると思います。 メニューバーにあるactual sizeにチェック入れると、もしかしたら上手くいくかもしれません
👍 1
Avatar
とりあえず marchv/UIScreenExtension が持ってる値で試してみたらどうでしょうか。
1:44 PM
そのライブラリは ppi を返してくれるので。
👍 1
1:44 PM
それでもし数字がズレてたら計測してフィードバックしてあげると良いと思います。
Avatar
実機でもcmにずれが生じる場合は、UIScreen.main.nativeBounds.width が同じ値でも端末によってppiは異なるので、そこで計算ずれてると思います。 omochiさんのいうようにまずはライブラリが持ってる値で試すと良さそうです。 (edited)
👍 1
Avatar
1:48 PM
Physical Sizeを押すと実機とほぼ同じサイズになりました!
👍 1
1:48 PM
(iPhone12と8で比較) (edited)
Avatar
Kishikawa Katsumi 10/27/2020 1:48 PM
「定規アプリ 作り方」「 Ruler app ios」みたいな検索語で調べるとある程度情報が集まると思います。
👍 1
Avatar
@ありぜ @Kishikawa Katsumi @omochimetaru みなさん本当にありがとうございました! (edited)
👍 2
Avatar
お世話になっております 非常に困っているので教えて頂きたいです 前提として以下が環境です Xcode12.1 iOS Development Targetが10.3 SwiftyRSAというライブラリを使っていて、バージョンは1.3.0 このライブラリのバージョンを1.6.0に上げる必要があるのですが 調べてみたらこのライブラリのios.deployment_targetが"11.0"に上がっており iOS10.3の実機を繋いでビルドができなくなってしまいました。。。 iOS10.3をサポートしながら、このライブラリを1.6.0にする方法はありますでしょうか? 以下がこのライブラリの1.6.0バージョンアップ時のコミットです ご教示頂けると幸いです。宜しくお願い致します。 https://github.com/TakeScoop/SwiftyRSA/commit/c4f97d7726b5d1cb9480d7e442be4002716d1be9
Avatar
Kishikawa Katsumi 11/10/2020 9:36 AM
自分でDeployment Targetと必要な部分を書き換えるしかないですね。
Avatar
見た限り10でも動きそうなので、podspecファイルを手元にコピーしてdeployment_targetを書き換えて、アプリ側のPodfileの中でコピーしたpodspecを以下のように指定すると良いと思います。 pod 'SwiftyRSA', :podspec => "./SwiftyRSA.podspec" (edited)
👍 1
Avatar
@Kishikawa Katsumi 回答頂きありがとうございます。 ライブラリ側のDeployment Targetを書き換えて、それに影響される部分の コードを自分で書き換えるって意味合いであってますでしょうか?
Avatar
Kishikawa Katsumi 11/10/2020 9:38 AM
そうです。ただ、シンプルなCommonCryptoのラッパーっぽいし、たぶん @Yuta Saito さんが書いたようにターゲットのバージョンを下げるだけで動きそう。
9:39 AM
もし、ライブラリの全部の機能を使ってないならライブラリのコードを参考にして必要なところだけ組み込んだりするのがいいんじゃないでしょうか。
Avatar
@Yuta Saito @Kishikawa Katsumi 回答ありがとうございます! なるほどアプリ側のPodfileで指定する方法があるんですね。。。 確かに全部の機能を使ってないなら掻い摘んで組み込むのが良さそうな気がします・・・。 少し手を動かしてみるので、詰まったらまた質問させて頂けると助かります! ありがとうございます!
👍 2
Avatar
Shohei Yamamoto 11/16/2020 1:15 PM
XCTAssertEqual で、expectedとactualの順番の決まりはあるのでしょうか? XCTAssertEqual(expected, actual)
Avatar
Kishikawa Katsumi 11/16/2020 1:24 PM
expected, actualという引数名がついているので、厳密に書くなら 第一引数に「期待する結果(たいていはあらかじめ自分で用意したもの)」、第二引数には「実際の結果」を与えます。
1:25 PM
入れ替わっても別に結果は一緒です。失敗したときのログが入れ替わるので順番は上記の順を守った方が何かとわかりやすいです。
Avatar
Shohei Yamamoto 11/16/2020 1:40 PM
@Kishikawa Katsumi ありがとうございます! XCTAssertEqualのドキュメントでは、#define XCTAssertEqual(expression1, expression2, ...) となっており、特にどちらが期待する結果かは書かれていないのですがSwiftを書く人達の中での共通認識や慣習として期待する結果を先に書くというのがあるのでしょうか?
Avatar
Kishikawa Katsumi 11/16/2020 1:45 PM
ああ、なるほど。いや上で XCTAssertEqual(expected, actual) と書かれていたのを見て、最初の引数がexpectedなのだな、と思っただけです。ちょっと調べても見つからなかったのでテストの中で統一されてたらどっちを期待する結果としてもいいのかもしれません。
🙇‍♂️ 1
1:46 PM
入れ替えても一緒なんですけど、バラバラなのは単純にわかりにくいので揃っていた方がいいです。
Avatar
Shohei Yamamoto 11/16/2020 1:48 PM
@Kishikawa Katsumi ありがとうございます!とりあえずプロジェクト内で決めて揃えるのは意識しようとおもいます!
Avatar
Kishikawa Katsumi 11/16/2020 1:50 PM
https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods この辺をみる限り、 XCTAssertEqual(table.rowCount, 0, "Row count was not zero.") XCTAssertEqual(table.columnCount, 0, "Column count was not zero.") と書かれているので XCTAssertEqual(実際の値, 期待する結果) がいいのかもしれません(Appleのドキュメントでそうなので)。
Avatar
Shohei Yamamoto 11/16/2020 1:54 PM
なるほど確かにそうなってますね! この順番でやっていきます!ありがとうございます。
Avatar
こんにちは! UIPageViewControllerについて質問させてください。 現在解決したい問題は以下です。 UIPageViewControllerのtransitionStyleがscrollの場合に UIPageViewControllerDataSource にある以下メソッドの呼び出しが余分に呼ばれたり、呼ばれなかったりする時があります。(初回はスワイプ 時はviewControllerBeforeとviewControllerAfterが同時に呼ばれる。以降で向きを切り替えてスワイプ した際の初回のスワイプ のイベントは呼ばれない) 但しtransitionStyleをpageControlに設定した際は正常な通知になるのですが、scrollに設定する際は他に設定する項目があるのでしょうか? 何かご存知の方がいらっしゃいましたらご教授頂けますと幸いです。 よろしくお願いいたします。 func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?

環境

  • Xcode12.2
  • StoryboardでViewControllerを作成し、ContainerViewでPageViewControllerを設定 # 使用用途
  • 上記DataSourceのメソッドを使用して現在のindexを更新して、表示したいViewControllerを配列から取り出しreturn
(edited)
Avatar
@teru 実装していたのが結構前なのでうろ覚えなのですが、指摘されているUIPageViewControllerの挙動はその通りですが、実際にはそれで正常な挙動だと思います。 そもそもbefore/afterのイベントは、スワイプを開始したことの通知ではなく、前後のページが必要なのでインスタンスを用意する、というメソッドです。 アニメーションをスクロールにした場合は、バウンスアニメーションを行うために、先のページまで読み込む必要があります。またUIPageViewController自体は直近前後1ページについてはキャッシュを持っていて、キャッシュが存在していればbefore/afterは呼び出す必要がなくなる、直前の画面遷移でバウンスのために用意したページをそのまま使う、といった挙動になります。
Avatar
@tarunon ご回答ありがとうございます!
アニメーションをスクロールにした場合は、バウンスアニメーションを行うために、先のページまで読み込む必要があります。
あぁ、なるほど...バウンスがあるから先のページまで読み込まれるのですね。納得です。 それでいうとpageViewControllerのbounceを切るとpageControlと同じ挙動になるんですかね? ちょっと試してみます!ありがとうございました!
Avatar
質問です! iOSで通信速度の下りの速度を取得したいのですが、取得する術はあるのでしょうか。 以下を見るとMacでの計測をしている記事は見つけたのですが、ProcessというクラスがMacOSでしか使用できないものらしく参考記事が見当たらないのです...。 https://qiita.com/Kyome/items/e9f56432fa0d1d3f3165 もしご存知の方がいらっしゃいましたら、ご教授頂けますと幸いです!よろしくお願いいたします。
CapabilitiesのIncoming Connections (Server)またはOutgoing Connections (Client)にチェックを入れる class Network { private ...
Avatar
Process がないという以前に netstat の実行ってできないと思う
6:40 AM
この辺りのAPIを使うんだったと思う。
Avatar
@niw おぉ、ありがとうございます! このあたりを見ると https://developer.apple.com/forums/thread/652680?answerId=618275022#618275022 考え方的には、Network Frameを使用して特定サイズのファイルをダウンロードして、ダウンロード時間から通信速度(kbps/sec)を算出するイメージなのでしょうか?
Avatar
そうですねー、network framework でどのネットワークかがわかるので、それぞれの状況に応じて計測してって感じになるかなと思います。
Avatar
了解です! ご回答ありがとうございましたー!
Avatar
Swift 勉強しようと思い、手元にあるURLリスト(1,000 ドメインくらい) をクローリングするコードを書いて見たのですが、数件取得したのちに A server with the specified hostname could not be found のようにエラーが出てしまい、curl ではアクセスできるURLでもうまくクローリングできません。 何かネットワークの設定などが必要でしょうか? https://gist.github.com/dictav/52e180d8f449912a0c8fe77d53f61b1c URLSession を使っています。 session.dataTask(with: URLRequest(url: self.url)) { (data, response, error) in defer { self.isExecuting = false self.isFinished = true } if let err = error { print(self.url, err.localizedDescription) return } if let res = response as? HTTPURLResponse { print("status: \(res.statusCode)") } }.resume() (edited)
GitHub Gist: instantly share code, notes, and snippets.
Avatar
同時にコネクション作り過ぎて死んでるんじゃないかと思いました。 以下のAPIで同時実行数を制御できるので、試してみては。 https://developer.apple.com/documentation/foundation/operationqueue
Avatar
Kishikawa Katsumi 1/23/2021 11:00 AM
^ 私もこれだと思います。URLSessionはテーブルビューとかで使うだけでも同時実行を制限しなかったらすぐに通信できなくなる印象。
11:01 AM
たぶん10〜20くらいでダメ。
Avatar
ありがとうございます! 同時実行数を5くらいに制御することでクローリングはできました。ただ、クローリングにものすごく時間がかかってしまい実用的とは言えないものになってしまいました。 書き忘れていたのですが、プログラムは macOS 上で走らせています。 試しに同じような振る舞いのプログラムを Go 言語で実装し、Linux 上と macOS 上とで走らせてみたのですが、Linux 上だと同時接続数を 100 などに増やしても問題なく動作するのに対し、macOS 上だと同時接続数を10くらいにすると類似のホストが見つからないエラーがでます。言語の問題ではなく、OSの制約なのかなと思っています。 iOS上であればある程度仕方ないと思うのですが、macOS であればコネクションをたくさん作るようなプログラムを作成することもままあると思います。何かしらOSの設定を変更することでコネクションを作れる数を増やせないものでしょうか?
Avatar
一つのURLSessionで回しているなら httpMaximumConnectionsPerHost を設定しておかないとデフォルト 6 (macOS) らしいです https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1407597-httpmaximumconnectionsperhost
👀 1
Avatar
Kishikawa Katsumi 1/25/2021 5:38 PM
あ、そこの値だったのか!
Avatar
ただ per host なので関係ないかも?もしかしてネームサーバへの同時接続ではじかれてるかも?
👀 1
Avatar
Kishikawa Katsumi 1/25/2021 5:53 PM
ただURLSessionはなんかエラーが返るというよりだんまりになる感じの挙動だったから、ちょっとちゃんと調べる必要あるなあ。わからない。
5:54 PM
^ 私が確認しているテーブルビューとかでたくさんリクエストを発行すると通信不能になるというやつ。
Avatar
試しに同じような振る舞いのプログラムを Go 言語で実装し、Linux 上と macOS 上とで走らせてみたのですが、 Linux 上と macOS 上とで走らせてみたのですが、Linux 上だと同時接続数を 100 などに増やしても問題なく動作するのに対し、macOS 上だと同時接続数を10くらいにすると類似のホストが見つからないエラーがでます。言語の問題ではなく、OSの制約なのかなと思っています。
逆に Linux & Swift でどうなるのか気になりますね👀
Avatar
Linux で Swift だと CoreLibs Foundation の実装依存かなあ。
Avatar
ネームサーバの同時接続で弾かれるというのもあるんですね。なるほど。
Avatar
The Foundation Project, providing core utilities, internationalization, and OS independence - apple/swift-corelibs-foundation
👀 1
4:51 PM
The Foundation Project, providing core utilities, internationalization, and OS independence - apple/swift-corelibs-foundation
4:53 PM
Apple の Foundation が libcurl ってことはないだろうけれど、API的には同じような振る舞いを期待してるんじゃないかな。
Avatar
Deleted User 2/1/2021 10:11 AM
Swiftでアプリ製作中でUITextViewについて躓いたので教えていただきたいです。 【躓いた点】 シミュレータ上でUITextViewに文字入力しようとしたときに、日本語入力ができない。 【試したこと】 ・シミュレータの言語設定を日本語に ・シミュレータのkeyboradに日本語(Romaji)を追加 同じView内のUITextFieldは問題なく日本語入力できています。 もし解決策があるようであればご教授いただきたいです。 よろしくおねがいします。
Avatar
Avatar
Deleted User
Swiftでアプリ製作中でUITextViewについて躓いたので教えていただきたいです。 【躓いた点】 シミュレータ上でUITextViewに文字入力しようとしたときに、日本語入力ができない。 【試したこと】 ・シミュレータの言語設定を日本語に ・シミュレータのkeyboradに日本語(Romaji)を追加 同じView内のUITextFieldは問題なく日本語入力できています。 もし解決策があるようであればご教授いただきたいです。 よろしくおねがいします。
Deleted User 2/2/2021 3:13 AM
text view作り直したら解決しました、、
Avatar
𝗔𝗖⚡ƆⱯ エビフライ 2/15/2021 6:56 AM
どこに投げたらいい質問か分からないのでまずこちらに投げさせてください。 社内でApple Developer Programのcertificateを誤って削除してしまう事故が起きたのですが、この再発を防ぐfool proof的な予防策ってございますでしょうか。React Nativeで開発中 expo build:ios --revoke-credentials してしまったようです。 (edited)
Avatar
作り直せばいいからさほど困らない気がするけれど...?
8:58 AM
(答えになってないかもしれないけれど。)
Avatar
Apple DeveloperのRoleでDeveloperを割り当てて、revokeできないようにするくらいでしょうか
3:00 PM
あと、別なアプローチもあると思ってます。 何かしら困りごとを解決しようとしてこのコマンドを実行したのでしょうから、その困りごとをフォローできる人にヘルプお願いしやすい雰囲気を作るとか
Avatar
Avatar
niw
作り直せばいいからさほど困らない気がするけれど...?
𝗔𝗖⚡ƆⱯ エビフライ 3/1/2021 3:08 AM
顧客のアプリがつかえなくなって怒られたそうです
😨 1
Avatar
Avatar
nomadmonad
Apple DeveloperのRoleでDeveloperを割り当てて、revokeできないようにするくらいでしょうか
𝗔𝗖⚡ƆⱯ エビフライ 3/1/2021 3:08 AM
なるほど
Avatar
Avatar
𝗔𝗖⚡ƆⱯ エビフライ
顧客のアプリがつかえなくなって怒られたそうです
ああ、開発用のではなくて、か。
Avatar
Avatar
nomadmonad
あと、別なアプローチもあると思ってます。 何かしら困りごとを解決しようとしてこのコマンドを実行したのでしょうから、その困りごとをフォローできる人にヘルプお願いしやすい雰囲気を作るとか
𝗔𝗖⚡ƆⱯ エビフライ 3/1/2021 3:11 AM
何かしら困りごとを解決しようとしてこのコマンドを実行したのでしょうから、その困りごとをフォローできる人にヘルプお願いしやすい雰囲気を作るとか
本来はこれが正しそうなのですが、組織的には道のりが遠そう。
Avatar
証明書周りでお詳しい方教えてください。 実機ビルドをしようとすると、codesignの箇所で下記エラーが表示されてビルドができない状況です。 Warning unable to build chain to self-signed root for signer "(null)" 現状、他の開発メンバーと同じTeamに参加しているAppleアカウントでCertificateを作成し、そのCertificateをSelectしたProvisioning Profileもダウンロードした状態です。 Automatically Manage Signingにはチェック入れる/入れないどちらも試しましたが同じエラーが表示され、証明書の作り直しなども試しましたがビルドできませんでした。 原因や怪しいところがありましたら教えていただけると幸いです。
Avatar
以前、似たような状況にある方の質問に回答したことがあります。何か参考になれば! https://teratail.com/questions/126378
以前実機でアプリがビルド出来ていたのに出来なくなってしまいました。 現在Swiftでアプリ開発を行っており、Udemyで学習しているのですが、昨日完成したアプリをビルドしようとしたところ、 この画面が出てきました。そこで、ログインパスワードを入力して、「許可」のボタンを押しても反応しなかったため
Avatar
Avatar
koogawa
以前、似たような状況にある方の質問に回答したことがあります。何か参考になれば! https://teratail.com/questions/126378
返信ありがとうございます。 実はその記事は事前に確認させていただいていて、中間証明書の再インストールとMacの再起動はやってみたのですが、結果変わらずでした😢
Avatar
Avatar
kojikoji
返信ありがとうございます。 実はその記事は事前に確認させていただいていて、中間証明書の再インストールとMacの再起動はやってみたのですが、結果変わらずでした😢
なるほど。。!すでに試されていましたか🙏
🙏 1
Avatar
certificate 周りはケースバイケースでこうしたら絶対治るってのがないから
3:37 AM
ひとつづつ理解して潰していくしかないかなあ。
3:38 AM
codesignがだしてるエラー的にはルート証明書まで辿れなくて証明書の検証ができないてきな感じに思えるけど、nullになってるあたり、なにか正しい名前か引数が渡されていないように見える。 (edited)
Avatar
Avatar
niw
codesignがだしてるエラー的にはルート証明書まで辿れなくて証明書の検証ができないてきな感じに思えるけど、nullになってるあたり、なにか正しい名前か引数が渡されていないように見える。 (edited)
反応ありがとうございます。 業務で作っているアプリとは別にProjectを一個作ってみて、TeamをPersonal Teamに指定してビルドしてみたんですが、そちらも同じエラーが発生し、nullのところには自分のアカウント(Apple Developer: ○○の形)が表示されていました。
Avatar
こんにちは,本日初めてswiftを触ってみた者です.
4:33 PM
switchやifが標準で値を返すようにしたほうが便利だと思うのですが,皆さんいかがお考えですか?
4:36 PM
ネットでざっと検索したところ,わざわざクロージャーを使うコードが見かけられました
Avatar
swiftだと、scalaで言うところのif式やswitch式は無いです。が、@resultBuilder という機能を使うことで限定されたコンテキストにおいて if式、switch式相当のものを、それも構築される型を指定して組み立てることが出来ます。ざっくりどんなものかは、SwiftUIにおけるViewBuilderを参照してみて下さい。 (edited)
6:29 PM
標準であった方が便利か、と言う問いに対しては個人的な解答になるんですけど。 普段if/switchを使うときに余計な制約が無く、必要に応じて式指向の為のコンテキストを作れるというのは、結構良い塩梅なんじゃないかなと考えています。 (edited)
Avatar
余計な制約
各ブランチの結果型を揃える必要があるとかですか?
Avatar
例えば早期returnをif文で書きたいのにそれが出来なくなるとか、
👍 1
6:33 PM
そう言ったことをイメージしています
6:33 PM
ブランチの結果型は基本的にはvoidで揃いそうだなと思いました
Avatar
if/else式 switch式 に関しては "Commonly Rejected Changes" に明記されていますね https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md#control-flow-closures-optional-binding-and-error-handling
Avatar
omochimetaru 3/27/2021 5:10 AM
早期脱出とif式は両立するよ。 例えばkotlinで実際それができるんだけど、returnしてる側の型はNeverなので、もう片方の型がAなら、ifの型はAになる。Never is Aなので。
Avatar
omochimetaru 3/27/2021 5:30 AM
Kotlinのif式は両辺の型のleast common typeになると思うんだけど、
5:31 AM
SwiftのResultBuilderはEither A B にできて、型的にはそっちのほうが正確だよね
Avatar
Eitherにもできるし、least common typeにすることも出来ますね
5:32 AM
resultBuilderの造りによってそれを決定できる
Avatar
omochimetaru 3/27/2021 5:33 AM
仕組みとしてはEitherにできるようなより柔軟なものが提供されていて、その上でユーザ実装としてLCTを選択できるね。 (edited)
5:33 AM
Kotlinの方式だと Eitherにすることはできなくって
5:34 AM
自分で両方のブランチで Either.left(A) みたいに書く必要がある。
5:36 AM
Commonly Rejected Changes に挙げられていて、 それで解決できることは他の方法で解決できる ←これは同意だけど if式を導入すると大きなトレードオフがある ←実際どんなデメリットがあるのかはあまりよくわからない
5:38 AM
他の方法については、
わざわざクロージャーを使う
対して記述量が変わるわけでもないので別に良いのでは無いか ifexp みたいな高階関数を書いてちょっと楽しても良い ↓以下のlet初期化スタイルでもそんな困らない let a: Int if ... { a = 3 } else { a = 2 } と思っている
Avatar
早期リターンが可能のイメージがつかない
Avatar
omochimetaru 3/27/2021 5:40 AM
val a = if (cond) { exp } else return (edited)
5:40 AM
↑こんな感じ
Avatar
そうするとネストが深くなるのか
Avatar
omochimetaru 3/27/2021 5:40 AM
Swiftだと guard let else return のパターンなら val a = exp ?: return (edited)
5:41 AM
ネストが深いとは?
Avatar
swiftでいうところの if ... { return A } ... return A みたいなものを表現しようとしたときに
5:44 AM
ifが式だと「手前のAを返さず後ろのAを返したい場合」は、elseによってしか実現できないのではないかと
Avatar
omochimetaru 3/27/2021 5:45 AM
func ifx<T>(_ cond: Bool, then: () -> T, else: () -> T) -> T { if cond { return then() } else { return `else`() } } let a = ifx (1 + 1 > 1) { return 2 } else: { return 1 } print(a) // 2 今のSwiftだとこんなのが書けますね。
Avatar
Avatar
tarunon
ifが式だと「手前のAを返さず後ろのAを返したい場合」は、elseによってしか実現できないのではないかと
omochimetaru 3/27/2021 5:46 AM
その形のコードはそのままkotlinでも書けるよ 別にifが式だろうと、式を2つ並べる事は許されているので
Avatar
早期リターンを書くと後ろの式を評価する術がなくならない?
5:48 AM
if式の中のreturn valueを外のコンテキストの返り値にしたいのだから
Avatar
omochimetaru 3/27/2021 5:48 AM
文を分けた場合は
5:48 AM
型は独立する
5:48 AM
一つ一つのif式ごとに型が決まるだけ
5:49 AM
if (foo) { return A } とだけ書いてある場合、このif式の型は Unit( voidみたいなもん) だね。ただ左辺が無いので意味はない。
5:50 AM
then側が Never で else側が書かれてないのでUnitだ
5:51 AM
returnはifに対するreturnになってるんじゃなくて、ifが書いてある関数に対するreturnだよ。
Avatar
ん、そうなるのか
5:51 AM
コンテキスト飛ぶのか、なるほどね
Avatar
omochimetaru 3/27/2021 5:52 AM
Kotlinの文法では val a = if (foo) { 1 } else { 2 } // これはaへの代入 val b = if (foo) { return 1 } else { return 2 } // これはここからの脱出、bは代入されない
👀 1
Avatar
返信が遅れ申し訳ございません.理解するのに時間がかかってしまいました.
7:06 AM
回答していただきありがとうございます.
Avatar
Avatar
omochimetaru
Commonly Rejected Changes に挙げられていて、 それで解決できることは他の方法で解決できる ←これは同意だけど if式を導入すると大きなトレードオフがある ←実際どんなデメリットがあるのかはあまりよくわからない
確かに,具体的なデメリットが書かれておらずざっくりした公式発表ですね
7:09 AM
swiftは関数型プログラミングを意識していると思うのですが,switchやifで値を返してくれないのがswiftに対する大きい不満点です.
7:10 AM
代数的データ型 Koka type color { Red Green Blue Rgb( r : int, g : int, b : int ) } または type color { Red; ...
7:10 AM
関数型を意識した他言語は値を返すものが多いのですが... (edited)
Avatar
omochimetaru 4/5/2021 7:11 AM
その後の会話の内容とも関連するんですが
7:12 AM
if式にして値を返せるようにすると
7:12 AM
「if式のthenブロックの値」を示す文法と、「ifが書かれている関数からのreturn」の混在が起きるという問題はありますね。 (edited)
Avatar
thenブロックとは中括弧の中身のことですか?
👌 1
Avatar
omochimetaru 4/5/2021 7:14 AM
Kotlinみたいに「thenブロックの最後に書いた式の値がthenの値である」ってルールにすることはできなくもないけど
Avatar
if/switchが式なら同様にwhile/forも式になると思うんですが、これらは多分returnじゃなくてyieldでコンテキストの外に値を渡すんじゃないかな。故にif/switchもyieldでコンテキストの外に値を渡せるとして、returnは関数からの脱出ということにすれば
7:15 AM
両立が可能だ
Avatar
omochimetaru 4/5/2021 7:15 AM
「本文が1文であるクロージャやメソッドの返り値はreturnを省略できる」って文法との兼ね合いがあって勘違いを誘発しそう。
Avatar
あとそもそも言語デフォルトでif/switchが提供されてる場合に、その型をどう解決するかという問題があると思うんですが
Avatar
Avatar
tarunon
if/switchが式なら同様にwhile/forも式になると思うんですが、これらは多分returnじゃなくてyieldでコンテキストの外に値を渡すんじゃないかな。故にif/switchもyieldでコンテキストの外に値を渡せるとして、returnは関数からの脱出ということにすれば
omochimetaru 4/5/2021 7:16 AM
yieldが関数レベルコルーチンの中断を表す文として使えなくなるから微妙だと思う。 まあ、例であって、別の文で区別して扱うというのは一つの方向性だね
Avatar
Either<T,F>が採用されるのか、TとFの共通の型が採用されるのか、或いはその両方か
Avatar
omochimetaru 4/5/2021 7:17 AM
たしかKotlinは LCT(T, F) で Either(T, F)ではなかったと思う。
Avatar
両方というのはEitherが自動でprotocolへの準拠を行う、みたいな感じね
7:18 AM
まあこの辺は結局言語のデザインに依存してしまって、あんまり嬉しくないシーンは出てくると思うんですよね
Avatar
omochimetaru 4/5/2021 7:19 AM
個人的には、ブロックの値とreturnの値の共存問題が大きいと思っていて
7:19 AM
Kotlinはそれを受け入れているんだけど、
7:19 AM
Kotlinはそれを突き進めてユーザー定義高階関数もその ブロックの値とreturnの両方を使えるようにするために
7:20 AM
inline funって概念を導入してるんだよね
7:20 AM
確かにうまく使えば便利ではあるんだけど、 高階関数側がパラメータのクロージャをどう呼び出すか、っていう振る舞いが、型に現れない暗黙のAPIになるので
7:21 AM
returnしたときにどういう形で中断されるのかとかが難しいのと
7:21 AM
実際にクロージャだけを脱出したい場合に備えて、ラベルつきreturnを使ったり
7:21 AM
ブロック文法ではない匿名fun式を使い分けたりする必要があって
7:21 AM
そのへんで言語仕様がすごい複雑になっちゃってて、
7:22 AM
シンプルではないんだよね、個人的にはあまり美しくない方向だと思ってる。
Avatar
resultBuilderを使いましょうね、というのは、デフォルトは多少不便になれど、今議論している双方の問題の解たり得るので 尚更そういう意味でも良い塩梅だなと思っている
7:22 AM
型はユーザーサイドで定義するから問題無し。コンテキストはクロージャを潜ることを強制するので問題無し。
Avatar
omochimetaru 4/5/2021 7:22 AM
Swiftではブロックの値と大域returnの共存はできていないので、 当然、returnはブロック(クロージャ)の脱出でしか無いんだけど、
7:23 AM
それで困るか?というと、別に困らなくって、 モナドを正しく使えば内側の結果を外側に伝搬するのは綺麗に書けるので、
7:23 AM
Kotlinは複雑になった割に得たものが少ないなと思ってる
7:25 AM
まあ「組み込みのif文等だけは式の値と大域脱出を両立できる」って線で手を打つ方針はありえるのかもしれない。
Avatar
Avatar
tarunon
resultBuilderを使いましょうね、というのは、デフォルトは多少不便になれど、今議論している双方の問題の解たり得るので 尚更そういう意味でも良い塩梅だなと思っている
omochimetaru 4/5/2021 7:29 AM
Eitherにするかどうか選べるし、 returnがかけないから2通りの制御の混乱もないねえ。
Avatar
@swift-5.3.3 enum Either<R, L> { case right(R) case left(L) } @_functionBuilder struct Expression { public static func buildIf<C>(_ c: C?) -> C? { c } public static func buildEither<T, F>(first: T) -> Either<T, F> { .right(first) } public static func buildEither<T, F>(second: F) -> Either<T, F> { .left(second) } } func exp<T>(@Expression f: () -> T) -> T { f() } let a = exp { if true { "" } else { 1 } } print(type(of: a))
Avatar
swift53 BOT 4/5/2021 7:31 AM
exit status: 11 with stderr:Stack dump: 0. Program arguments: /usr/bin/swift -frontend -interpret - -disable-objc-interop -I /Libraries/.build/x86_64-unknown-linux-gnu/debug -I /Libraries/.build/checkouts/SwiftBacktrace/Sources/CSwiftBacktrace/include -I /Libraries/.build/checkouts/SwiftBacktrace/Sources/Clibunwind/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOHTTPParser/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOSHA1/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOAtomics/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOWindows/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIODarwin/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOLinux/include -module-cache-path /Libraries/.build/x86_64-unknown-linux-gnu/debug/ModuleCache -D DEBUG -Xcc -fmodule-map-file=/Libraries/.build/checkouts/SwiftBacktrace/Sources/CSwiftBacktrace/include/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/checkouts/SwiftBacktrace/Sources/Clibunwind/include/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/x86_64-unknown-linux-gnu/debug/CNIOHTTPParser.build/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/x86_64-unknown-linux-gnu/debug/CNIOSHA1.build/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/x86_64-unknown-linux-gnu/debug/CNIOAtomics.build/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/checkouts/swift-nio/Sources/CNIOWindows/include/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/x86_64-unknown-linux-gnu/debug/CNIODarwin.build/module.modulemap -Xcc -fmodule-map-file=/Libraries/.build/x86_64-unknown-linux-gnu/debug/CNIOLinux.build/module.modulemap -module-name main -lLibraries 1. Swift version 5.3.3 (swift-5.3.3-RELEASE) 2. While evaluating request TypeCheckSourceFileRequest(source_file "<stdin>") 3. While type-checking statement at [<stdin>:26:1 - line:32:1] RangeText="let a = exp { if true { "" } else { 1 } " 4. Whil
Avatar
だめだったw
Avatar
omochimetaru 4/5/2021 7:32 AM
あれ? Either2View<A, B> とかどうやって作ってるんだ? (edited)
Avatar
多分上のはちょっと制約足りなくて死んだ
Avatar
omochimetaru 4/5/2021 7:33 AM
あ、これaも推論させてるからそうだね
7:36 AM
extension ViewBuilder { public static func buildEither<TrueContent, FalseContent>(first: TrueContent) -> _ConditionalContent<TrueContent, FalseContent> where TrueContent : View, FalseContent : View public static func buildEither<TrueContent, FalseContent>(second: FalseContent) -> _ConditionalContent<TrueContent, FalseContent> where TrueContent : View, FalseContent : View } https://yanamura.hatenablog.com/entry/2019/09/05/150849
potatotips #64でLTした内容です。 SwiftUIのViewで条件によってViewをだしわけたいことがたまにあるかと思います。 SwiftUIでこのように条件によってViewを出し分けるようなコードを書いてみます。 var body: some View { if imageName.isEmpty { return Text("no image") } else { return Image(imageName) } } そうするとこのようなコンパイルエラーになってしまいます。 ! Function declares an opaque return type, but the…
7:36 AM
できることは間違いない。
Avatar
過去に私が書いたコード見ても、外から推論を与えないと上手く行かない事が示唆されてるから
7:40 AM
あんまり便利な感じにはならなさそう
Avatar
@swift-5.3.3 enum Either<R, L> { case right(R) case left(L) } @_functionBuilder struct Expression { static func buildBlock() -> () { return () } static func buildBlock<T1>(_ t1: T1) -> (T1) { return (t1) } public static func buildEither<T, F>(first: T) -> Either<T, F> { return .right(first) } public static func buildEither<T, F>(second: F) -> Either<T, F> { return .left(second) } } func exp<T>(@Expression f: () -> T) -> T { f() } let a = exp { if true { "" } else { 1 } } print(type(of: a))
Avatar
swift53 BOT 4/5/2021 7:40 AM
Either<String, Int>stderr:<stdin>:34:9: warning: will never be executed 1 ^ <stdin>:31:8: note: condition always evaluates to true if true { ^
Avatar
buildBlockが必要
👏 3
Avatar
あああーーー
7:40 AM
なるほどね
Avatar
新しいコンパイラでコンパイルしたらちゃんとしたエラー出て偉かった
Avatar
ifの中で単一式を評価できない状態になってた
7:42 AM
このresultBuilderの機能を使って、コンテキストに合わせた立式を定義できるんで
7:42 AM
やりたいことはかなりカバーできるはず
7:42 AM
while,forもサポートされ…ましたっけ?プロポーザルは見た
7:43 AM
ちなみに Either<L, R> が一般的だと思うよ
😇 1
Avatar
確かにLが左だわね
Avatar
Avatar
omochimetaru
val a = if (cond) { exp } else return (edited)
話の流れを遮ってしまってすみません.理解が追いついていません笑 早期リターンの例を書いてみたのですが,仮にifが値を返すように実装されたとしたらどのような感じになりますか?(学んだばかりで,適切なエラーハンドリングがわからないので,0を返しています.ここも含めてリファクタリングしていただいても結構です) func calculatePaymentPrice(_ price : Int) -> Int{ if price < 0 { return 0 //エラーの代わり } return Int(Double(price)*1.1) } (edited)
Avatar
Avatar
basashi
話の流れを遮ってしまってすみません.理解が追いついていません笑 早期リターンの例を書いてみたのですが,仮にifが値を返すように実装されたとしたらどのような感じになりますか?(学んだばかりで,適切なエラーハンドリングがわからないので,0を返しています.ここも含めてリファクタリングしていただいても結構です) func calculatePaymentPrice(_ price : Int) -> Int{ if price < 0 { return 0 //エラーの代わり } return Int(Double(price)*1.1) } (edited)
omochimetaru 4/5/2021 7:46 AM
返信先のコードはelseでreturnしてるifが式でval aに代入できている例です。 提示されているcalculatePaymentPriceは普通のSwiftに見えますけど質問はなんですか?
Avatar
if式でreturnが問題になるという話は、ifをネストさせると何が問題なのかが解りやすくなると思う (edited)
Avatar
わかりづらくてすみません😢 仮にswiftのifが値を返すとしたら,同じ動きをする関数をどう書いたらよいかという質問です (edited)
Avatar
omochimetaru 4/5/2021 7:49 AM
func calculatePaymentPrice(_ price : Int) -> Int { if price < 0 { 0 } else { Int(Double(price) * 1.1) } } こうなるって話をしてると思ってます。式1つなのでreturnは省略しました。
7:51 AM
ちなみに現状のSwiftでも func calculatePaymentPrice2(_ price : Int) -> Int { price < 0 ? 0 : Int(Double(price) * 1.1) } func calculatePaymentPrice3(_ price : Int) -> Int { ifx (price < 0) { 0 } else: { Int(Double(price) * 1.1) } } ↑この2つの書き方はできます。(ifxは自作の関数)
Avatar
Avatar
omochimetaru
func calculatePaymentPrice(_ price : Int) -> Int { if price < 0 { 0 } else { Int(Double(price) * 1.1) } } こうなるって話をしてると思ってます。式1つなのでreturnは省略しました。
確かに先程の例だと,ifブロックの後ろをelseに入れられますね.例が悪かったかもしれないです.
7:57 AM
いい例えが思いつかないのですが,
7:58 AM
func calculatePaymentPrice(_ price : Int) -> Int{ if price < 0 { return 0 //エラーの代わり } if price = 0 { return 0 //エラーの代わり } return Int(Double(price)*1.1) }
7:58 AM
(無理やりエラー処理をもう一つ追加しました)
7:59 AM
このような場合だとどうなりますか?
Avatar
omochimetaru 4/5/2021 8:00 AM
func calculatePaymentPrice(_ price : Int) -> Int{ if price < 0 { 0 } else if price = 0 { 0 //エラーの代わり } else { Int(Double(price)*1.1) } } こうですか??
8:01 AM
そもそも僕はif式にしなくていいだろうと思っているので、 if式があったらどうなるかと言われても、答えようがないですよ。
8:01 AM
ifが文ではなく式だったらいいのに、と思っているのは @basashi さんなのだから、 「こういうコードが書けたら良いのに」という思いがあるのは、そちらでは。 (edited)
Avatar
if式を採用した場合に発生するコンテキストの問題として、if文の中のreturnが何を指すのかという問題が発生する。 1. if式の返り値として値を採用し、if式から脱出する 2. 関数の返り値として値を採用し、関数から脱出する。この時if式自体の返り値はNever型になる。 1を採用した場合、シンプルなif文を使った早期returnが表現できなくなるか、或いはネストしてif elseで表現することを強制される。 例 if myArray.isEmpty { return -1 } if elseで表現することを強制される、ということはそれは即ちif式での早期脱出の数だけ、本文のネストが深くなるということであり、望ましいものではない。 2を採用した場合、if式の中でif式の値として早期脱出を表現することは不可能になる。 例 let a = if myCond { if myArray.isEmpty { return -1 } // この行は関数の返り値になり、aとして利用することは出来なくなる ... } これらの1,2双方の問題を解決しようとした場合、ラベル付returnのような複雑な仕様が必要となるが、それは望ましくない というのがSwiftでif/switch/for/whileが式として提供されない一般の理由、と考えて良いと思います。 個人的にはラベル付returnよりはResultBuilderの方がシンプルなんじゃないかな、という感想。 (edited)
Avatar
Avatar
omochimetaru
ifが文ではなく式だったらいいのに、と思っているのは @basashi さんなのだから、 「こういうコードが書けたら良いのに」という思いがあるのは、そちらでは。 (edited)
確かにswiftサーバーでお聞きする質問ではなかったですね.すみません
Avatar
型の話はこのコンテキストの課題を超えた先の問題になりますね
Avatar
まずはコンテキストの壁を超えるようにがんばります
Avatar
Avatar
basashi
確かにswiftサーバーでお聞きする質問ではなかったですね.すみません
質問すること自体は良かったと思いますよ。僕は横目で議論を見てif式のメリットとデメリットを確認することができました。ただメリデメがあると分かった上で、basashiさんの「デメリットを引き受けてでもif式で解決したい課題」が説明できるとより良かったかもしれません
👍 2
Avatar
@basashi
swiftは関数型プログラミングを意識していると思うのですが,switchやifで値を返してくれないのがswiftに対する大きい不満点です.
僕は Swift はあまり関数型ではないと思っています。特に、イミュータビリティに対する考え方が異なります。 Swift はイミュータブルクラスの代わりにミュータブルな struct を使うことが多いです。 // イミュータブルクラス final class User { let age: Int = 0 } var user = User() // 年齢を 1 増やす user = User(age: user.age + 1) // struct struct User { var age: Int = 0 } var user = User() // 年齢を 1 増やす user.age += 1
(edited)
8:24 AM
if 文の例で考えると、↓のような違いが生まれます。 // イミュータブルクラス user = if ... { // if 式がほしい User(age: user.age + 1) } else { User(age: user.age + 2) } // struct if ... { // if 文で十分 user.age += 1 } else { user.age += 2 }
8:26 AM
if が式でなく文なのはミュータブルな値型( struct )を多用する Swift と馴染んでおり、適切な言語仕様ではないかと思います。 (edited)
8:29 AM
なお、ミュータブルな値型のインスタンスは共有することができないので(ミュータブルクラスのインスタンスではこれが可能なのでイミュータブルクラスを使いたい)、実質的にイミュータブルクラスのように働きます。
Avatar
swiftに対する先入観が誤っていたかもしれません
8:40 AM
更に勉強