Skip to content

Instantly share code, notes, and snippets.

View yccheok's full-sized avatar

Yan Cheng Cheok yccheok

View GitHub Profile
private static func setupNSPersistentContainer(_ iCloudSync: Bool) -> NSPersistentContainer {
precondition(Thread.isMainThread)
let container = NSPersistentCloudKitContainer(name: "wenote", managedObjectModel: NSManagedObjectModel.wenote)
guard let oldStoreDescription = container.persistentStoreDescriptions.first else {
fatalError("Failed to retrieve a persistent store description.")
}
// Integrate AppGroup with CoreData. If we are assigning a new store description to CoreData, it is important
import WidgetKit
import SwiftUI
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date())
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date())
struct Provider: IntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
let nsTodoList = NSTodoListRepository.INSTANCE.getNSTodoList(nil)
return SimpleEntry(
date: Date(),
nsTodoList: nsTodoList,
configurationIntent: nil
)
}
func updatePinnedsAsync(_ objectIDs: [NSManagedObjectID], _ pinned: Bool) {
let currentTimeMillis = Date.currentTimeMillis
updateAsync(objectIDs: objectIDs, propertiesToUpdate: [
"pinned": pinned,
"syncedTimestamp": currentTimeMillis
])
}
private func updateAsync(objectIDs: [NSManagedObjectID], propertiesToUpdate: [AnyHashable : Any]) {
struct TodoWidgetEntryView : View {
var entry: Provider.Entry
let todoItems: [TodoItem] = DataManager().todoItems
var body: some View {
VStack(alignment: .leading, spacing: 1) {
ForEach(0..<todoItems.count, id: \.self) { index in
Button(intent: TodoIntent(item: todoItems[index].taskName)) {
Label(todoItems[index].taskName, systemImage: "circle\(todoItems[index].isCompleted ? ".fill" : "")")
.frame(maxWidth: .infinity, alignment: .leading).lineLimit(1)
var attachmentables: [Attachmentable] {
// Strange issue happens only in 16.4. I do not encounter such an issue in 15.0
//
// However, "self.attachments == self.cachedAttachments" will return true, even there is mutation on
// "self.attachments". If we call "self.cachedAttachments.count" prior performing
// "self.attachments == self.cachedAttachments", then such comparison will return correct result.
//
// (Comparing count seems redundant. But, we still need to do that)
if self.attachments.count == self.cachedAttachments.count && self.attachments == self.cachedAttachments {
return self.cachedAttachmentables
// During EditText initialization.
if (WeNoteOptions.isAutoURLLink() || WeNoteOptions.isAutoPhoneLink()) {
final int linksMask = getLinksMask();
bodyEditText.setLinksClickable(false);
bodyEditText.setAutoLinkMask(linksMask);
// https://stackoverflow.com/a/18541955/72437
bodyEditText.setMovementMethod(MyLinkMovementMethod.getInstance());
}
@yccheok
yccheok / gist:05573fac91cb1c61d8391849baef1ea7
Created February 28, 2023 16:12
text search feature for iOS
func share() {
/*
let attributedText = NSMutableAttributedString(attributedString: bodyTextView.attributedText!)
let range = NSRange(location: 1, length: 2)
let range2 = NSRange(location: 5, length: 7)
attributedText.addAttribute(
NSAttributedString.Key.backgroundColor,
value: UIColor.yellow,
/*
However, such mythology is not entirely correct, based on https://developer.apple.com/videos/play/wwdc2018/225/ . According to the video, reloadItems and moveItem do not play well. We need to make sure correct calling performBatchUpdates sequence, to avoid NSInternalInconsistencyException.
My code idea is
Separate out section operations, and non section operations.
Separate out update operations (for non section only), with rest of the operations (for non section only)
Include an ignoreUpdate flag, to ignore didChange callback, when we are performing drag and reordering operation. Drag and reordering has perform UI update for us automatically. We no longer required to perform UI update in didChange callback
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
let currentDate = Date()
let stickyNote = NSPlainNoteRepository.getStickyNote(configuration)
let entry = SimpleEntry(date: currentDate, stickyNote: stickyNote)
entries.append(entry)
let timeline = Timeline(entries: entries, policy: .never)
completion(timeline)