WWDC2016,Apple發布了ios10,每次版本發布,都會帶來新的接口,新的機會,也能間接的看到Apple的未來發展方向。
這里就不討論iphone7、MacBook Pro、Apple Watch、Apple TV以及AirPods了。
下面回顧一下,Apple今年為我們帶來了什么
一,一些限制
IPV6
HTTPS
1.IPV6
由于IPv4最大的問題在于網絡地址資源有限,嚴重制約了互聯網的應用和發展。IPv6的使用,不僅能解決網絡地址資源數量的問題,而且也解決了多種接入設備連入互聯網的障礙
6月1號以后提交新版本需要支持IPV6-Only的網絡
與IPv4地址空間需要擴充迫在眉睫,越來越多的企業和移動電話運營商部署IPv6 DNS64和NAT64網絡。DNS64 / NAT64網絡是一種能使ipv6網絡。取決于應用程序的性質,過渡有不同的含義:如果您正在編寫一個客戶端應用程序使用高級網絡api,如NSURLSession和CFNetwork框架,你應該不需要改變任何東西為您的應用程序使用IPv6地址。如果項目中用了老的AFNetworking或ASIHTTPRequest等第三方網絡請求框架則可能需要做一下適配。因為,蘋果審核是不會讓你過得。
客戶端向服務器端請求域名解析,首先通過DNS64 Server查詢IPv6的地址,如果查詢不到,再向DNS Server查詢IPv4地址,通過DNS64 Server合成一個IPV6的地址,最終將一個IPV6的地址返回給客戶端
關于IPV6的詳細介紹請見:
IPV6
2.HTTPS
前面一個大神已經詳細得介紹了HTTPS的相關知識,講得非常詳細,大家想看的話可以回顧一下。我在這也就不做過多贅述了。
HTTPS
- 2017年1月1日起,蘋果App Store中的所有App都必須啟用 App Transport Security(ATS)安全功能。(但延期了)
"應用傳輸安全協議是與iOS9和OS X 10.11一同發布的,該協議需要應用程序通過HTTPS使用安全的網絡連接,以提高用戶的數據和隱私安全。
在2016年WWDC上我們宣布在今年年底之前,提交到App Store的應用程序必須支持應用傳輸安全協議。為了給你們充裕的時間去準備,這個截止日期已被延長,當新的截止日期確定的時候,我們將及時提供相關信息。"
- App Transport Security(應用程序安全傳輸),簡稱 ATS,是蘋果在 iOS 9 中首次推出的一項隱私安全保護功能,啟用ATS后,它會屏蔽明文HTTP資源加載,強制App通過HTTPS連接網絡服務,通過傳輸加密保障用戶數據安全。
- ATS要求服務器必須支持傳輸層安全(TLS)協議1.2以上版本;證書必須使用SHA256或更高的哈希算法簽名;必須使用2048位以上RSA密鑰或256位以上ECC算法等等,不滿足條件的證書,ATS都會拒絕連接。強制開啟ATS體現了蘋果一貫的隱私保護態度。 開發者需要HTTPS證書。
二,ios10
IMessage
SiriKit
Speech Recognition
User Notifications
Others
1.IMessage
IMessage獲得重大更新,提供消息氣泡框效果,手寫信息。同時內置的emoji表情也得到優化,除了圖片變大3倍外,還能將文字直接轉化成emoji表情。蘋果還特別為IMessage開辟了應用專區,所以你也可以做IMessage App了。
使用Messages framework創建兩種類型的app extensions:
Sticker packs
IMessage apps
第一種方式僅僅提供靜態的貼紙,貼紙包圖片,用戶可以發送內聯消息附加到消息氣泡中。貼紙包不需要任何代碼。你添加標簽圖像文件拖到貼紙包文件夾內的貼紙資源目錄。有效的圖像文件必須符合以下規格:
- 圖片必須是png、apng、gif、jpeg中的一種
- 圖片必須小于500k
- 為了效果好,圖像不應少于100×100pt,或超過206×206pt
如果你想做這些事的時候你就要用到第二種方式了
Use iMessage apps to:
- Present a custom user interface inside the Messages app; see MSMessagesAppViewController.
- Create a custom or dynamic sticker browser; see MSStickerBrowserViewController.
- Insert text, stickers, or media files into the Messages app’s input field; see MSConversation.
- Create interactive messages that carry app-specific data; see MSMessage.
- Update interactive messages (for example, to create games or collaborative apps); see MSSession.
//example1作為一個貼紙瀏覽器
class MessagesViewController: MSMessagesAppViewController, MSStickerBrowserViewDataSource {
var stickers = [MSSticker]()
func loadStickers() {
for i in 1...2 {
if let url = Bundle.main.url(forResource: "Sticker \(i)", withExtension: "png"){
do {
let sticker = try MSSticker(contentsOfFileURL: url, localizedDescription: "")
stickers.append(sticker)
} catch {
print(error)
}
}
}
}
func createStickerBrowser() {
let controller = MSStickerBrowserViewController(stickerSize: .large)
addChildViewController(controller)
view.addSubview(controller.view)
controller.stickerBrowserView.backgroundColor = UIColor.purple
controller.stickerBrowserView.dataSource = self
view.topAnchor.constraint(equalTo: controller.view.topAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: controller.view.bottomAnchor).isActive = true
view.leftAnchor.constraint(equalTo: controller.view.leftAnchor).isActive = true
view.rightAnchor.constraint(equalTo: controller.view.rightAnchor).isActive = true
}
func numberOfStickers(in stickerBrowserView: MSStickerBrowserView) -> Int {
return stickers.count
}
func stickerBrowserView(_ stickerBrowserView: MSStickerBrowserView, stickerAt index: Int) -> MSSticker {
return stickers[index]
}
override func viewDidLoad() {
super.viewDidLoad()
loadStickers()
createStickerBrowser()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Conversation Handling
override func willBecomeActive(with conversation: MSConversation) {
}
override func didResignActive(with conversation: MSConversation) {
}
override func didReceive(_ message: MSMessage, conversation: MSConversation) {
}
override func didStartSending(_ message: MSMessage, conversation: MSConversation) {
}
override func didCancelSending(_ message: MSMessage, conversation: MSConversation) {
}
override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
}
override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
}
}
example2(交互式)
class MessagesViewController: MSMessagesAppViewController {
@IBOutlet weak var stepper: UIStepper!
@IBAction func didPress(button sender: AnyObject) {
if let image = createImageForMessage(), let conversation = activeConversation {
let layout = MSMessageTemplateLayout()
layout.image = image
layout.caption = "云萊塢"
let message = MSMessage()
message.layout = layout
message.url = URL(string: "http://www.yunlaiwu.com/")
conversation.insert(message, completionHandler: { (error) in
print(error ?? "no error")
})
}
}
func createImageForMessage() -> UIImage? {
let background = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
background.backgroundColor = UIColor.white
let label = UILabel(frame: CGRect(x: 75, y: 75, width: 150, height: 150))
label.font = UIFont.systemFont(ofSize: 56.0)
label.backgroundColor = UIColor.red
label.textColor = UIColor.white
label.text = "\(Int(stepper.value))"
label.textAlignment = .center
label.layer.cornerRadius = label.frame.size.width/2.0
label.clipsToBounds = true
let imageView = UIImageView(frame: CGRect(x: 0, y: 200, width: 300, height: 100))
imageView.image = UIImage(named:"Sticker 2")
background.addSubview(label)
background.addSubview(imageView)
background.frame.origin = CGPoint(x: view.frame.size.width, y: view.frame.size.height)
view.addSubview(background)
UIGraphicsBeginImageContextWithOptions(background.frame.size, false, UIScreen.main.scale)
background.drawHierarchy(in: background.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
background.removeFromSuperview()
return image
}
2.SiriKit
Apple 為我們開放了兩個framework讓我們更好的接入Siri
Intents、IntentsUI
Intents框架是必須支持的,支持基本應用程序和系統之間的通信。
IntentsUI框架是可選的,他提供了任務成功操作后的自定義UI接口。
它所包括的領域:
- VoIP calling
- Messaging
- Payments
- Photo
- Workouts
- Ride booking
- CarPlay (automotive vendors only)
- Restaurant reservations (requires additional support from Apple)
接入siri的注意事項:
- 證書支持
-
plist文件支持你所要的操作事件
siri.png
import Intents
// As an example, this class is set up to handle Message intents.
// You will want to replace this or add other intents as appropriate.
// The intents you wish to handle must be declared in the extension's Info.plist.
// You can test your example integration by saying things to Siri like:
// "Send a message using <myApp>"
// "<myApp> John saying hello"
// "Search for messages in <myApp>"
class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling {
override func handler(for intent: INIntent) -> Any {
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
return self
}
// MARK: - INSendMessageIntentHandling
// Implement resolution methods to provide additional information about your intent (optional).
func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void) {
if let recipients = intent.recipients {
// If no recipients were provided we'll need to prompt for a value.
if recipients.count == 0 {
completion([INPersonResolutionResult.needsValue()])
return
}
var resolutionResults = [INPersonResolutionResult]()
for recipient in recipients {
let matchingContacts = [recipient] // Implement your contact matching logic here to create an array of matching contacts
switch matchingContacts.count {
case 2 ... Int.max:
// We need Siri's help to ask user to pick one from the matches.
resolutionResults += [INPersonResolutionResult.disambiguation(with: matchingContacts)]
case 1:
// We have exactly one matching contact
resolutionResults += [INPersonResolutionResult.success(with: recipient)]
case 0:
// We have no contacts matching the description provided
resolutionResults += [INPersonResolutionResult.unsupported()]
default:
break
}
}
completion(resolutionResults)
}
}
func resolveContent(forSendMessage intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
if let text = intent.content, !text.isEmpty {
completion(INStringResolutionResult.success(with: text))
} else {
completion(INStringResolutionResult.needsValue())
}
}
// Once resolution is completed, perform validation on the intent and provide confirmation (optional).
func confirm(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
// Verify user is authenticated and your app is ready to send a message.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity)
completion(response)
}
// Handle the completed intent (required).
func handle(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
// Implement your application logic to send a message here.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
let response = INSendMessageIntentResponse(code: .success, userActivity: userActivity)
completion(response)
}
// Implement handlers for each intent you wish to handle. As an example for messages, you may wish to also handle searchForMessages and setMessageAttributes.
// MARK: - INSearchForMessagesIntentHandling
func handle(searchForMessages intent: INSearchForMessagesIntent, completion: @escaping (INSearchForMessagesIntentResponse) -> Void) {
// Implement your application logic to find a message that matches the information in the intent.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self))
let response = INSearchForMessagesIntentResponse(code: .success, userActivity: userActivity)
// Initialize with found message's attributes
response.messages = [INMessage(
identifier: "identifier",
content: "I am so excited about SiriKit!",
dateSent: Date(),
sender: INPerson(personHandle: INPersonHandle(value: "sarah@example.com", type: .emailAddress), nameComponents: nil, displayName: "Sarah", image: nil, contactIdentifier: nil, customIdentifier: nil),
recipients: [INPerson(personHandle: INPersonHandle(value: "+1-415-555-5555", type: .phoneNumber), nameComponents: nil, displayName: "John", image: nil, contactIdentifier: nil, customIdentifier: nil)]
)]
completion(response)
}
// MARK: - INSetMessageAttributeIntentHandling
func handle(setMessageAttribute intent: INSetMessageAttributeIntent, completion: @escaping (INSetMessageAttributeIntentResponse) -> Void) {
// Implement your application logic to set the message attribute here.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSetMessageAttributeIntent.self))
let response = INSetMessageAttributeIntentResponse(code: .success, userActivity: userActivity)
completion(response)
}
}
3.Speech Recognition
iOS 10引入了一個新的API,支持連續語音識別,可以將識別語音轉錄成文本??梢詧绦姓Z音實時轉錄和記錄音頻。
SpeechFramework框架中的重要類
SFSpeechRecognizer:這個類是語音識別的操作類,用于語音識別用戶權限的申請,語言環境的設置,語音模式的設置以及向Apple服務發送語音識別的請求。
SFSpeechRecognitionTask:這個類是語音識別服務請求任務類,每一個語音識別請求都可以抽象為一個SFSpeechRecognitionTask實例,其中SFSpeechRecognitionTaskDelegate協議中約定了許多請求任務過程中的監聽方法。
SFSpeechRecognitionRequest:語音識別請求類,需要通過其子類來進行實例化。
SFSpeechURLRecognitionRequest:通過音頻URL來創建語音識別請求。
SFSpeechAudioBufferRecognitionRequest:通過音頻流來創建語音識別請求。
SFSpeechRecognitionResult:語音識別請求結果類。
SFTranscription:語音轉換后的信息類。
當然,首先為了安全你得到plist文件中加權限
SFSpeechRecognizer.requestAuthorization { authStatus in
if authStatus == SFSpeechRecognizerAuthorizationStatus.authorized {
if let path = Bundle.main.url(forResource: "PPAP", withExtension: ".mp3") {
let recognizer = SFSpeechRecognizer()
let request = SFSpeechURLRecognitionRequest(url: path)
recognizer?.recognitionTask(with: request, resultHandler: { (result, error) in
if let error = error {
print("There was an error: \(error)")
} else {
print(result?.bestTranscription.formattedString)
}
})
}
}
}
4.User Notifications
支持了很多用戶定義的通知,并且可以捕捉到各個通知狀態的回調。以往的通知是大家想接收的都提前做好準備,然后一下全量分發,沒收到也不管了,也不關心發送者?,F在用戶通知做成了和網絡請求有點像,一個request,response的流程,也支持了error處理,可以在各個狀態的方法中做一些額外操作,并且也能取到一些字段,如發送者等。
更為重要的是,新增了UserNotificationsUI.framework框架,在收到通知的時候,可自定義通知UI樣式
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert,.badge,.sound]) { (granted, error) in
if granted {
print("授權成功")
}else{
print("授權失敗")
}
}
let content = UNMutableNotificationContent()
content.title = "云萊塢 PPAP"
content.body = "I have a pen I have an apple"
content.subtitle = "have a pineapple"
content.sound = UNNotificationSound.default()
let trigger1 = UNTimeIntervalNotificationTrigger(timeInterval: 61, repeats: true)
let request = UNNotificationRequest(identifier: "notificationTest", content: content, trigger:trigger1)
UNUserNotificationCenter.current().add(request) { (error) in
if (error != nil) {
print(error?.localizedDescription)
}
}
5.Others
- CallKit 集成了VoIP及信息標識,還有了黑名單功能,當然不是云萊塢的黑名單
//開始請求的方法,在打開設置-電話-來電阻止與身份識別開關時,系統自動調用
- (void)beginRequestWithExtensionContext:(CXCallDirectoryExtensionContext *)context;
//添加黑名單:根據生產的模板,只需要修改CXCallDirectoryPhoneNumber數組,數組內號碼要按升序排列
- (BOOL)addBlockingPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context;
// 添加信息標識:需要修改CXCallDirectoryPhoneNumber數組和對應的標識數組;CXCallDirectoryPhoneNumber數組存放的號碼和標識數組存放的標識要一一對應,CXCallDirectoryPhoneNumber數組內的號碼要按升序排列
- (BOOL)addIdentificationPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context;
- Wide Color 寬域顏色
@available(iOS 10.0, *)
public init(displayP3Red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
- Adapting to the True Tone Display 真彩色顯示
UIWhitePointAdaptivityStyle
共有五種選擇:
UIWhitePointAdaptivityStyleStandard 標準
UIWhitePointAdaptivityStyleReading 閱讀
UIWhitePointAdaptivityStylePhoto 圖片
UIWhitePointAdaptivityStyleVideo 視頻
UIWhitePointAdaptivityStyleGame 游戲
App Search Enhancements 應用搜索增強
Widget Enhancements 鎖屏部件增強
News Publisher Enhancements 新聞出版商增強
Apple Pay Enhancements 支付增強
Security and Privacy Enhancements 安全和保密性增強
三,swift3.0
1.去除了swift2系列棄用得特性
2.語法精簡,更加哲理性(這詞用得好啊)
3.響應式,函數式,面向協議等語言現代化。
let queue = dispatch_queue_create("this is Swift 2.2", nil)
dispatch_async(queue) {
print("Swift 2.2 queue")
}
Swift 3 取消了這種冗余的寫法,而采用了更為面向對象的方式:
let queue = DispatchQueue(label: "this is Swift 3.0")
queue.async {
print("Swift 3 queue")
}
當然,問題還很多,但4.0就快來了
四,watchOS3.0,tvOS,AppStore,macOS Sierra...
1.watchOS3.0
- 新增智能回覆與 Scribble 功能,可在表面手寫文字用以回覆訊息。
- 新增 SOS 功能,其支持全球的語言與緊急電話,危急時刻可立即通話或發出訊息。
- 新增的《Breathe》App 能提醒用戶休息片刻、多做深呼吸。
- 《活動記錄》App 加入 Activity Sharing 功能,能將您個人的活動量分享給親朋好友或健身教練,與他人運動競爭或幫助維持健康?!痘顒佑涗洝犯槍Τ俗喴蔚臍堈嫌脩魞灮O計,提醒何時該稍做休息。
2.tvOS
整合 Siri,用以加強語音搜索功能。此外,tvOS 將新增 Single Sign-on 功能,僅需登入一次即可瀏覽所有付費電視頻道。
當然,國內是被墻的
3.AppStore
AppStore 2.0 變革:更改拆帳比例、置入搜索廣告、縮短審查時間
4.macOS Sierra
- 新增 Auto Unlock 功能,當用戶戴著配對認證的 Apple Watch 開啟 Mac 電腦立即自動登入,無須輸入密碼。
- 新增 Universal Clipboard 功能,使用 iCloud 可跨蘋果設備復制與貼上文字、照片、影片等。
- 使用 iCloud Drive,將允許多部 Mac 電腦共用桌面,而且 iPhone、iPad 也能存取桌面上的檔案。
- 新增 Optimized Storage 功能,當 Mac 電腦容量不足,自動將不常用的檔案上傳 iCloud,提醒用戶清空垃圾桶。
- 線上付款將支持 Apple Pay,搭配 iPhone 或 Apple Watch 快速且安全地完成網購的付款動作。
- 包括《地圖》、《郵件》、《Pages》、《Numbers》、《Keynote》甚至第三方 Apps 將支持分頁功能。
- Safari 與 iTunes 新增 Picture in Picture 功能,以子母畫面的方式觀賞影片。
- 加入 Siri 功能,可在 macOS Sierra 當中語音搜索訊息、文件、照片、網頁等,甚至語音建立備忘錄或開啟 FaceTime 視訊。登陸 macOS Sierra 之后,Siri 終能跨蘋果四大平臺使用。