相信有不少人都会将临时代办事项记录在 iPhone「提醒事项」App内,如果想要将 iOS「提醒事项」自动同步到「行事历」内要怎么做? 同步功能似乎需要依赖第三方App才能达成,那有没有免费又能快速解决的方案?
其实要让iOS提醒事项与行事历同步透过捷径自动化就能轻松实现,这篇就来分享搭配自动化 Scripts 脚本,实现每次透过 iPhone 提醒事项纪录生活琐碎的事情,都能自动同步到行事历内。

通常 iOS 内建「提醒事项」App,如果要将代办事项同步到行事历内,都要手动点选才能搬移加入,这种做法非常不人性化,反而比较推荐让行事历与提醒事项同步会更智慧又省时,实现效果如下画面,当 iPhone 在提醒事项内增加后,就会立即同步到行事历内,省去要手动搬移的步骤,实现步骤可参考底下iPhone行事历如何同步提醒事项教学:

如何将 iPhone行事历同步提醒事项教学
目录
本篇教学不管是iPhone或iPad设备都能使用,系统需iOS 14或iPadOS 14或以上。
1. 替iOS行事历与提醒事项建立相同列表
要实现 iPhone 行事历与提醒事项同步功能,要在两款 App 内都建立相同的列表名称,后续才能同步。
先打开「提醒事项」App,点选右下角「新增列表」,自订想同步的列表名。

接下来开启 iOS 内建「行事历」App,点选底下「行事历」会进入行事历列表列表,点选左下角「加入行事历」。

输入与「提醒事项」App 相同的列表名称,按下右上角「完成」,后续想将重要事情纪录在同步的列表内即可。

2. 建立 Scripts 同步脚本
为了能够实现 iPhone 内建行事历与提醒事项同步,我们需要利用「Scripts App」来运行自动化 JavaScript 脚本。
Scriptable App Store 下载:https://apps.apple.com/cn/app/scriptable/id1405459188
载并且打开「Scripts」App,点选右上角「+」新增按钮,会出现新的脚本页面,点击上方「Untitled Script」文字后,将名称改为「提醒事项同步行事历」。

并且将后面的 iOS 提醒事项同步日历代码直接复制粘贴,按下 Done 关闭。

iOS 提醒事项同步行事历代码
脚本原作者:汀力
var dur_month = 1 const startDate = new Date() startDate.setMonth(startDate.getMonth() - dur_month) console.log(`日曆的開始時間 ${startDate.toLocaleDateString()}`) const endDate = new Date() endDate.setMonth(endDate.getMonth() + dur_month) console.log(`日曆的結束時間 ${endDate.toLocaleDateString()}`) const reminders = await Reminder.allDueBetween(startDate, endDate) console.log(`獲取 ${reminders.length} 條提醒事項`) var calendar = await Calendar.forEvents() //獲取日曆名和對應的日曆 var m_dict = {} for(cal of calendar) { m_dict[cal.title] = cal //console.log(`日曆:${cal.title}`) } const events = await CalendarEvent.between(startDate, endDate, calendar) console.log(`獲取 ${events.length} 條日曆`) var reminders_id_set = new Set(reminders.map(e=>e.identifier)) //刪除日曆里提醒事項刪除的事項 events_created = events.filter(e=>e.notes != null && e.notes.includes("[Reminder]")) for(let event of events_created){ //console.warn(event.notes) let reg = /(\[Reminder\])\s([A-Z0-9\-]*)/ let r = event.notes.match(reg) //if(r) console.log(r[2]) if(!reminders_id_set.has(r[2])) { event.remove() } } for (const reminder of reminders) { //reminder的標識符 const targetNote = `[Reminder] ${reminder.identifier}` const [targetEvent] = events.filter(e => e.notes != null && e.notes.includes(targetNote))//過濾重復的reminder if(!m_dict[reminder.calendar.title]) { console.warn("找不到日曆"+ reminder.calendar.title) continue } if (targetEvent) { //console.log(`找到已經創建的事項 ${reminder.title}`) updateEvent(targetEvent, reminder) } else { console.warn(`創建事項 ${reminder.title} 到 ${reminder.calendar.title}`) const newEvent = new CalendarEvent() newEvent.notes = targetNote + "\n" + reminder.notes//要加入備注 updateEvent(newEvent, reminder) } } Script.complete() function updateEvent(event, reminder) { event.title = `${reminder.title}` cal_name = reminder.calendar.title cal = m_dict[cal_name] event.calendar = cal //console.warn(event.calendar.title) //已完成事項 if(reminder.isCompleted) { event.title = `✅${reminder.title}` event.isAllDay = true event.startDate = reminder.dueDate event.endDate=reminder.dueDate // var ending = new Date(reminder.completionDate) // ending.setHours(ending.getHours()+1) // event.endDate = ending var period = (reminder.dueDate-reminder.completionDate)/1000/3600/24 period = period.toFixed(1) if(period < 0) { period = -period event.location = " 延期" + period + "天完成" } else if (period == 0) { event.location = " 準時完成" } else { event.location = " 提前" + period + "天完成" } } //未完成事項 else{ const nowtime = new Date() var period = (reminder.dueDate-nowtime)/1000/3600/24 period = period.toFixed(1) //console.log(reminder.title+(period)) if(period < 0) { //待辦順延 event.location = " 延期" + (-period) + "天" //如果不是在同一天,設置為全天事項 if(reminder.dueDate.getDate() != nowtime.getDate()) { event.title = `❌${reminder.title}` event.startDate = nowtime event.endDate = nowtime event.isAllDay = true } //在同一天的保持原來的時間 else { event.title = `⭕️${reminder.title}` event.isAllDay = false event.startDate = reminder.dueDate var ending = new Date(reminder.dueDate) ending.setHours(ending.getHours()+1) event.endDate = ending } console.log(`【${reminder.title}】待辦順延${-period}天` ) } else { event.title = `⭕️${reminder.title}` event.isAllDay = false event.location = "還剩" + period + "天" event.startDate = reminder.dueDate var ending = new Date(reminder.dueDate) ending.setHours(ending.getHours()+1) event.endDate = ending } } if(!reminder.dueDateIncludesTime) event.isAllDay = true event.save() }
会看见「提醒事项同步行事历」Scripts 脚本后,就可以退回主画面。

