如何设置自定义类型的粘贴板属性列表-NSPasteboard/Swift
我正在使用Cocoa应用程序在两个NSTableView之间拖放文件。我不想只使用URL,而是希望使用自定义结构,以便在需要时可以访问更多数据,而不必不断调用FileManager 我认为我需要实现将自定义粘贴板实用程序与NSPasteboardReading相一致,以便正确地消化接收表上的数据 我不确定在处理我在粘贴板中使用的自定义结构时,设置如何设置自定义类型的粘贴板属性列表-NSPasteboard/Swift,swift,cocoa,nstableview,nspasteboard,property-list,Swift,Cocoa,Nstableview,Nspasteboard,Property List,我正在使用Cocoa应用程序在两个NSTableView之间拖放文件。我不想只使用URL,而是希望使用自定义结构,以便在需要时可以访问更多数据,而不必不断调用FileManager 我认为我需要实现将自定义粘贴板实用程序与NSPasteboardReading相一致,以便正确地消化接收表上的数据 我不确定在处理我在粘贴板中使用的自定义结构时,设置init?(粘贴板属性列表属性列表:Any,of type:NSPasteboard.PasteboardType)函数需要什么 坦率地说,我不确定在这
init?(粘贴板属性列表属性列表:Any,of type:NSPasteboard.PasteboardType)
函数需要什么
坦率地说,我不确定在这种情况下如何使用属性列表,因为我过去通常只在设置全局应用程序plists时使用它
遗憾的是,这里没有太多的资源。我看到的大多数示例通常在属性列表中引用JSON对象。我不确定是否需要将数据从自定义类型提取到数据或字符串类型数组中
任何关于实施的指导,或者更好的关于财产清单的指导,都将不胜感激
传递到粘贴板的自定义结构:
表视图控制器:
我将项目写入粘贴板的位置
表视图控制器:
我要接受放置并移动文件的位置
自定义粘贴板实用程序:
首先,要能够拖放自定义对象,此对象必须是
NSObject
的子类
这是一个具有非可选类型的快速脏实现。数据通过Codable
与属性列表进行序列化。综合了协议方法init(从解码器
到编码器)和encode(到编码器
)
在init?(pasteboardPropertyList
中,您必须解码一个实例并使用标准初始值设定项创建一个新实例
final class TidiFile : NSObject, Codable {
var url : URL
var createdDateAttribute : Date
var modifiedDateAttribute : Date
var fileSizeAttribute: Int
init(url: URL, createdDateAttribute: Date, modifiedDateAttribute: Date, fileSizeAttribute: Int) {
self.url = url
self.createdDateAttribute = createdDateAttribute
self.modifiedDateAttribute = modifiedDateAttribute
self.fileSizeAttribute = fileSizeAttribute
}
convenience init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
guard let data = propertyList as? Data,
let tidi = try? PropertyListDecoder().decode(TidiFile.self, from: data) else { return nil }
self.init(url: tidi.url, createdDateAttribute: tidi.createdDateAttribute, modifiedDateAttribute: tidi.modifiedDateAttribute, fileSizeAttribute: tidi.fileSizeAttribute)
}
}
extension TidiFile : NSPasteboardWriting, NSPasteboardReading
{
public func writingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.WritingOptions {
return .promised
}
public func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
if type == .tidiFile {
return try? PropertyListEncoder().encode(self)
}
return nil
}
public static func readableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public static func readingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.ReadingOptions {
return .asData
}
}
首先,要能够拖放自定义对象,此对象必须是
NSObject
的子类
这是一个具有非可选类型的快速而肮脏的实现。数据通过Codable
与属性列表进行序列化。协议方法init(从解码器
和encode(到编码器
)被合成
在init?(pasteboardPropertyList
中,您必须解码一个实例并使用标准初始值设定项创建一个新实例
final class TidiFile : NSObject, Codable {
var url : URL
var createdDateAttribute : Date
var modifiedDateAttribute : Date
var fileSizeAttribute: Int
init(url: URL, createdDateAttribute: Date, modifiedDateAttribute: Date, fileSizeAttribute: Int) {
self.url = url
self.createdDateAttribute = createdDateAttribute
self.modifiedDateAttribute = modifiedDateAttribute
self.fileSizeAttribute = fileSizeAttribute
}
convenience init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
guard let data = propertyList as? Data,
let tidi = try? PropertyListDecoder().decode(TidiFile.self, from: data) else { return nil }
self.init(url: tidi.url, createdDateAttribute: tidi.createdDateAttribute, modifiedDateAttribute: tidi.modifiedDateAttribute, fileSizeAttribute: tidi.fileSizeAttribute)
}
}
extension TidiFile : NSPasteboardWriting, NSPasteboardReading
{
public func writingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.WritingOptions {
return .promised
}
public func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
if type == .tidiFile {
return try? PropertyListEncoder().encode(self)
}
return nil
}
public static func readableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public static func readingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.ReadingOptions {
return .asData
}
}
谢谢。这对我来说很有意义,因为NSObject和初始声明中的
便利init
。也就是说,在这个解决方案中,您是打算用扩展来代替定制的粘贴板实用工具粘贴板编写器
,还是支持其中所需的功能?谢谢您。我就NSObject和初始声明中的便利init
而言,t对我来说是有意义的。也就是说,在这个解决方案中,您是打算用扩展来代替定制的PasteboardUtility,PasteboardWriter
,还是支持其中所需的函数?
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
let pasteboard = info.draggingPasteboard
let pasteboardItems = pasteboard.pasteboardItems
}
import Foundation
import Cocoa
class PasteboardWriter: NSObject, NSPasteboardWriting, NSPasteboardReading {
required init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
// Need to implement
}
var tidiFile : TidiFile
var index: Int
init(tidiFile : TidiFile, at index: Int) {
self.tidiFile = tidiFile
self.index = index
}
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tableViewIndex, .tidiFile]
}
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
switch type {
case .tidiFile:
return tidiFile
case .tableViewIndex:
return index
default:
return nil
}
}
static func readableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tableViewIndex, .tidiFile]
}
}
extension NSPasteboard.PasteboardType {
static let tableViewIndex = NSPasteboard.PasteboardType("com.bradzellman.tableViewIndex")
static let tidiFile = NSPasteboard.PasteboardType("com.bradzellman.tidiFile")
}
extension NSPasteboardItem {
open func integer(forType type: NSPasteboard.PasteboardType) -> Int? {
guard let data = data(forType: type) else { return nil }
let plist = try? PropertyListSerialization.propertyList(
from: data,
options: .mutableContainers,
format: nil)
return plist as? Int
}
}
final class TidiFile : NSObject, Codable {
var url : URL
var createdDateAttribute : Date
var modifiedDateAttribute : Date
var fileSizeAttribute: Int
init(url: URL, createdDateAttribute: Date, modifiedDateAttribute: Date, fileSizeAttribute: Int) {
self.url = url
self.createdDateAttribute = createdDateAttribute
self.modifiedDateAttribute = modifiedDateAttribute
self.fileSizeAttribute = fileSizeAttribute
}
convenience init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
guard let data = propertyList as? Data,
let tidi = try? PropertyListDecoder().decode(TidiFile.self, from: data) else { return nil }
self.init(url: tidi.url, createdDateAttribute: tidi.createdDateAttribute, modifiedDateAttribute: tidi.modifiedDateAttribute, fileSizeAttribute: tidi.fileSizeAttribute)
}
}
extension TidiFile : NSPasteboardWriting, NSPasteboardReading
{
public func writingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.WritingOptions {
return .promised
}
public func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
if type == .tidiFile {
return try? PropertyListEncoder().encode(self)
}
return nil
}
public static func readableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
return [.tidiFile]
}
public static func readingOptions(forType type: NSPasteboard.PasteboardType, pasteboard: NSPasteboard) -> NSPasteboard.ReadingOptions {
return .asData
}
}