calendar - iOS 11 拖放 : dropping on standard Calendar app

标签 calendar drag-and-drop ios11

我正在尝试将 iOS 11 拖放功能集成到来自 Xcode 9 beta 的应用程序中。 我对创建标准日历应用程序可以理解的 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。不走运,日历应用程序没有记录掉落。

我找不到关于此的任何官方文档。我希望日历应用程序正在寻找一些标准的日历数据,而这不仅限于相互通信的标准应用程序。例如,您可以将笔记应用中的文本拖放到日历中以创建事件。

有人知道我可以尝试什么吗?

提前致谢。

最佳答案

TL;DR:让默认 iOS 日历应用程序识别符合 NSItemProviderWriting 协议(protocol)的自定义对象的秘诀是 "com.apple .ical.ics" 类型标识符并将自定义对象导出为 iCalendar 字符串 (vEvent)。


我已经研究了几天,终于成功了!我会尝试尽可能分解我的步骤。

  1. 创建符合 NSItemProviderWriting 的自定义对象:
    • 要遵守协议(protocol),您需要实现 writableTypeIdentifiersForItemProviderloadData(withTypeIdentifier:, forItemProviderCompletionHandler:) .
    • 标识符数组是您可以导出的类型标识符的列表,按保真度顺序排列,保真度最高的在前。所以把你的自定义类型标识符放在第一位,然后包括 "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
}
  1. 使用您的自定义事件信息创建一个 iCalendar vEvent 字符串:
    • 此步骤与 Session 227 中的演示非常相似来自 WWDC 2017,在那里他们为自定义联系人创建了一个 vCard 字符串。从该 session 中 check out 演示项目。
    • 基本上,日历应用程序支持几种特定类型的类型标识符,iCal 格式就是其中之一。因此,您只需要创建一个辅助方法将您的自定义事件类型转换为 iCalendar。字符串。
    • 我不会详细介绍 vEvent,但是有很多有用的信息 herehere .

这里有一个建议:

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)
}

↑ 类似于我之前提到的 session 演示中的 createVCard() 函数……

就是这样!这几乎就是您所需要的。困难的部分是了解日历应用程序支持的标识符以及如何制作 vEvent。感谢quiker用于查找支持的标识符。

最后一个提示:您可以使用 this nifty tool here 验证您的 iCalendar 字符串.

请注意,这只允许删除您的自定义对象。 将事件从日历拖到您的应用程序是另一回事,但您可以从我这里的提示中弄清楚。 :)

编码愉快!

关于calendar - iOS 11 拖放 : dropping on standard Calendar app,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45457789/

相关文章:

ios - 日期转换不当?

cocoa - 拖放到非 View

android - 在可扩展 ListView 中拖放(Android)

jQuery HTML5 文件拖放

ios - 在 iOS 11 中编辑文本字段时 uitableViewCell 不向上滚动

具有自定义 ID 的 Java TimeZone 不考虑夏令时

java GregorianCalendar 添加小时奇怪的行为

ios - 解散弹出窗口后的第一响应者/焦点

javascript - Firebase 查询不返回数据

ios - 如何检测 iOS 11+ Safari 以及旧版本 Safari 中的隐私浏览?