Skip to content

Commit

Permalink
Use UTType.utf8PlainText (explicit encoding) instead of `kUTTypePla…
Browse files Browse the repository at this point in the history
…inText`

Since newer versions of iOS use this new `public.utf8-plain-text` UTI instead of `public.plain-text` like in previous OS versions.
  • Loading branch information
AliSoftware committed Apr 18, 2024
1 parent 665b15b commit 90c0e4d
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 30 deletions.
3 changes: 2 additions & 1 deletion Aztec/Classes/Extensions/NSAttributedString+Archive.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Foundation
import UIKit

// MARK: - NSAttributedString Archive methods
//
extension NSAttributedString
{
static let pastesboardUTI = "com.wordpress.aztec.attributedString"
static let pasteboardUTI = UIPasteboard.UTType(identifier: "com.wordpress.aztec.attributedString")

func archivedData() throws -> Data {
return try NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
Expand Down
87 changes: 78 additions & 9 deletions Aztec/Classes/Extensions/UIPasteboard+Helpers.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import UniformTypeIdentifiers
import MobileCoreServices
import UIKit

Expand Down Expand Up @@ -30,24 +31,92 @@ extension UIPasteboard {
}

func html() -> String? {
guard let htmlData = data(forPasteboardType: String(kUTTypeHTML)) else {
guard let htmlData = data(forPasteboardType: UTType.html.identifier) else {
return nil
}

return String(data: htmlData, encoding: .utf8)
}

// Compatibility Helper for using UTType before iOS14's UniformTypeIdentifiers
// Feel free to remove once Deployment Target of the project gets bumped to >14.0
struct UTType {
let identifier: String

static let html: UTType = {
UTType(identifier: {
if #available(iOS 14.0, *) {
UniformTypeIdentifiers.UTType.html.identifier
} else {
kUTTypeHTML as String
}
}())
}()
static let plainText: UTType = {
UTType(identifier: {
if #available(iOS 14.0, *) {
UniformTypeIdentifiers.UTType.utf8PlainText.identifier
} else {
kUTTypeUTF8PlainText as String
}
}())
}()
static let richText: UTType = {
UTType(identifier: {
if #available(iOS 14.0, *) {
UniformTypeIdentifiers.UTType.text.identifier
} else {
kUTTypeText as String
}
}())
}()
static let RTFText: UTType = {
UTType(identifier: {
if #available(iOS 14.0, *) {
UniformTypeIdentifiers.UTType.rtf.identifier
} else {
kUTTypeRTF as String
}
}())
}()
static let RTFDText: UTType = {
UTType(identifier: {
if #available(iOS 14.0, *) {
UniformTypeIdentifiers.UTType.flatRTFD.identifier
} else {
kUTTypeFlatRTFD as String
}
}())
}()
static let URL: UTType = {
UTType(identifier: {
if #available(iOS 14.0, *) {
UniformTypeIdentifiers.UTType.url.identifier
} else {
kUTTypeURL as String
}
}())
}()
}

func store(_ data: Any, as type: UTType) {
if numberOfItems > 0 {
items[0][type.identifier] = data
} else {
addItems([[type.identifier: data]])
}
}
}

// MARK: - Attributed String Conversion

