我正在尝试在Xcode 9测试版的应用中集成iOS 11拖放功能。 我很有兴趣创建一个可以被标准日历应用程序理解的NSItemProvider。我的拖动从UITableView开始,因此只实现了一个dragDelegate方法。
到目前为止,我尝试了以下内容:
let text = "Rendez-vous at \(clientName)"
let data = text.data(using: .utf8)
let itemProvider = NSItemProvider()
itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypeCalendarEvent as String, visibility: .all) { completion in
completion(data, nil)
return nil
}
let dragItem = UIDragItem(itemProvider: itemProvider)
并且还尝试使用类型标识符kUTTypePlainText。没有运气,日历应用程序没有注册掉落。
我找不到任何关于此的官方文档。我希望日历应用程序正在寻找一些标准的日历数据,这不仅限于相互通信的标准应用程序。例如,您可以从notes应用程序拖动文本并将其放入日历中以创建活动。
任何人都知道我可以尝试什么?
提前致谢。
答案 0 :(得分:3)
TL; DR :让默认iOS日历应用识别符合NSItemProviderWriting
协议的自定义对象的秘密因素是"com.apple.ical.ics"
类型标识符并导出您的自定义对象作为iCalendar字符串(vEvent
)。
我已经玩了好几天了,我终于成功了!我会尝试尽可能地分解我的步骤。
"com.apple.ical.ics"
。loadData
函数将尝试查找拖动目标(此方案中的日历应用程序)支持的标识符,以及您的应用程序也支持的标识符,尝试首先获得最高保真度。 例如:
public static var writableTypeIdentifiersForItemProvider: [String] {
return ["com.yourcompany.myEvent", "com.apple.ical.ics"]
}
public func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Void) -> Progress? {
switch typeIdentifier {
case "com.yourcompany.myEvent": // Your custom handling goes here
case "com.apple.ical.ics": completionHandler(createVEvent(), nil)
default: completionHandler(nil, YourAppError.someCustomError)
}
return nil
}
vEvent
字符串:
vCard
字符串。从该会话中签出演示项目。 vEvent
s,但有很多好消息here和here。这是一个建议:
private func createVEvent() -> Data? {
let today = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd'T'HHmmss'Z'"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let startDateString = dateFormatter.string(from: startDate)
let endDateString = dateFormatter.string(from: endDate)
let todayString = dateFormatter.string(from: today)
var vCalendarText = "BEGIN:VCALENDAR\n"
vCalendarText += "VERSION:2.0\n"
vCalendarText += "PRODID:-//Your Company//App Name//EN\n"
vCalendarText += "BEGIN:VEVENT\n"
vCalendarText += "UID:\(identifier.uuidString)\n"
vCalendarText += "SUMMARY:\(name)\n"
vCalendarText += "DTSTAMP:\(todayString)\n"
vCalendarText += "DTSTART:\(startDateString)\n"
vCalendarText += "DTEND:\(endDateString)\n"
vCalendarText += "END:VEVENT\n"
vCalendarText += "END:VCALENDAR"
return vCalendarText.data(using: .utf8)
}
↑类似于我之前提到过的那个会话演示中的createVCard()
函数......
那就是它!这几乎就是你所需要的。困难的部分是知道日历应用程序支持的标识符以及如何创建vEvent
。感谢quiker找到支持的标识符。
最后一个提示:您可以使用this nifty tool here验证您的iCalendar字符串。
请注意,这只允许删除您的自定义对象。 将一个事件从日历拖动到您的应用程序是一个不同的故事,但您可以从我的提示中找到它。 :)
快乐的编码!