3. 建立捷径自动化
开启「捷径」App,点选「自动化」>「制作个人自动化操作」,选择「App」。

按下「App」按钮,搜寻并且勾选「提醒事项」和「日历」。

最后确定自动化操作是否设定为「已开启」,就可以按「下一步」。 在动作编辑页面中,点击加入动作。

利用搜索找到「Scriptable」,并且从 Run Script 内选择刚创建的 JavaScript 自动化脚本。

最后点击下一步。

会进入自动化执行设定页面,将「执行前先询问」和「执行时通知」两项功能都关闭,最后点击「完成」。

4. 排除自动化错误
以上步骤就能实现打开内建「行事历」或「提醒事项」App,就会立即自动同步,不过 Sctiptable 没有设定好权限,会导致执行脚本会出现「找不到日历错误」情况,会发现两个 App 之间没办法同步,底下告诉大家解决方法。 (此步骤一定要做)

先打开 iOS 内建「设定」,找到「Scriptable」控制设定,将「日历」和「提醒事项」关闭再次开启,偏好语言设定为「英文」。

都设定完成后,将 iPhone 重开机一次,打开「Scriptable」App 执行「提醒事项同步行事历」脚本,观察 Log 如果没有跳出任何黄字错误,能够正常运行就代表已经成功。

5. 实现行事历与提醒事项同步
以上全部都设定完成后,后续只要打开「行事历」或「提醒事项」其中一款App 就会立即同步,只要纪录在「提醒事项」App 的未完成的代办事项,就会立即同步到「行事历」App 内,甚至会显示还剩多少时间。

要是完成的代办事项,在行事历内也会看间打勾状态,透过行事历也能清楚知道今天有哪些未完成的工作,不管是日常生活、工作或学业都很方便。

要是打开行事历App没有出现提醒事项的项目,检查「提醒事项」内是否有设定日期时间,或是将行事历App 从后台关闭再次打开就可以,当然也可以建立好几组提醒事项列表,只要行事历有对应的名称两边就能够同步。
如何删除行事历内的提醒事项项目?
要是有些提醒事项已经完成,还是会一直显示在 iOS 行事历内要怎么删除? 这部分要通过删除提醒事项的项目才能删除,操作方法如下:
打开「提醒事项」App 的项目,按下右上角「•••」>「显示已完成的项目」。

列表就会显示已经完成的代办事项,往左滑动选择删除已经完成的事项,就能够将行事历已完成的项目也移除。

功能总结
透过这篇技巧后,就可以让 iPhone 行事历与提醒事项进行同步功能,而且免费又方便,只要有新增移除和编辑动作,一切透过提醒事项内操作就可以,行事历只是单纯显示。
