Swipe up to unlock
になってますね。Swipe up to open
なような Press home to open
なので、手に持って顔認証解除した状態だと Swipe up to open
じゃないかなと思った次第でした。 (edited)fastlane beta
するとXcode9でコケる問題、Fastfileに下のオプション付けると問題が解消されるみたいですね export_xcargs: "-allowProvisioningUpdates"
https://github.com/fastlane/fastlane/issues/9589If you have a sharing extension, you can also get `PHLivePhoto` objects by using `NSItemProvider`.
とあるけど、実際にはできない。iOS 9.1リリース時点では出来たのか不明。 https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS9_1.htmlURLSession
をプロキシ越しに使うとお漏らしする・・・・・self.dissmissLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 50)) self.dissmissLabel.font = UIFont(name: "Bold", size: 100) self.dissmissLabel.text = "×"
(edited)UIFont(name: "Bold", size: 100)
で nil
が返って、何も指定しないデフォルトになってるんじゃないですかね。 self.dissmissLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 50)) self.dissmissLabel.font = UIFont(name: "HiraginoSans-W3", size: 100) self.dissmissLabel.text = "×"
これで、サイズ指定できましたself.dissmissLabel.font = UIFont.boldSystemFont(ofSize: 100)
or self.dissmissLabel.font = UIFont.systemFont(ofSize: 100)
(edited)UITextInputTokenizer
を返すようにしたら変えられるんじゃないかと思ってるんですけど、あまり簡単ではないです。 https://developer.apple.com/documentation/uikit/uitextinput/1614537-tokenizerPodsなんとか.dylib
みたいなのができてませんでしたっけ。1個にまとまるような?UIColor!
だったからいけるかなーと思ったけどwillMoveToSuperviewの時点でデフォの値が入ってるっぽくて頓挫extension UILabel { open override func willMove(toSuperview newSuperview: UIView?) { if textColor == .black { textColor = UIColor.red } super.willMove(toSuperview: newSuperview) } }
typealias SCNQuaternion = SCNVector4
/* m30, m31, and m32 correspond to the translation values tx, ty, and tz, respectively. m[12], m[13], and m[14] correspond to the translation values tx, ty, and tz, respectively. */ public struct _GLKMatrix4 {
(edited)DESCRIPTION glTranslate produces a translation by (x,y,z). The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, as if glMultMatrix were called with the following matrix for its argument: 1 0 0 x 0 1 0 y 0 0 1 z 0 0 0 1
matrix_float4x4
はメモリレイアウトが転置してなかったかな。自信ないけど。The default value is 0.
ってなってるけど Xcode9.3のQuartzCore/CADisplayLinkのヘッダにはThe default value is 60.
ってなってるなぁ。 iOS10.3.1/11.3のシミュレータだと60が初期値になっている気がする。 0を指定すると最大値になるっていう点では間違ってない気がするけどこれ意図したドキュメントなんだろうか…。 (edited)var i = 0.0 while i < 1.1 { i += 0.01 print(i, i == 1.0) if i == 1.0 { print("####called this line####") } } }
(edited)0.81 false 0.82 false 0.83 false 0.839999 false 0.849999 false 0.859999 false
0.01じゃなくなるタイミングがある、なんか言語仕様的なアレでしたっけこれ…var double: Double = 0.0 var decimal: Decimal = 0.0 for _ in 1...100 { double += 0.01 decimal += 0.01 print(double) print(decimal) }
を実行すると、 … 0.8 0.8 0.81 0.81 0.820000000000001 0.82 0.830000000000001 0.83 0.840000000000001 0.84 …
0.82から狂いはじめてますねimport Foundation var i: Decimal = 0.0 while i < 1.1 { i += 0.01 print(i, i == 1.0) if i == 1.0 { print("####called this line####") } }
(edited)0.01 false 0.02 false 0.03 false 0.04 false 0.05 false 0.06 false 0.07 false 0.08 false 0.09 false 0.1 false 0.11 false 0.12 false 0.13 false 0.14 false 0.15 false 0.16 false 0.17 false 0.18 false 0.19 false 0.2 false 0.21 false 0.22 false 0.23 false 0.24 false 0.25 false 0.26 false 0.27 false 0.28 false 0.29 false 0.3 false 0.31 false 0.32 false 0.33 false 0.34 false 0.35 false 0.36 false 0.37 false 0.38 false 0.39 false 0.4 false 0.41 false 0.42 false 0.43 false 0.44 false 0.45 false 0.46 false 0.47 false 0.48 false 0.49 false 0.5 false 0.51 false 0.52 false 0.53 false 0.54 false 0.55 false 0.56 false 0.57 false 0.58 false 0.59 false 0.6 false 0.61 false 0.62 false 0.63 false 0.64 false 0.65 false 0.66 false 0.67 false 0.68 false 0.69 false 0.7 false 0.71 false 0.72 false 0.73 false 0.74 false 0.75 false 0.76 false 0.77 false 0.78 false 0.79 false 0.8 false 0.81 false 0.82 false 0.83 false 0.84 false 0.85 false 0.86 false 0.87 false 0.88 false 0.89 false 0.9 false 0.91 false 0.92 false 0.93 false 0.94 false 0.95 false 0.96 false 0.97 false 0.98 false 0.99 false 1 true ####called this line#### 1.01 false 1.02 false 1.03 false 1.04 false 1.05 false 1.06 false 1.07 false 1.08 false 1.09 false 1.1 false
(edited) override func viewDidLoad() { super.viewDidLoad() while i < 1.1 { i += 0.01 } } public var i: Float = 0.0 { willSet { self.i = min(newValue, 1.0) } didSet { if i == 1.0 { print("####called this line####") } } }
こんな感じだったのですが、willSetで代入予定の値差し替えるのは出来ないんですね willSetでガードしていたつもりだったので変にハマってしまった….sync
は呼び出しスレッドで実行される。キューのスレッドではない。 2. .async
はキューのスレッドで実行される。 3. 複数のキューがスレッドを共有する事がある。ワーカースレッド512本まではキューのために新しいスレッドが立つが、 513個目のキューには既存のスレッドが共有割当された。この数はおそらく環境によって変わるんだろう。 4. キューに割り当てられたスレッドが変更される事は無さそうだった。DispatchQueue.main
の時はqueue512: thread sharing found: queue 1 also use <NSThread: 0x1c807da80>{number = 4, name = main}
iPhoneXでも512っぽいですねー open func invalidateAndCancel() { NSUnimplemented() }
まあ、キャンセルの実装されてないけどwoutput = [[AVCaptureVideoDataOutput alloc] init]; ... output.videoSettings = @{(id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)};
import UIKit import AVFoundation import EasyCamery import EasyImagy class ViewController: UIViewController { @IBOutlet var imageView: UIImageView! private let camera: Camera<RGBA<UInt8>> = try! Camera(sessionPreset: .vga640x480, focusMode: .continuousAutoFocus) override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) camera.start { [weak self] image in DispatchQueue.main.async { self?.imageView.image = image.uiImage } } } override func viewWillDisappear(_ animated: Bool) { camera.stop() super.viewWillDisappear(animated) } }
image
は EasyImagy の Image
型なので自由にピクセルにアクセスできます。 var image = Image<RGBA<UInt8>>(named: "ImageName")! print(image[x, y]) image[x, y] = RGBA(red: 255, green: 0, blue: 0, alpha: 127) image[x, y] = RGBA(0xFF00007F) // red: 255, green: 0, blue: 0, alpha: 127 // Iterates over all pixels for pixel in image { // ... } // Processes images (e.g. binarizations) let binarized: Image<Bool> = image.map { $0.gray >= 127 } // From/to `UIImage` image = Image<RGBA<UInt8>>(uiImage: imageView.image!) imageView.image = image.uiImage
CVPixelBuffer
が BGRA
で来るので、 RGBA
に変換してるとこのオーバーヘッドが相当ありますCVPixelBuffer
からは必ずコピーして使うので、どのみちどこかにコピーしないといけないんですが、そのコピー先を EasyImagy の Image
型のバッファにしてるのでBGRA
型を作って Image<BGRA<UInt8>>
でフレームを取得するのであれば、ちゃんとやれば余計なオーバーヘッドなしになりそうだと思ってます。UIImage
に変換して UIImageView
で表示させてるとこはもちろん余計なオーバーヘッドがあります。本当はもっと効率的な方法でレンダリングすべきです。が、そこはライブラリの外の話なので。 EasyImagy に withUnsafePointer
とか実装してあるんで、それを使って image
から効率的にレンダリングは可能です。DispatchQueue.main.async
を通してコールバックが呼ばれるようにして、コールバックに渡された image
も inout
にしてそのまま編集できるようにしました。 ↓は画像のピクセルにアクセスして編集して、ネガポジ反転してる例です。 import UIKit import AVFoundation import EasyCamery import EasyImagy class ViewController: UIViewController { @IBOutlet var imageView: UIImageView! private let camera: Camera<RGBA<UInt8>> = try! Camera(sessionPreset: .vga640x480, focusMode: .continuousAutoFocus) override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) camera.start { [weak self] image in // Makes `image` negative image.update { pixel in pixel.red = 255 - pixel.red pixel.green = 255 - pixel.green pixel.blue = 255 - pixel.blue } self?.imageView.image = image.uiImage } } override func viewWillDisappear(_ animated: Bool) { camera.stop() super.viewWillDisappear(animated) } }
image
は生のピクセルデータですね。↑の例はそのピクセルを操作してネガ・ポジ反転してます。 (edited)CVPixelBuffer
そのものかという意味でしたらコピーと、 CVPixelBuffer
では BRGA なので R と B の反転をしてるという意味で生ではないです。個々の RGB のチャネルの値は生の値と同じですね。 (edited)github "koher/EasyCamery" "master"
と書いて carthage update --platform ios
すれば EasyImagy も勝手に取得してビルドされると思います(試せてませんが・・・)。 (edited)UIImageView
で出力するなら、オーバーヘッドを気にしなければ image.rotated(byDegrees: 90)
とかで回転できます。 (edited)UIImageView
よりパフォーマンスのいい専用 View
を提供して、そこでオリエンテーションを吸収とかはありかも?override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // Makes `image` negative camera.start { [weak self] image in image.update { pixel in pixel.red = 255 - pixel.red pixel.green = 255 - pixel.green pixel.blue = 255 - pixel.blue } self?.imageView.image = UIImage(cgImage: image.cgImage, scale: 1.0, orientation: .right) } }
@koher さんがご懸念されてたコールバックの度に回転させちゃうコードだとこんな感じでしょうか (edited)UIImage
の orientation
で設定するのが良さそうですね。それだと余計なオーバーヘッドはなさそうです。 (edited)Image
の rotated(byDesrees:)
を使って、↓のようにやることでした。 camera.start { [weak self] image in let rotated = image.rotated(byDegrees: angle) self?.imageView.image = rotated.uiImage }
rotated
が無駄に生成される分だけ余計です (edited)self?.imageView.image = UIImage(cgImage: image.cgImage, scale: 1.0, orientation: .right)
上記のコードでしょうか? 上記と下記で挙動は変わりました。 self?.imageView.image = image.uiImage // koherさんが最初に書かれたサンプルコード
(edited).right
決め打ちではなく端末の orientation に従った値を渡す必要がありますね。Could not find Developer Disk Image
とWarning がでて 書き込めなくなりました。 ...self?.imageView.image = UIImage(cgImage: image.cgImage, scale: 1.0, orientation: .right) print(self!.imageView.image!.imageOrientation.rawValue)
@Kishikawa Katsumi 上記のようにprintを仕込んだところ、コンソールには 3 が表示され続けました。 (edited)let o: UIImageOrientation switch UIDevice.current.orientation { case .portrait: o = .right case .landscapeLeft: o = .up case .landscapeRight: o = .down default: o = .right } self?.imageView.image = UIImage(cgImage: image.cgImage, scale: 1.0, orientation: o)
@koher @Kishikawa Katsumi こんな感じにしてみました。デバイスの向きが portraitUpsideDown である場合を除いて、良い感じに動いてます。import UIKit import AVFoundation import EasyCamery import EasyImagy class ViewController: UIViewController { @IBOutlet var imageView: UIImageView! private let camera: Camera<RGBA<UInt8>> = try! Camera(sessionPreset: .vga640x480, focusMode: .continuousAutoFocus) override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) camera.start { [weak self] image in // Makes `image` negative image.update { pixel in pixel.red = 255 - pixel.red pixel.green = 255 - pixel.green pixel.blue = 255 - pixel.blue } self?.imageView.image = image.uiImage(orientedTo: UIApplication.shared.cameraOrientation) } } override func viewWillDisappear(_ animated: Bool) { camera.stop() super.viewWillDisappear(animated) } } extension Image where Pixel == RGBA<UInt8> { func uiImage(orientedTo orientation: UIImageOrientation) -> UIImage { return UIImage(cgImage: cgImage, scale: 1.0, orientation: orientation) } } extension UIApplication { var cameraOrientation: UIImageOrientation { switch statusBarOrientation { case .portrait: return .right case .landscapeRight: return .up case .portraitUpsideDown: return .left case .landscapeLeft: return .down case .unknown: return .right } } }
(edited)libc++abi.dylib: terminating with uncaught exception of type NSException
^ これのもうちょい手前のログとかスタックトレースないですか?maxISO
、minISO
がAVCaptureDeviceFormatから調べられると思うので、その値を見てみてください。device.setExposureModeCustom(duration: CMTimeMakeWithSeconds(0.001, 1000*1000*1000), iso: device.activeFormat.maxISO, completionHandler: nil)
import EasyCamery
が不要に見えますね。github "mattt/Surge" ~> 2.0.0
これを削除したらコンパイル通って、クラスも参照できたんですよねimport XXX import YYY Foo.xxx // 🙅FooがXXX,YYY両方にあるとダメ、import XXXだけなら問題ない。なので XXX.Foo.xxx // 🙆モジュール名を明示的に指定する必要がある
UNUserNotification
の getDeliveredNotifications
が常に空で帰ってくる… (iOS 11.0.2 だとちゃんと取れる)try fileStrDataForTimeAxisWaveForm.write(to: path, atomically: true, encoding: String.Encoding.utf8) print(path) print("Success to Wite the File")
これは成功裏に実行されてるんですよね。ただ、該当するファイルがフォルダ内に無いという if let documentDirectoryFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last { // ディレクトリのパスにファイル名をつなげてファイルのフルパスを作る var fileStrDataForTimeAxisWaveForm:String = "" for singleData in self.wave{ fileStrDataForTimeAxisWaveForm += "\"" + String(singleData) + "\"" + "\n" } let targetTextFilePath = documentDirectoryFileURL.appendingPathComponent(self.generateFileNameForTimeAxisWaveForm()) print("書き込むファイルのパス: \(targetTextFilePath)") do { try fileStrDataForTimeAxisWaveForm.write(to: targetTextFilePath, atomically: true, encoding: String.Encoding.utf8) } catch let error as NSError { print("failed to write: \(error)") } }
UNUserNotificationCenter.current().add(request, withCompletionHandler: { error in guard let error = error else {return} print(error) })
ではエラーもなく,直前にbreakpointを貼って一度止めてから動かすと,何故か発火するという不可解な状態です. どなたか似たようなケースあった方いらっしゃいますか?UNLocationNotificationTrigger
を使って指定場所でローカルプッシュを打ちたい感じでしょうかmacOS 10.13 and iOS 11 Release Notes NSUserDefaults Data Loss Fix Starting in iOS 9.3, and in subsequent releases of iOS and macOS, NSUserDefaults could fail to load data if more than roughly 250 separate apps (including separate reinstalls of the same app) had been launched since the last reboot. This has been corrected.
viewDidLoad
で DispatchQueue.main.async
したやつが viewDidAppear
よりあとに呼ばれるのって別に何も保証されてないですよねdidMove
が同期的に呼ばれるとは限らないからされないなdidMove
の話してるから確かにそうだback.pdf
, forward.pdf
という名前を付けるのではなく、 leftArrow.pdf
、 rightArrow.pdf
の方がたいていは良いです。let backImage = UIImage(named: leftArrow)
のように名前をつけます。 色々なところで使われるなら、 backImage
を定数などにして参照可能にします。 @IBAction func getWalk(_ sender: Any) { let pedometer:CMPedometer = CMPedometer() if(!CMPedometer.isStepCountingAvailable()) { print("cannot get stepcount") } //let now = Date() //let oneWeekAgo = Date(timeIntervalSinceNow:604800) let now:NSDate = NSDate() let formatter:DateFormatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" let from:NSDate = self.stringToDate(date: formatter.string(from: now as Date), isStart: true) let to:NSDate = self.stringToDate(date: formatter.string(from: now as Date), isStart: false) pedometer.queryPedometerData(from: from as Date, to: to as Date, withHandler: {(pedometerData:CMPedometerData!, error:NSError!) in print("\(pedometerData.numberOfSteps)") // 歩数 //print("\(pedometerData.distance)") // 距離 //print("\(pedometerData.floorsAscended)") // 上った回数 //print("\(pedometerData.floorsDescended)") } as! CMPedometerHandler) } private func stringToDate(date: String, isStart: Bool) -> NSDate { let timestamp = (isStart) ? date + " 00:00:00" : date + " 23:59:59" let formatter:DateFormatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" return formatter.date(from: timestamp)! as NSDate }
このコードがエラーで実行できないんですよね。 2日ぐらいやってるんですがよくわからなくてtypealias CMPedometerHandler = (CMPedometerData?, Error?) -> Void
なのでキャストに失敗しているみたいです。as! CMPedometerHandler)
{(pedometerData:CMPedometerData!, error:NSError!) in
を { (pedometerData, error) in
にすると型推論で型が充てられるので処理が通るようになると思います。 (as! CMPedometerHandler
も不要になります。) (edited)let pedometer:CMPedometer = CMPedometer()
これが、ローカル変数になっていて、コールバックが呼ばれたときにCMPedometer()がなくなっていてエラー吐いていたようですlldb
でpo 変数
を打った時に、 (lldb) error: Couldn't IRGen expression, no additional error
となって変数の中身がわからないのですが、どなたか解決する方法知りませんか。 https://stackoverflow.com/q/52420272/1876356 にあるように、 rm -rf ~/Library/Caches/org.carthage.CarthageKit
rm -rf Carthage/
を試して、 再度ライブラリをupdateしても問題が起きたままなので、困ってます。 (edited)class ViewController: UIViewController { ... func foo() { DispatchQueue.main.async { [weak self] in guard let self = self else { return } // self を使う処理 DispatchQueue.main.async { [weak self] in guard let self = self else { return } // self を使う処理 } } } }
class ViewController: UIViewController { ... func foo() { weak var wself = self DispatchQueue.main.async { () in guard let self = wself else { return } // self を使う処理 DispatchQueue.main.async { () in guard let self = wself else { return } // self を使う処理 } } } }
[weak self]
の繰り返しは避けられますよ、僕は2重3重になるときはそうしてます。async
はミスリーディングだったかもです。空で書けてぱっと出てくる @escaping
な高階関数が DispatchQueue.async
だっただけですね foo
とかにしておいた方がよかったかも。[weak self]
書いておかないと内側のクロージャ式で誤ってそのまま self
使ってしまいそうな・・・。まあ、 [weak self]
書き忘れでも同じことにはなるんですが。個人的には wself
の名前問題も発生しないし、 [weak self]
繰り返しの方が好みですね。
class ViewController: UIViewController { var hogehoge: UIView = UIView() func piyopiyo() { NotificationCenter.default.post(.hoge, object: hogehoge.snapshotImage()) self.dismiss(animated: true, completion: nil) } } extension UIView { func snapshotImage() -> UIImage? { UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0) guard let currentContext = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext() return nil } layer.renderInContext(currentContext) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } }
CoreData
が使いたければ、project settings の Linked Frameworks and Libraries の +ボタンを押してCoreData.frameworkを明示的に追加する必要があった気がしますが、いまだとおもむろにコード中で import CoreData
とか書いてやればすぐに使えるようになってる気がするんですが、これってどういうことなんでしたっけ?昔からでしたっけ (edited)In-app provisioning of payment cards.
+PKAddPaymentPassViewController
使えばアプリ内でApple Payの登録画面を呼び出せるって認識で合ってるんですかね?PKAddPaymentPassViewController
でした。 手元の検証機iPhone X (iOS 12.1)では、 アプリ内でApple Pay登録処理 > 登録完了 > 決済シートが表示 の流れで動作していてエラーは確認していませんね
- (nullable NSData *)readDataUpToLength:(NSUInteger)length error:(out NSError **)error API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) NS_REFINED_FOR_SWIFT;
@available(iOS 13.0, *) open func __readDataUp(toLength length: Int) throws -> Data