private extension UIPasteboard {

// MARK: -

/// Attempts to unarchive the Pasteboard's Aztec-Archived String
///
private func aztecAttributedString() -> NSAttributedString? {
guard let data = data(forPasteboardType: NSAttributedString.pastesboardUTI) else {
guard let data = data(forPasteboardType: NSAttributedString.pasteboardUTI.identifier) else {
return nil
}

Expand All @@ -57,25 +126,25 @@ private extension UIPasteboard {
/// Attempts to unarchive the Pasteboard's Plain Text contents into an Attributed String
///
private func plainTextAttributedString() -> NSAttributedString? {
return unarchiveAttributedString(fromPasteboardCFType: kUTTypePlainText, with: StringOptions.plainText)
return unarchiveAttributedString(fromPasteboardType: .plainText, with: StringOptions.plainText)
}

/// Attempts to unarchive the Pasteboard's Text contents into an Attributed String
///
private func richTextAttributedString() -> NSAttributedString? {
return unarchiveAttributedString(fromPasteboardCFType: kUTTypeText, with: StringOptions.RTFText)
return unarchiveAttributedString(fromPasteboardType: .richText, with: StringOptions.RTFText)
}

/// Attempts to unarchive the Pasteboard's RTF contents into an Attributed String
///
private func rtfAttributedString() -> NSAttributedString? {
return unarchiveAttributedString(fromPasteboardCFType: kUTTypeRTF, with: StringOptions.RTFText)
return unarchiveAttributedString(fromPasteboardType: .RTFText, with: StringOptions.RTFText)
}

/// Attempts to unarchive the Pasteboard's RTFD contents into an Attributed String
///
private func rtfdAttributedString() -> NSAttributedString? {
return unarchiveAttributedString(fromPasteboardCFType: kUTTypeFlatRTFD, with: StringOptions.RTFDText)
return unarchiveAttributedString(fromPasteboardType: .RTFDText, with: StringOptions.RTFDText)
}

// MARK: - Helpers
Expand All @@ -97,8 +166,8 @@ private extension UIPasteboard {
///
/// - Returns: NSAttributed String with the contents of the specified Pasteboard entry, if any.
///
private func unarchiveAttributedString(fromPasteboardCFType type: CFString, with options: [DocumentReadingOptionKey: Any]) -> NSAttributedString? {
guard let data = data(forPasteboardType: String(type)) else {
private func unarchiveAttributedString(fromPasteboardType type: UTType, with options: [DocumentReadingOptionKey: Any]) -> NSAttributedString? {
guard let data = data(forPasteboardType: type.identifier) else {
return nil
}

Expand Down
18 changes: 3 additions & 15 deletions Aztec/Classes/TextKit/TextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -668,27 +668,15 @@ open class TextView: UITextView {
// MARK: - Pasteboard Helpers

internal func storeInPasteboard(encoded data: Data) {
if pasteboard.numberOfItems > 0 {
pasteboard.items[0][NSAttributedString.pastesboardUTI] = data
} else {
pasteboard.addItems([[NSAttributedString.pastesboardUTI: data]])
}
pasteboard.store(data, as: NSAttributedString.pasteboardUTI)
}

internal func storeInPasteboard(html: String) {
if pasteboard.numberOfItems > 0 {
pasteboard.items[0][kUTTypeHTML as String] = html
} else {
pasteboard.addItems([[kUTTypeHTML as String: html]])
}
pasteboard.store(html, as: .html)
}

internal func storeInPasteboard(plain: String) {
if pasteboard.numberOfItems > 0 {
pasteboard.items[0][kUTTypePlainText as String] = plain
} else {
pasteboard.addItems([[kUTTypePlainText as String: plain]])
}
pasteboard.store(plain, as: .plainText)
}

// MARK: - Intercept keyboard operations
Expand Down
4 changes: 2 additions & 2 deletions AztecTests/Extensions/UIPasteboardHelpersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class UIPasteboardHelpersTests: XCTestCase {
return
}

pasteboard.setData(data, forPasteboardType: String(kUTTypeFlatRTFD))
pasteboard.setData(data, forPasteboardType: UIPasteboard.UTType.RTFDText.identifier)

guard let pastedString = pasteboard.attributedString() else {
XCTFail()
Expand All @@ -46,7 +46,7 @@ class UIPasteboardHelpersTests: XCTestCase {
let pasteboard = UIPasteboard.forTesting
let html = "<p>testing</p>"

pasteboard.setValue(html, forPasteboardType: String(kUTTypeHTML))
pasteboard.setValue(html, forPasteboardType: UIPasteboard.UTType.html.identifier)

XCTAssertEqual(pasteboard.html(), html)
}
Expand Down
6 changes: 3 additions & 3 deletions AztecTests/TextKit/TextViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1985,7 +1985,7 @@ class TextViewTests: XCTestCase {
let textView = TextViewStub(withHTML: "")

let url = URL(string: "http://wordpress.com")!
UIPasteboard.forTesting.setValue(url, forPasteboardType: String(kUTTypeURL))
UIPasteboard.forTesting.setValue(url, forPasteboardType: UIPasteboard.UTType.URL.identifier)

textView.paste(nil)

Expand All @@ -1997,7 +1997,7 @@ class TextViewTests: XCTestCase {
let textView = TextViewStub(withHTML: "WordPress")

let url = URL(string: "http://wordpress.com")!
UIPasteboard.forTesting.setValue(url, forPasteboardType: String(kUTTypeURL))
UIPasteboard.forTesting.setValue(url, forPasteboardType: UIPasteboard.UTType.URL.identifier)
textView.selectedRange = NSRange(location: 0, length: 9)
textView.paste(nil)

Expand Down Expand Up @@ -2082,7 +2082,7 @@ class TextViewTests: XCTestCase {
func testPasteAttributedText() {
let sourceAttributedText = NSAttributedString(string: "Hello world")
var pasteItems = [String:Any]()
pasteItems[kUTTypePlainText as String] = try! sourceAttributedText.data(from: sourceAttributedText.rangeOfEntireString, documentAttributes: [.documentType: DocumentType.plain])
pasteItems[UIPasteboard.UTType.plainText.identifier] = try! sourceAttributedText.data(from: sourceAttributedText.rangeOfEntireString, documentAttributes: [.documentType: DocumentType.plain])
UIPasteboard.forTesting.setItems([pasteItems], options: [:])
let textView = TextViewStub(withHTML: "")
textView.textColor = UIColor.red
Expand Down

0 comments on commit 90c0e4d

Please sign in to comment.