diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-09-10 22:48:37 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-09-10 22:48:37 +0200 |
| commit | 1613c951d49e6d85aff52f312d57fa087b35c079 (patch) | |
| tree | c31b74c56f32c3a60e628c187b6f7c236fffe36e /QSThingsPlugin/Helpers | |
| parent | 7cf393095282077b0bbae3046826b67f4f20a8eb (diff) | |
Move things URL calls to a helper
Diffstat (limited to 'QSThingsPlugin/Helpers')
| -rw-r--r-- | QSThingsPlugin/Helpers/KeychainHelper.h | 7 | ||||
| -rw-r--r-- | QSThingsPlugin/Helpers/KeychainHelper.m | 7 | ||||
| -rw-r--r-- | QSThingsPlugin/Helpers/ThingsHelper.h | 34 | ||||
| -rw-r--r-- | QSThingsPlugin/Helpers/ThingsHelper.m | 70 |
4 files changed, 104 insertions, 14 deletions
diff --git a/QSThingsPlugin/Helpers/KeychainHelper.h b/QSThingsPlugin/Helpers/KeychainHelper.h index d935bec..3665377 100644 --- a/QSThingsPlugin/Helpers/KeychainHelper.h +++ b/QSThingsPlugin/Helpers/KeychainHelper.h @@ -1,10 +1,3 @@ -// -// KeychainHelper.h -// Things Plugin -// -// Created by Ruben Beltran del Rio on 2025-09-10. -// - #import "Constants.h" #import <Foundation/Foundation.h> #import <Security/Security.h> diff --git a/QSThingsPlugin/Helpers/KeychainHelper.m b/QSThingsPlugin/Helpers/KeychainHelper.m index 9ce90f7..fcf8291 100644 --- a/QSThingsPlugin/Helpers/KeychainHelper.m +++ b/QSThingsPlugin/Helpers/KeychainHelper.m @@ -1,10 +1,3 @@ -// -// KeychainHelper.m -// Things Plugin -// -// Created by Ruben Beltran del Rio on 2025-09-10. -// - #import "KeychainHelper.h" NS_ASSUME_NONNULL_BEGIN diff --git a/QSThingsPlugin/Helpers/ThingsHelper.h b/QSThingsPlugin/Helpers/ThingsHelper.h new file mode 100644 index 0000000..29d3092 --- /dev/null +++ b/QSThingsPlugin/Helpers/ThingsHelper.h @@ -0,0 +1,34 @@ +#import "KeychainHelper.h" +#import "Constants.h" +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + Enum of valid Things URL routes. + */ +typedef NSString* ThingsURLRoute NS_STRING_ENUM; + +extern ThingsURLRoute const ThingsURLRouteSearch; +extern ThingsURLRoute const ThingsURLRouteShow; +extern ThingsURLRoute const ThingsURLRouteUpdate; +extern ThingsURLRoute const ThingsURLRouteUpdateProject; +extern ThingsURLRoute const ThingsURLRouteAdd; +extern ThingsURLRoute const ThingsURLRouteAddProject; + +/** + Helper class to communicate with things using the URL API + */ +@interface ThingsHelper : NSObject + +/** + Calls a Things URL route with the specified parameters + @param route the Things URL route to call. Use ThingsURLRoute enum. + @param parameters NSDictionary of query parameters to include in the URL. Can be nil or empty. + @returns YES if the URL was successfully opened, NO if something went wrong. + */ ++ (BOOL)callRoute:(ThingsURLRoute)route withParameters:(NSDictionary *)parameters; + +@end + +NS_ASSUME_NONNULL_END diff --git a/QSThingsPlugin/Helpers/ThingsHelper.m b/QSThingsPlugin/Helpers/ThingsHelper.m new file mode 100644 index 0000000..cc7267b --- /dev/null +++ b/QSThingsPlugin/Helpers/ThingsHelper.m @@ -0,0 +1,70 @@ +#import "ThingsHelper.h" + +NS_ASSUME_NONNULL_BEGIN + +ThingsURLRoute const ThingsURLRouteSearch = @"search"; +ThingsURLRoute const ThingsURLRouteShow = @"show"; +ThingsURLRoute const ThingsURLRouteUpdate = @"update"; +ThingsURLRoute const ThingsURLRouteUpdateProject = @"update-project"; +ThingsURLRoute const ThingsURLRouteAdd = @"add"; +ThingsURLRoute const ThingsURLRouteAddProject = @"add-project"; + +@implementation ThingsHelper + ++ (instancetype)sharedInstance { + static ThingsHelper *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + ++ (BOOL)requiresAuthentication:(ThingsURLRoute)route { + if ([route isEqualToString:ThingsURLRouteSearch] || [route isEqualToString:ThingsURLRouteShow]) { + return NO; + } + return YES; +} + ++ (BOOL)callRoute:(ThingsURLRoute)route withParameters:(NSDictionary *)parameters { + NSString *authenticationKey = [KeychainHelper authenticationKey]; + if ([self requiresAuthentication:route] && !authenticationKey) { + NSLog(@"Attempted to call an authenticated things URL without an authentication key."); + return NO; + } + + NSString *baseURL = [NSString stringWithFormat:@"things:///%@", route]; + NSMutableArray *queryComponents = [NSMutableArray array]; + + if ([self requiresAuthentication:route]) { + [queryComponents addObject:[NSString stringWithFormat:@"auth-token=%@", authenticationKey]]; + } + + for (NSString *key in parameters) { + id value = parameters[key]; + NSString *encodedKey = [self urlEncodeString:key]; + NSString *encodedValue = [self urlEncodeString:[NSString stringWithFormat:@"%@", value]]; + [queryComponents addObject:[NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue]]; + } + + NSString *urlString = baseURL; + if ([queryComponents count] > 0) { + urlString = [NSString stringWithFormat:@"%@?%@", baseURL, [queryComponents componentsJoinedByString:@"&"]]; + } + + NSURL *url = [NSURL URLWithString:urlString]; + + [[NSWorkspace sharedWorkspace] openURL:url]; + + return YES; +} + ++ (NSString *)urlEncodeString:(NSString *)string { + NSCharacterSet *allowedCharacters = [NSCharacterSet URLQueryAllowedCharacterSet]; + return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; +} + +@end + +NS_ASSUME_NONNULL_END |