Skip to content

Commit

Permalink
move old extension to the native module
Browse files Browse the repository at this point in the history
  • Loading branch information
BrtqKr committed Feb 26, 2024
1 parent ae8246d commit 0e60afe
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 3 deletions.
12 changes: 9 additions & 3 deletions ios/NewExpensify.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
BDB853621F354EBB84E619C2 /* ExpensifyNewKansas-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D2AFB39EC1D44BF9B91D3227 /* ExpensifyNewKansas-MediumItalic.otf */; };
DD79042B2792E76D004484B4 /* RCTBootSplash.m in Sources */ = {isa = PBXBuildFile; fileRef = DD79042A2792E76D004484B4 /* RCTBootSplash.m */; };
DDCB2E57F334C143AC462B43 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D20D83B0E39BA6D21761E72 /* ExpoModulesProvider.swift */; };
E51DC681C7DEE40AEBDDFBFE /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
E51DC681C7DEE40AEBDDFBFE /* (null) in Frameworks */ = {isa = PBXBuildFile; };
E5647A2C2B88F2000047156F /* RCTShareExtensionHandlerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = E5647A2B2B88F2000047156F /* RCTShareExtensionHandlerModule.m */; };
E5CB2F112B7F834000B63003 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5CB2F102B7F834000B63003 /* ShareViewController.swift */; };
E5CB2F142B7F834000B63003 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E5CB2F122B7F834000B63003 /* MainInterface.storyboard */; };
E5CB2F182B7F834000B63003 /* ShareMenuExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E5CB2F0E2B7F834000B63003 /* ShareMenuExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
Expand Down Expand Up @@ -157,6 +158,8 @@
E2C8555C607612465A7473F8 /* Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig"; sourceTree = "<group>"; };
E2F1036F70CBFE39E9352674 /* Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig"; sourceTree = "<group>"; };
E2F78D2A9B3DB96F0524690B /* Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig"; sourceTree = "<group>"; };
E5647A2A2B88F1990047156F /* ios:NewExpensify:RCTShareExtensionHandlerModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ios:NewExpensify:RCTShareExtensionHandlerModule.h"; sourceTree = "<group>"; };
E5647A2B2B88F2000047156F /* RCTShareExtensionHandlerModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTShareExtensionHandlerModule.m; sourceTree = "<group>"; };
E5CB2F0E2B7F834000B63003 /* ShareMenuExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareMenuExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
E5CB2F102B7F834000B63003 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
E5CB2F132B7F834000B63003 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
Expand Down Expand Up @@ -188,9 +191,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E51DC681C7DEE40AEBDDFBFE /* BuildFile in Frameworks */,
E51DC681C7DEE40AEBDDFBFE /* (null) in Frameworks */,
976CCB5F8C921482E6AEAE71 /* libPods-NewExpensify.a in Frameworks */,
E51DC681C7DEE40AEBDDFBFE /* BuildFile in Frameworks */,
E51DC681C7DEE40AEBDDFBFE /* (null) in Frameworks */,
EEAE4F8907465429AA5B5520 /* libPods-NewExpensify.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -297,6 +300,8 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
E5647A2B2B88F2000047156F /* RCTShareExtensionHandlerModule.m */,
E5647A2A2B88F1990047156F /* ios:NewExpensify:RCTShareExtensionHandlerModule.h */,
374FB8D528A133A7000D84EF /* OriginImageRequestHandler.h */,
374FB8D628A133FE000D84EF /* OriginImageRequestHandler.mm */,
F0C450E92705020500FD2970 /* colors.json */,
Expand Down Expand Up @@ -922,6 +927,7 @@
buildActionMask = 2147483647;
files = (
18D050E0262400AF000D658B /* BridgingFile.swift in Sources */,
E5647A2C2B88F2000047156F /* RCTShareExtensionHandlerModule.m in Sources */,
0F5E5350263B73FD004CA14F /* EnvironmentChecker.m in Sources */,
374FB8D728A133FE000D84EF /* OriginImageRequestHandler.mm in Sources */,
7041848526A8E47D00E09F4D /* RCTStartupTimer.m in Sources */,
Expand Down
85 changes: 85 additions & 0 deletions ios/RCTShareExtensionHandlerModule.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// RCTShareExtensionHandlerModule.m
// NewExpensify
//
// Created by Bartek Krasoń on 23/02/2024.
//

#import <Foundation/Foundation.h>
#import "ios:NewExpensify:RCTShareExtensionHandlerModule.h"
#import <React/RCTLog.h>

NSString *const ShareExtensionGroupIdentifier = @"group.com.new-expensify";
NSString *const ShareExtensionFilesKey = @"ShareFiles";

@implementation RCTShareExtensionHandlerModule

// To export a module named RCTCalendarModule
RCT_EXPORT_MODULE(RCTShareExtensionHandlerModule);

RCT_EXPORT_METHOD(processFiles:(RCTResponseSenderBlock)callback)
{
RCTLogInfo(@"Processing share extension files");
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:ShareExtensionGroupIdentifier];
NSString *sharedImagesFolderPath = [defaults objectForKey:ShareExtensionFilesKey];

// Set default to NULL so it is not used when app is launched regularly.
[defaults setObject:NULL forKey:ShareExtensionFilesKey];
[defaults synchronize];

if (sharedImagesFolderPath == NULL) {
NSLog(@"handleShareExtension Missing 'folder' in shareExtensionData");
return;
}

// Get image file names
NSError *error = nil;
NSArray *imageSrcPath = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:sharedImagesFolderPath error:&error];

