WWDC2016セッションメモ「A Peek at 3D Touch」
WWDC2016セッションを見たメモです。
文中の画像やコードは公開情報から引用しています。
正確で詳しい内容をお求めの方は一次情報の確認をおすすめします。
A Peek at 3D Touch
A Peek at 3D Touch - WWDC 2016 - Videos - Apple Developer
ぐっ ぶっ ぴ のやつ。
こんなやつ。
こんなやつとか。
UIPreviewInteraction
新しいやつ。
アプリ内の3D Touchに関する技術。
3D Touchが扱いやすくなりましたよ。
UIPreviewInteractionDelegate
プロトコルに準拠します。
extension ChatDetailViewController :UIPreviewInteractionDelegate
UIPreviewInteraction
UIPreviewInteractionを生成します。
override func viewDidLoad() { super.viewDidLoad() replyPreviewInteraction = UIPreviewInteraction(view: view) replyPreviewInteraction.delegate = self }
状態が二段階になってる。
開始〜プレビューの状態と、プレビュー〜コミットの状態。
ぐっと押して、プレビュー表示の状態。
ぐぐっと押して、コミット完了した状態。
デリゲートメソッド
開始されたときのデリゲートメソッド。
previewInteractionShouldBegin()
開始〜プレビューまでの状態の時に、
押す強さが更新されたら呼ばれるデリゲートメソッド。
func previewInteraction(_ previewInteraction: UIPreviewInteraction, didUpdatePreviewTransition transitionProgress: CGFloat, ended: Bool) { //ビューの更新処理 updateForPreview(progress: transitionProgress) if ended { //プレビューの完了処理 completePreview() } }
プレビューがキャンセルされたら呼ばれるデリゲートメソッド。
指を離した時ですね。
func previewInteractionDidCancel(_ previewInteraction: UIPreviewInteraction) { //キャンセル処理 UIView.animate(withDuration: 0.4) { self.updateForPreview(progress: 0) self.resetToInitialAppearance() } }
プレビュー〜コミットまでの時に、
押す強さが更新されたら呼ばれるデリゲートメソッド。
func previewInteraction(_ previewInteraction: UIPreviewInteraction, didUpdateCommitTransition transitionProgress: CGFloat, ended: Bool) { //ビューの更新処理 updateForCommit(progress: transitionProgress) if ended { //コミットの完了処理 completeCommit() } }
感想
この操作ができることをどうやってユーザーに知らせるかが課題ではある。
扱いやすくなったのではりきって3D Touchするぞー!
WWDC2016セッションメモシリーズはこちら
WWDC2016 カテゴリーの記事一覧 - ROADTO みちログ
WWDCビデオ「A Peek at 3D Touch」拝聴。
— ひとのみち (@hitonomichi) 2016年6月26日
操作の速攻性はあるから使いたい。どうやってこの機能があるか知らせば良いのか。チュートリアルか。
WWDC2016セッションメモ「Advanced Notifications」
WWDC2016セッションを見たメモです。
文中の画像やコードは公開情報から引用しています。
正確で詳しい内容をお求めの方は一次情報の確認をおすすめします。
Advanced Notifications
Advanced Notifications - WWDC 2016 - Videos - Apple Developer
Media Attachments
{ aps: { alert: { ... }, mutable-content: 1 } my-attachment: "https://example.com/photo.jpg" }

// Adding an attachment to a user notification public class NotificationService: UNNotificationServiceExtension { override public func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: (UNNotificationContent) -> Void) { let fileURL = // ... let attachment = UNNotificationAttachment(identifier: "image", url: fileURL, options: nil) let content = request.content.mutableCopy as! UNMutableNotificationContent content.attachments = [ attachment ] contentHandler(content) } }
Media Attachments は、
Local notifications も Remote notifications も対応。
対応してるのは画像、音声、ビデオ。
時間やサイズに制限はあるよ。
Custom User Interface
通知内容を拡張できる。
ビューをカスタムできる。
通知アクションに応答する。
Notification Content Extension
「Notification Content」を選択。

UNNotificationContentExtension を継承したUIViewControllerのサブクラスができる。
カスタムビュー
class NotificationViewController: UIViewController, UNNotificationContentExtension { @IBOutlet var eventTitle: UILabel! @IBOutlet var eventDate: UILabel! @IBOutlet var eventLocation: UILabel! @IBOutlet var eventMessage: UILabel! func didReceive(_ notification: UNNotification) { let content = notification.request.content eventTitle.text = content.title eventDate.text = content.subtitle eventMessage.text = content.body if let location = content.userInfo["location"] as? String { eventLocation.text = location } } }
eventMessageの箇所

eventMessageの箇所

plistにいろいろ設定するらしい。


こうなる。
The Bash〜のところがUNNotificationExtensionInitialContentSizeRatioで措定されている。
Default content が非表示になってる。
メディアの追加
設定する。
// Notification Content Extension Attachments class NotificationViewController: UIViewController, UNNotificationContentExtension { @IBOutlet var eventImage: UIImageView! func didReceive(_ notification: UNNotification) { let content = notification.request.content if let attachment = content.attachments.first { if attachment.url.startAccessingSecurityScopedResource() { eventImage.image = UIImage(contentsOfFile: attachment.url.path!) attachment.url.stopAccessingSecurityScopedResource() } } } }
こうなる。

アクションとレスポンス
// Intercepting notification action response class NotificationViewController: UIViewController, UNNotificationContentExtension { func didReceive(_ response: UNNotificationResponse, completionHandler done: (UNNotificationContentExtensionResponseOption) -> Void) { server.postEventResponse(response.actionIdentifier) { if response.actionIdentifier == "accept" { eventResponse.text = "Going!" eventResponse.textColor = UIColor.green() } else if response.actionIdentifier == "decline" { eventResponse.text = "Not going :(" eventResponse.textColor = UIColor.red() } // done(.dismiss) done(.dismissAndForwardAction) } } } }
こうなる。

テキスト入力
UNNotificationCategoryをつくる。
// Text Input Action private func makeEventExtensionCategory() -> UNNotificationCategory { let commentAction = UNTextInputNotificationAction( identifier: "comment", title: "Comment", options: [], textInputButtonTitle: "Send", textInputPlaceholder: "Type here...") return UNNotificationCategory(identifier: "event-invite", actions: [ acceptAction, declineAction, commentAction ], }
こうなる。

// Text input action response class NotificationViewController: UIViewController, UNNotificationContentExtension { func didReceive(_ response: UNNotificationResponse, completionHandler done: (UNNotificationContentExtensionResponseOption) -> Void) { if let textResponse = response as? UNTextInputNotificationResponse { server.send(textResponse.userText) { done(.dismiss) } } } }
アクセサリーのカスタム(?)
// Custom input accessory view class NotificationViewController: UIViewController, UNNotificationContentExtension { override func canBecomeFirstResponder() -> Bool { return true } override var inputAccessoryView: UIView { get { return inputView } } func didReceive(_ response: UNNotificationResponse, completionHandler done: (UNNotificationContentExtensionResponseOption) -> Void) { } }
感想
出来ることが増えてここだけで機能完結できることもありそう。 がんばってリッチな通知するぞー!
WWDC2016セッションメモシリーズはこちら
WWDC2016 カテゴリーの記事一覧 - ROADTO みちログ
「Advanced Notifications」拝聴。通知に画像、音声、ビデオが対応。
— ひとのみち (@hitonomichi) 2016年6月24日
リッチ〜。
WWDC2016セッションメモ「Introduction to Notifications」
WWDC2016セッションを見たメモです。
文中の画像やコードは公開情報から引用しています。
正確で詳しい内容をお求めの方は一次情報の確認をおすすめします。
Introduction to Notifications
Introduction to Notifications - WWDC 2016 - Videos - Apple Developer
User Notifications Framework

watchOS単独でLocalNotificationが使える
Registration
使うのにRegistration が必要。
ローカルもリモートも必要。
UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted, error) in /* ... */}
ユーザ定義を設定する
UNUserNotificationCenter.current().getNotificationSettings { (settings) in /* ... */}
コンテンツ
TitleとSubtitleが追加された。
画像とかメディアも表示出来る。

Local Notification
let content = UNMutableNotificationContent() content.title = "Introduction to Notifications" content.subtitle = "Session 707" content.body = "Woah! These new notifications look amazing! Don’t you agree?" content.badge = 1
Remote Notification
{ "aps" : { "alert" : { "title" : "Introduction to Notifications", "subtitle" : "Session 707", "body" : "Woah! These new notifications look amazing! Don’t you agree?" }, "badge" : 1 }, }
トリガー
Time Interval
//2分後に発火 UNTimeIntervalNotificationTrigger(timeInterval: 120, repeats: false) //リピートするならrepeatsをtrueに。
Calendar
//「明日朝8時に」「毎週月曜日の18時に」とか指定できる。 let dateComponents = DateComponents() // dateComponentsに設定する UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
Location
//「家についたら」「アモーレと思い出の場所に近づいたら」とか指定できる。 let region = CLRegion() // ここでregionに設定する UNLocationNotificationTrigger(region: region, repeats: false)
どうやるのか

// Notification Delivery Summary import UserNotifications //許可 UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted, error) in // ... } //コンテンツ指定 let content = UNMutableNotificationContent() content.title = "Introduction to Notifications" content.body = "Let's talk about notifications!" //トリガー指定 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) //リクエスト作成 let requestIdentifier = "sampleRequest" let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger) //UNUserNotificationCenterに追加 UNUserNotificationCenter.current().add(request) { (error) in // ... }
ハンドリング
フォアグラウンドの時アプリ内表示ハンドリング
protocol UNUserNotificationCenterDelegate : NSObjectProtocol func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler handlerBlock: (UNNotificationPresentationOptions) -> Void) { // Roll banner and sound alert handlerBlock([.alert, .sound]) }
Notification Management
たくさんの通知うっとおしいよね。
最新の一件だけに更新できますよ。

保留の通知を消す
保留の通知を消すこともできますよ。
// Pending Notification Removal let gameStartIdentifier = "game1.start.identifier" let gameStartRequest = UNNotificationRequest(identifier: gameStartIdentifier, content: content, trigger: startTrigger) UNUserNotificationCenter.current().add(gameStartRequest) { (error) in // ... } // Game was cancelled UNUserNotificationCenter.current.current() .removePendingNotificationRequests(withIdentifiers: [gameStartIdentifier])
保留の通知を更新
保留の通知を更新することもできますよ。
// Pending Notification Update let gameStartIdentifier = "game1.start.identifier" let gameStartRequest = UNNotificationRequest(identifier: gameStartIdentifier, content: content, trigger: startTrigger) UNUserNotificationCenter.current().add(gameStartRequest) { (error) in // ... } // Game start time was updated let updatedGameStartRequest = UNNotificationRequest(identifier: gameStartIdentifier, content: content, trigger: newStartTrigger) UNUserNotificationCenter.current().add(updatedGameStartRequest) { (error) in // ... }
配信済みの通知を削除
// Delivered Notification Removal let gameScoreIdentifier = "game1.score.identifier" let gameScoreRequest = UNNotificationRequest(identifier: gameScoreIdentifier, content: scoreContent, trigger: trigger) UNUserNotificationCenter.current().add(gameScoreRequest) { (error) in // ... } // Wrong game score was published UNUserNotificationCenter.current() .removeDeliveredNotifications(withIdentifiers: [gameScoreIdentifier])
配信済みの通知を更新
// Delivered Notification Update let gameScoreIdentifier = "game1.score.identifier" let gameScoreRequest = UNNotificationRequest(identifier: gameScoreIdentifier, content: scoreContent, trigger: trigger) UNUserNotificationCenter.current().add(gameScoreRequest) { (error) in // ... } // Score game was updated let updateGameScoreRequest = UNNotificationRequest(identifier: gameScoreIdentifier, content: newScoreContent, trigger: newTrigger) UNUserNotificationCenter.current().add(updateGameScoreRequest) { (error) in // ... }
アクション付き通知
- ボタン付き
- 返信とかのテキスト入力
- iOSとwatchOSで使えます。

let action = UNNotificationAction(identifier:"reply",title:"Reply",options:[]) let category = UNNotificationCategory(identifier: "message", actions: [action], minimalActions: [action], intentIdentifiers: [], options: []) UNUserNotificationCenter.current().setNotificationCategories([category])
非表示アクション
通知をスワイプで消せますよ。
optionsに設定します。
customDismissAction: UNNotificationCategoryOptions let category = UNNotificationCategory(identifier: "message", actions: [action], minimalActions: [action], intentIdentifiers: [], options: [.customDismissAction])
感想
できること増えたね!
WWDC2016セッションメモシリーズはこちら
WWDC2016 カテゴリーの記事一覧 - ROADTO みちログ
「Introduction to Notifications」拝聴。出来ること増えたしツール系は嬉しい。
— ひとのみち (@hitonomichi) 2016年6月23日
ゲームにももちろん使えるけど広告になるとうざいかも。
WWDC2016セッションメモ「AVCapturePhotoOutput—Beyond the Basics」
WWDC2016セッションを見たメモです。
文中の画像やコードは公開情報から引用しています。
正確で詳しい内容をお求めの方は一次情報の確認をおすすめします。
AVCapturePhotoOutput—Beyond the Basics
AVCapturePhotoOutput - Beyond the Basics - WWDC 2016 - Videos - Apple Developer
アクセスの確認が変わった
iOS10からカメラ、音声、写真アクセスの許可時に理由の記載が必須になる。

設定はplistに追加する。
方法はこちら。
plistに直接書くならこう。
<plist version="1.0"> <dict> <key>NSCameraUsageDescription</key> <string>to take photos and video</string> <key>NSMicrophoneUsageDescription</key> <string>to record Live Photos and movies</string> <key>NSPhotoLibraryUsageDescription</key> <string>to save photos and videos</string> </dict> </plist>
感想
カメラはともかく写真使うの結構あるから対応しないと。
WWDC2016セッションメモシリーズはこちら
WWDC2016セッションメモ「What's New in Swift」
WWDC2016セッションを見たメモです。
文中の画像やコードは公開情報から引用しています。
正確で詳しい内容をお求めの方は一次情報の確認をおすすめします。
What's New in Swift
What's New in Swift - WWDC 2016 - Videos - Apple Developer
名前が変わった。
NSが付かなくなりますよ。
APIが変わった。
Swift2.2
↓↓↓
Swift3
パラメータのラベリングが変わった
Swift2.2
↓↓↓
Swift3
ひとつ目のパラメータにラベルが付いてわかりやすくなったね。
なくなるのもあるよ
インクリメントの++がなくなる。
昔からのfor文の書き方ができなくなる。
など。
マイグレーション
Swift2.2→3へ変換してくれる。
感想
張り切って変換するぞー。。
WWDC2016セッションメモシリーズはこちら
WWDC2016 カテゴリーの記事一覧 - ROADTO みちログ
What's New in Swiftから。今日は何本見れるかな。
— ひとのみち (@hitonomichi) 2016年6月15日
WWDC2016セッションメモ「Platforms State of the Union」
WWDC2016セッションを見たメモです。
文中の画像やコードは公開情報から引用しています。
正確で詳しい内容をお求めの方は一次情報の確認をおすすめします。
Platforms State of the Union
Platforms State of the Union - WWDC 2016 - Videos - Apple Developer
iMessage
MSConversation
MSSession
MSMessage
日本も対応。
スタンプを送ってそれに追加イメージして送るなんていう画像コミュニケーションができる。
SiriKit
車、料理など手が離せないことに向いてる。
ただし、出来ることは限られている。

Swift
短く簡単に書けるようになった。
Swift Praygrounds
シェアもできるよ。
Xcode
色のパレットが表示できるようになったよ。 イメージのイメージが表示できるようになったよ。
感想
プラットフォーム全体の状態がよくわかりました。
WWDC2016セッションメモシリーズはこちら
Road to シェアオフィスの話
今日から少し環境が変わりました。
出勤してる。
— ひとのみち (@hitonomichi) 2016年6月1日
経緯は縁
この毎日3時間の通勤時間を何に使うか。
— ひとのみち (@hitonomichi) 2016年6月1日