在macOS和iOS上查看電子郵件時,郵件會在[檢測到的日期和時間]下劃線 。您能夠與他們互動以建立新的日曆事件。若是您在「日曆」中打開此類活動,則會在其擴展詳細信息中看到「在郵件中顯示」連接。單擊此連接可將您帶回到原始電子郵件。此功能能夠追溯到iPhone的發佈。它將被歸入當年的 [Mac OS X版本(Leopard)中,] 這將標誌着許多移動功能中的第一個進入臺式機。html
若是要將「魔術」 URL複製到粘貼板並在文本編輯器中查看,則會看到如下內容:web
"message:%3C1572873882024.NSHIPSTER%40mail.example.com%3E"
經驗豐富的iOS開發人員將當即意識到使用 [自定義URL方案]。其中精通網絡的用戶能夠對主機進行百分比解碼,並識別出它相似於電子郵件地址,但事實並不是如此。express
所以,若是沒有電子郵件地址,咱們在這裏看什麼?
這是另外一個不一樣的電子郵件字段,稱爲Message-ID。swift
另外,若是你想一塊兒進階,不妨添加一下交流羣[1012951431],選擇加入一塊兒交流,一塊兒學習。期待你的加入!(進羣可領取學習禮包)瀏覽器
[RFC 5322§3.6.4]規定,每封電子郵件應該 具備「消息ID:」字段包含單個惟一消息標識符。該標識符的語法本質上是一個帶有尖括號(< >)的電子郵件地址。安全
儘管該規範未包含任何有關生成良好Message-ID的規範性指導,但 1998年的[IETF草案草稿]仍是很不錯的。ruby
讓咱們看一下如何在Swift中執行此操做:網絡
前述文檔中描述的第一種技術涉及生成帶有64位隨機數的隨機消息ID,該消息ID帶有時間戳,以進一步減小衝突的機會。咱們可使用Swift 5內置的隨機數生成器API和[String(_:radix:uppercase:)初始化]程序來輕鬆完成此操做 :app
import Foundation let timestamp = String(Int(Date().timeIntervalSince1970 * 1000)) let nonce = String(UInt64.random(in: 0..<UInt64.max), radix: 36, uppercase: true) let domain = "mail.example.com" let MessageID = "<\(timestamp).\(nonce)@\(domain)>" //"<1572873882024.NSHIPSTER@mail.example.com>"
而後,咱們能夠將生成的Message-ID與關聯的記錄一塊兒保存,以便之後連接到它。可是,在許多狀況下,一種更簡單的選擇是使消息ID具備肯定性,而且能夠從其現有狀態進行計算。框架
考慮符合[Identifiable協議]且其關聯`ID`類型爲 [UUID]的記錄結構 。您能夠這樣生成消息ID:
import Foundation func messageID<Value>(for value: Value, domain: String) -> String where Value: Identifiable, Value.ID == UUID { return "<\(value.id.uuidString)@\(domain)>" }
若是缺乏持久性標識符(或任何其餘區別功能),則能夠改用消息正文自己的摘要來生成消息ID。這是使用新的[CryptoKit框架]的示例實現 :
import Foundation import CryptoKit let body = #""" Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. """# let digest = Data(SHA256.hash(data: body.data(using: .utf8)!)) .map { String($0, radix: 16, uppercase: true) } .joined() let domain = "ADF" "<\(digest)@\(domain)>" // "<F52380112175FCE8ECF2731C193EB8A7CC8642E53C68D292CD88531D42F145@mail.example.com>"
iOS和macOS上的常規Mail客戶端都將嘗試`message:`經過啓動到前臺並嘗試使用編碼的Message-ID字段打開消息來使用自定義方案打開URL 。
掌握了Message-ID以後,最後的任務是建立一個深層連接,您可使用該深層連接將Mail打開到關聯的消息。惟一的技巧是 在URL中對消息ID 進行 [百分比編碼]。您可使用[方法]來執行此操做 ,可是咱們更願意將全部操做委託給-這具備進一步的優點,即無需使用[格式字符串]就能夠完整構建URL 。[`adding PercentEncoding(withAllowedCharacters:)`][`URLComponents`]
import Foundation var components = URLComponents() components.scheme = "message" components.host = MessageID components.string! // "message://%3C1572873882024.NSHIPSTER%40mail.example.com%3E"
據咱們所知,自定義`message:`方案後是否存在雙斜槓不會對郵件深層連接解析產生任何影響。
若是您`message:`在iOS上打開URL,而且能夠從 其中一個賬戶的inbox輕鬆訪問連接的消息,則Mail將當即啓動該消息。若是找不到該消息,則該應用程序將啓動並在後臺異步加載該消息,並在可用時將其打開。相比之下,嘗試在macOS上打開到還沒有加載的郵件的郵件深層連接會致使顯示警報模式。所以,咱們建議僅在iOS上使用郵件深層連接。例如, [飛行學校]使用無密碼身份驗證系統來執行此操做。要訪問書籍的電子副本,請輸入用於購買書籍的電子郵件地址。提交表單後,iOS上的用戶將看到一個深層連接,用於打開指向包含「魔術登陸連接」✨的電子郵件的Mail應用程序。
其餘系統可能使用消息ID經過[通用連接]簡化其本機應用或網站的無密碼身份驗證 ,或者將其合併爲2fa策略的一部分 (由於[出於此目的,再也不認爲][sms是安全的])。若是您在Web應用程序中使用Rails,則 [ActiveMailer攔截器]提供了一種方便的方式來Message-ID爲無密碼驗證流注入字段。
與蘋果平臺上如此衆多的私人集成(仍然是第一方應用程序的專有領域)不一樣,「在郵件中顯示」的祕密之處在於咱們全部人都能參與進來。儘管沒有記錄,可是因爲該功能與系統的深度集成以及植根於基本Web標準中,所以該功能不太可能很快被刪除。
從[瀏覽器供應商], [社交媒體公司]到 [政府](甚至有時甚至是蘋果[公司)的]每一個人都 試圖拆開開放的網絡並控制咱們能夠看到和執行的操做時,很高興得知電子郵件 [將近50年了],保持互聯網自由和分散的能力仍然堅定。
翻譯地址: https://nshipster.com/message-id/