ios: Expose post text to Core Spotlight search.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 17m54s

This commit is contained in:
2025-11-11 21:40:17 -05:00
parent 0edb76b678
commit 50b2c0c7f4
3 changed files with 65 additions and 3 deletions

View File

@@ -815,7 +815,9 @@ $(MACOS_TARGETS) $(IOS_TARGETS) $(IOSSIM_TARGETS): CFLAGS += \
$(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \ $(IOS_TARGETS) $(IOSSIM_TARGETS): LDFLAGS += \
-framework Foundation \ -framework Foundation \
-framework CoreFoundation \ -framework CoreFoundation \
-framework CoreSpotlight \
-framework UIKit \ -framework UIKit \
-framework UniformTypeIdentifiers \
-framework WebKit -framework WebKit
## ##
@@ -1180,6 +1182,7 @@ ios%go: out/tildefriends-ios%.app/tildefriends
ideviceinstaller -i $(realpath $(dir $<)) ideviceinstaller -i $(realpath $(dir $<))
iossimdebuggo: out/tildefriends-iossimdebug.app/tildefriends ## Build, install, and run an iOS debug build. iossimdebuggo: out/tildefriends-iossimdebug.app/tildefriends ## Build, install, and run an iOS debug build.
xcrun -sdk iphoneos codesign -f -s 'Apple Distribution' --entitlements src/ios/Entitlements.plist --generate-entitlement-der out/tildefriends-iossimdebug.app
xcrun simctl install booted out/tildefriends-iossimdebug.app/ xcrun simctl install booted out/tildefriends-iossimdebug.app/
xcrun simctl launch --console booted com.unprompted.tildefriends xcrun simctl launch --console booted com.unprompted.tildefriends
.PHONY: iossimdebuggo .PHONY: iossimdebuggo

View File

@@ -1,3 +1,6 @@
#import <CoreSpotlight/CSSearchableIndex.h>
#import <CoreSpotlight/CSSearchableItem.h>
#import <CoreSpotlight/CSSearchableItemAttributeSet.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <WebKit/WKDownload.h> #import <WebKit/WKDownload.h>
#import <WebKit/WKDownloadDelegate.h> #import <WebKit/WKDownloadDelegate.h>
@@ -9,6 +12,7 @@
#import <WebKit/WKWebViewConfiguration.h> #import <WebKit/WKWebViewConfiguration.h>
#include "log.h" #include "log.h"
#include "util.js.h"
#include <libgen.h> #include <libgen.h>
#include <string.h> #include <string.h>
@@ -90,6 +94,7 @@ static void _start_initial_load(WKWebView* web_view)
- (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation - (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation
{ {
self.initial_load_complete = true; self.initial_load_complete = true;
tf_printf("initial load complete\n");
} }
- (void)webView:(WKWebView*)webView didFailProvisionalNavigation:(WKNavigation*)navigation withError:(NSError*)error - (void)webView:(WKWebView*)webView didFailProvisionalNavigation:(WKNavigation*)navigation withError:(NSError*)error
@@ -179,18 +184,16 @@ static void _start_initial_load(WKWebView* web_view)
- (void)download:(WKDownload*)download didFailWithError:(NSError*)error resumeData:(NSData*)resumeData - (void)download:(WKDownload*)download didFailWithError:(NSError*)error resumeData:(NSData*)resumeData
{ {
tf_printf("didFailWithError:%s\n", [error.localizedDescription UTF8String]); tf_printf("download didFailWithError:%s\n", [error.localizedDescription UTF8String]);
} }
- (void)documentPicker:(UIDocumentPickerViewController*)controller didPickDocumentAtURLs:(NSArray<NSURL*>*)urls - (void)documentPicker:(UIDocumentPickerViewController*)controller didPickDocumentAtURLs:(NSArray<NSURL*>*)urls
{ {
tf_printf("did pick!\n");
[[NSFileManager defaultManager] removeItemAtURL:self.download_url error:nil]; [[NSFileManager defaultManager] removeItemAtURL:self.download_url error:nil];
} }
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController*)controller - (void)documentPickerWasCancelled:(UIDocumentPickerViewController*)controller
{ {
tf_printf("no pick!\n");
[[NSFileManager defaultManager] removeItemAtURL:self.download_url error:nil]; [[NSFileManager defaultManager] removeItemAtURL:self.download_url error:nil];
} }
@end @end
@@ -208,8 +211,41 @@ static void _start_initial_load(WKWebView* web_view)
[self.window makeKeyAndVisible]; [self.window makeKeyAndVisible];
return YES; return YES;
} }
- (BOOL)application:(UIApplication*)application continueUserActivity:(NSUserActivity*)activity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>>*))restorationHandler
{
if ([activity.activityType isEqual:CSSearchableItemActionType]) {
const char* identifier = [[activity.userInfo valueForKey:CSSearchableItemActivityIdentifier] UTF8String];
tf_printf("Jumping to search result: %s.\n", identifier);
char url[1024];
snprintf(url, sizeof(url), "http://localhost:12345/~core/ssb/#%s", identifier);
tf_printf("Navigating to %s.", url);
ViewController* view_controller = (ViewController*)self.window.rootViewController;
[view_controller.web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithUTF8String:url]]]];
} else {
tf_printf("no search\n");
}
return NO;
}
@end @end
void tf_notify_message_added_ios(const char* identifier, const char* title, const char* content)
{
tf_printf("indexing: identifier=%s title=%s content=%s\n", identifier, title, content);
CSSearchableItemAttributeSet* attribute_set = [[CSSearchableItemAttributeSet alloc] initWithContentType:UTTypeText];
attribute_set.title = [NSString stringWithUTF8String:content];
attribute_set.contentDescription = [NSString stringWithUTF8String:title];
CSSearchableItem* item = [[CSSearchableItem alloc] initWithUniqueIdentifier:[NSString stringWithUTF8String:identifier] domainIdentifier:@"com.unprompted.tildefriends.messages" attributeSet:attribute_set];
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:@[item] completionHandler:^(NSError* _Nullable error) {
if (error) {
tf_printf("indexing error: %s.\n", [error.localizedDescription UTF8String]);
} else {
tf_printf("indexed successfully.\n");
}
}];
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
NSFileManager* file_manager = [NSFileManager defaultManager]; NSFileManager* file_manager = [NSFileManager defaultManager];

View File

@@ -716,6 +716,29 @@ static void _tf_ssb_db_store_message_after_work(tf_ssb_t* ssb, int status, void*
tf_trace_end(trace); tf_trace_end(trace);
} }
#if TARGET_OS_IPHONE
JSContext* context = tf_ssb_get_context(ssb);
JSValue content = JS_ParseJSON(context, store->content, strlen(store->content), NULL);
if (JS_IsObject(content))
{
JSValue type_value = JS_GetPropertyStr(context, content, "type");
const char* type = JS_ToCString(context, type_value);
if (type && strcmp(type, "post") == 0)
{
JSValue text_value = JS_GetPropertyStr(context, content, "text");
const char* text = JS_ToCString(context, text_value);
void tf_notify_message_added_ios(const char* identifier, const char* title, const char* content);
tf_notify_message_added_ios(store->id, type, text);
JS_FreeCString(context, text);
JS_FreeValue(context, text_value);
}
JS_FreeCString(context, type);
JS_FreeValue(context, type_value);
}
JS_FreeValue(context, content);
#endif
if (store->callback) if (store->callback)
{ {
store->callback(store->id, store->out_stored, store->user_data); store->callback(store->id, store->out_stored, store->user_data);