if (imageSrcPath.count == 0) {
NSLog(@"handleShareExtension Failed to find images in 'sharedImagesFolderPath'");
return;
}
NSLog(@"handleShareExtension shared %lu images", imageSrcPath.count);

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSMutableArray *imageFinalPaths = [NSMutableArray array];

for (int i = 0; i < imageSrcPath.count; i++) {
if (imageSrcPath[i] == NULL) {
NSLog(@"handleShareExtension Invalid image in position %d, imageSrcPath[i] is nil", i);
continue;
}
NSLog(@"handleShareExtension Valid image in position %d", i);
NSString *srcImageAbsolutePath = [sharedImagesFolderPath stringByAppendingPathComponent:imageSrcPath[i]];
UIImage *smartScanImage = [[UIImage alloc] initWithContentsOfFile:srcImageAbsolutePath];
if (smartScanImage == NULL) {
NSLog(@"handleShareExtension Failed to load image %@", srcImageAbsolutePath);
continue;
}

// Correct image orientation so it displays correctly on expenses.
UIGraphicsBeginImageContext(smartScanImage.size);
[smartScanImage drawAtPoint:CGPointMake(0, 0)];
CGContextRotateCTM (UIGraphicsGetCurrentContext(), 90 * M_PI/180);
smartScanImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Save image to file.
NSString *pathName = [NSString stringWithFormat:@"%@%@", [[NSUUID UUID] UUIDString], ShareImageFileExtension];
NSString *path = [documentsDirectory stringByAppendingPathComponent:pathName];
NSData *data = UIImagePNGRepresentation(smartScanImage);
[data writeToFile:path atomically:YES];
[imageFinalPaths addObject:path];
}

// Delete shared image folder
if (![[NSFileManager defaultManager] removeItemAtPath:sharedImagesFolderPath error:&error]) {
NSLog(@"Failed to delete shared image folder: %@, error: %@", sharedImagesFolderPath, error);
}

callback(@[@[imageFinalPaths]]);
}

@end
3 changes: 3 additions & 0 deletions ios/ShareMenuExtension/ShareViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class ShareViewController: UIViewController {
let content = extensionContext!.inputItems[0] as! NSExtensionItem
let contentType = UTType.image.identifier

// TODO: Remove when app group setup is done
self.openMainApp()

os_log("ShareViewController.viewDidAppear contentType: \(contentType)")
os_log("ShareViewController.viewDidAppear content: \(content)")
saveImageToAppGroup(content: content, contentType: contentType) { (error) in
Expand Down
15 changes: 15 additions & 0 deletions ios/ios:NewExpensify:RCTShareExtensionHandlerModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// ios:NewExpensify:RCTShareExtensionHandlerModule.h
// NewExpensify
//
// Created by Bartek Krasoń on 23/02/2024.
//

#ifndef ios_NewExpensify_RCTShareExtensionHandlerModule_h
#define ios_NewExpensify_RCTShareExtensionHandlerModule_h

#import <React/RCTBridgeModule.h>
@interface RCTShareExtensionHandlerModule : NSObject <RCTBridgeModule>
@end

#endif /* ios_NewExpensify_RCTShareExtensionHandlerModule_h */
9 changes: 9 additions & 0 deletions src/modules/ShareExtensionHandlerModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {NativeModules} from 'react-native';

const {ShareExtensionHandlerModule} = NativeModules;

type ShareExtensionHandlerType = {
processFiles(callback: (array: string[]) => void): void;
};

export default ShareExtensionHandlerModule as ShareExtensionHandlerType;
9 changes: 9 additions & 0 deletions src/pages/share/ShareRootPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import React, {useEffect} from 'react';
import {View} from 'react-native';
import Text from '@components/Text';
import ShareExtensionHandlerModule from '@src/modules/ShareExtensionHandlerModule';

// type ShareRootPageProps = {};

export default function ShareRootPage() {
useEffect(() => {
ShareExtensionHandlerModule?.processFiles((processedFiles) => {
// eslint-disable-next-line no-console
console.warn('PROCESSED FILES ', processedFiles);
});
}, []);

return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>share root</Text>
Expand Down

0 comments on commit 0e60afe

Please sign in to comment.