mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Move RCTTest & takeSnapshot to RNTester (#23721)
Summary: Part of: #23313. This moves the `RCTTest` lib from `Libraries/RCTTest` to `RNTester/RCTTest`. This also removes `takeSnapshot` from React Native, and implements it as a standalone module in RNTester called `ScreenshotManager`. [General] [Removed] - RCTTest & ReactNative.takeSnapshot Pull Request resolved: https://github.com/facebook/react-native/pull/23721 Differential Revision: D14434796 Pulled By: PeteTheHeat fbshipit-source-id: d6e103a0ea0b6702701cdb5ce8449163ca4628ce
This commit is contained in:
committed by
Facebook Github Bot
parent
d17e061c0e
commit
fc94ade11c
@@ -24,19 +24,6 @@ invariant(
|
||||
'UIManager is undefined. The native module config is probably incorrect.',
|
||||
);
|
||||
|
||||
// In past versions of ReactNative users called UIManager.takeSnapshot()
|
||||
// However takeSnapshot was moved to ReactNative in order to support flat
|
||||
// bundles and to avoid a cyclic dependency between UIManager and ReactNative.
|
||||
// UIManager.takeSnapshot still exists though. In order to avoid confusion or
|
||||
// accidental usage, mask the method with a deprecation warning.
|
||||
UIManager.__takeSnapshot = UIManager.takeSnapshot;
|
||||
UIManager.takeSnapshot = function() {
|
||||
invariant(
|
||||
false,
|
||||
'UIManager.takeSnapshot should not be called directly. ' +
|
||||
'Use ReactNative.takeSnapshot instead.',
|
||||
);
|
||||
};
|
||||
const triedLoadingConfig = new Set();
|
||||
UIManager.getViewManagerConfig = function(viewManagerName: string) {
|
||||
if (
|
||||
|
||||
@@ -56,8 +56,6 @@ module.exports = [
|
||||
'StyleConstants',
|
||||
'AccessibilityEventTypes',
|
||||
'UIView',
|
||||
'__takeSnapshot',
|
||||
'takeSnapshot',
|
||||
'getViewManagerConfig',
|
||||
'blur',
|
||||
'focus',
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
const ReactNative = require('ReactNative');
|
||||
const UIManager = require('UIManager');
|
||||
|
||||
/**
|
||||
* Capture an image of the screen, window or an individual view. The image
|
||||
* will be stored in a temporary file that will only exist for as long as the
|
||||
* app is running.
|
||||
*
|
||||
* The `view` argument can be the literal string `window` if you want to
|
||||
* capture the entire window, or it can be a reference to a specific
|
||||
* React Native component.
|
||||
*
|
||||
* The `options` argument may include:
|
||||
* - width/height (number) - the width and height of the image to capture.
|
||||
* - format (string) - either 'png' or 'jpeg'. Defaults to 'png'.
|
||||
* - quality (number) - the quality when using jpeg. 0.0 - 1.0 (default).
|
||||
*
|
||||
* Returns a Promise.
|
||||
* @platform ios
|
||||
*/
|
||||
module.exports = function takeSnapshot(
|
||||
view?: 'window' | React$Element<any> | number,
|
||||
options?: {
|
||||
width?: number,
|
||||
height?: number,
|
||||
format?: 'png' | 'jpeg',
|
||||
quality?: number,
|
||||
},
|
||||
): Promise<any> {
|
||||
if (typeof view !== 'number' && view !== 'window') {
|
||||
view = ReactNative.findNodeHandle(view) || 'window';
|
||||
}
|
||||
|
||||
// Call the hidden '__takeSnapshot' method; the main one throws an error to
|
||||
// prevent accidental backwards-incompatible usage.
|
||||
return UIManager.__takeSnapshot(view, options);
|
||||
};
|
||||
@@ -346,9 +346,6 @@ module.exports = {
|
||||
get requireNativeComponent() {
|
||||
return require('requireNativeComponent');
|
||||
},
|
||||
get takeSnapshot() {
|
||||
return require('takeSnapshot');
|
||||
},
|
||||
|
||||
// Prop Types
|
||||
get ColorPropType() {
|
||||
|
||||
28
RNTester/NativeModuleExample/NativeScreenshotManager.js
Normal file
28
RNTester/NativeModuleExample/NativeScreenshotManager.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from 'RCTExport';
|
||||
import * as TurboModuleRegistry from 'TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getConstants: () => {||};
|
||||
takeSnapshot(id: string): Promise<string>;
|
||||
}
|
||||
|
||||
const NativeModule = TurboModuleRegistry.get<Spec>('ScreenshotManager');
|
||||
|
||||
export function takeSnapshot(id: string): Promise<string> {
|
||||
if (NativeModule != null) {
|
||||
return NativeModule.takeSnapshot(id);
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
12
RNTester/NativeModuleExample/Screenshot.h
Normal file
12
RNTester/NativeModuleExample/Screenshot.h
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// RNTTakeScreenshot.h
|
||||
// RNTester
|
||||
//
|
||||
// Created by Eric Lewis on 3/1/19.
|
||||
// Copyright © 2019 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
@interface ScreenshotManager : RCTViewManager
|
||||
@end
|
||||
84
RNTester/NativeModuleExample/Screenshot.m
Normal file
84
RNTester/NativeModuleExample/Screenshot.m
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// RNTTakeScreenshot.m
|
||||
// RNTester
|
||||
//
|
||||
// Created by Eric Lewis on 3/1/19.
|
||||
// Copyright © 2019 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Screenshot.h"
|
||||
|
||||
#import <React/RCTUIManager.h>
|
||||
|
||||
@implementation ScreenshotManager
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_EXPORT_METHOD(takeScreenshot:(id /* NSString or NSNumber */)target
|
||||
withOptions:(NSDictionary *)options
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
|
||||
// Get view
|
||||
UIView *view;
|
||||
if (target == nil || [target isEqual:@"window"]) {
|
||||
view = RCTKeyWindow();
|
||||
} else if ([target isKindOfClass:[NSNumber class]]) {
|
||||
view = viewRegistry[target];
|
||||
if (!view) {
|
||||
RCTLogError(@"No view found with reactTag: %@", target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get options
|
||||
CGSize size = [RCTConvert CGSize:options];
|
||||
NSString *format = [RCTConvert NSString:options[@"format"] ?: @"png"];
|
||||
|
||||
// Capture image
|
||||
if (size.width < 0.1 || size.height < 0.1) {
|
||||
size = view.bounds.size;
|
||||
}
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
|
||||
BOOL success = [view drawViewHierarchyInRect:(CGRect){CGPointZero, size} afterScreenUpdates:YES];
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
if (!success || !image) {
|
||||
reject(RCTErrorUnspecified, @"Failed to capture view snapshot.", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert image to data (on a background thread)
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
NSData *data;
|
||||
if ([format isEqualToString:@"png"]) {
|
||||
data = UIImagePNGRepresentation(image);
|
||||
} else if ([format isEqualToString:@"jpeg"]) {
|
||||
CGFloat quality = [RCTConvert CGFloat:options[@"quality"] ?: @1];
|
||||
data = UIImageJPEGRepresentation(image, quality);
|
||||
} else {
|
||||
RCTLogError(@"Unsupported image format: %@", format);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save to a temp file
|
||||
NSError *error = nil;
|
||||
NSString *tempFilePath = RCTTempFilePath(format, &error);
|
||||
if (tempFilePath) {
|
||||
if ([data writeToFile:tempFilePath options:(NSDataWritingOptions)0 error:&error]) {
|
||||
resolve(tempFilePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached here, something went wrong
|
||||
reject(RCTErrorUnspecified, error.localizedDescription, error);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -30,4 +30,6 @@ type SnapshotViewNativeType = Class<NativeComponent<NativeProps>>;
|
||||
|
||||
const requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
module.exports = ((requireNativeComponent('RCTSnapshot'):any): SnapshotViewNativeType);
|
||||
module.exports = ((requireNativeComponent(
|
||||
'RCTSnapshot',
|
||||
): any): SnapshotViewNativeType);
|
||||
@@ -35,7 +35,6 @@
|
||||
1497CFB01B21F5E400C1F8F2 /* RCTFontTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA81B21F5E400C1F8F2 /* RCTFontTests.m */; };
|
||||
1497CFB11B21F5E400C1F8F2 /* RCTEventDispatcherTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA91B21F5E400C1F8F2 /* RCTEventDispatcherTests.m */; };
|
||||
1497CFB31B21F5E400C1F8F2 /* RCTUIManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */; };
|
||||
14B6DA821B276C5900BF4DD1 /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58005BEE1ABA80530062E044 /* libRCTTest.a */; };
|
||||
14D6D7111B220EB3001FB087 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14D6D7101B220EB3001FB087 /* libOCMock.a */; };
|
||||
14D6D71E1B2222EF001FB087 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
|
||||
14D6D7201B2222EF001FB087 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 134A8A251AACED6A00945AAE /* libRCTGeolocation.a */; };
|
||||
@@ -43,7 +42,6 @@
|
||||
14D6D7221B2222EF001FB087 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
|
||||
14D6D7231B2222EF001FB087 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; };
|
||||
14D6D7241B2222EF001FB087 /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
|
||||
14D6D7251B2222EF001FB087 /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58005BEE1ABA80530062E044 /* libRCTTest.a */; };
|
||||
14D6D7261B2222EF001FB087 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
|
||||
14D6D7271B2222EF001FB087 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
|
||||
14D6D7281B2222EF001FB087 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDED91B0651EA00C62182 /* libRCTWebSocket.a */; };
|
||||
@@ -62,7 +60,6 @@
|
||||
2D4624FB1DA2EAC300C74D09 /* RCTRootViewIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 27B885551BED29AF00008352 /* RCTRootViewIntegrationTests.m */; };
|
||||
2D4624FD1DA2EAC300C74D09 /* RNTesterSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* RNTesterSnapshotTests.m */; };
|
||||
2D4624FE1DA2EAC300C74D09 /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
|
||||
2D4625351DA2EBBE00C74D09 /* libRCTTest-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323CC1DA2DD8B000FE1B8 /* libRCTTest-tvOS.a */; };
|
||||
2D4BD8D21DA2E20D005AC8A8 /* RCTURLUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */; };
|
||||
2D4BD8D31DA2E20D005AC8A8 /* RCTBundleURLProviderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FF44371CF6111500720EFD /* RCTBundleURLProviderTests.m */; };
|
||||
2D4BD8D41DA2E20D005AC8A8 /* RCTAllocationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */; };
|
||||
@@ -103,7 +100,6 @@
|
||||
2DE7E8011FB2A4F3009E225D /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323C31DA2DD8B000FE1B8 /* libRCTNetwork-tvOS.a */; };
|
||||
2DE7E8021FB2A4F3009E225D /* libRCTPushNotification-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D05746C1DE6008900184BB4 /* libRCTPushNotification-tvOS.a */; };
|
||||
2DE7E8031FB2A4F3009E225D /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323C81DA2DD8B000FE1B8 /* libRCTSettings-tvOS.a */; };
|
||||
2DE7E8041FB2A4F3009E225D /* libRCTTest-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323CC1DA2DD8B000FE1B8 /* libRCTTest-tvOS.a */; };
|
||||
2DE7E8051FB2A4F3009E225D /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D01DA2DD8B000FE1B8 /* libRCTText-tvOS.a */; };
|
||||
2DE7E8061FB2A4F3009E225D /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D51DA2DD8B000FE1B8 /* libRCTWebSocket-tvOS.a */; };
|
||||
2DE7E8071FB2A4F3009E225D /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D91DA2DD8B000FE1B8 /* libReact.a */; };
|
||||
@@ -121,6 +117,11 @@
|
||||
3DD981D61D33C6FB007DC7BE /* RNTesterUnitTestsBundle.js in Resources */ = {isa = PBXBuildFile; fileRef = 3DD981D51D33C6FB007DC7BE /* RNTesterUnitTestsBundle.js */; };
|
||||
52C11BBB1EEACA7100C1A058 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5281CA511EEAC9A700AC40CD /* libRCTBlob.a */; };
|
||||
52C11BE11EEACA7800C1A058 /* libRCTBlob-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5281CA531EEAC9A700AC40CD /* libRCTBlob-tvOS.a */; };
|
||||
6862DFC62229DCE600684E03 /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6862DFAC2229DCC400684E03 /* libRCTTest.a */; };
|
||||
6862DFC72229DD1000684E03 /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6862DFAC2229DCC400684E03 /* libRCTTest.a */; };
|
||||
6862DFC82229DD1900684E03 /* libRCTTest-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6862DFAE2229DCC400684E03 /* libRCTTest-tvOS.a */; };
|
||||
6862DFC92229DD2100684E03 /* libRCTTest-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6862DFAE2229DCC400684E03 /* libRCTTest-tvOS.a */; };
|
||||
6862DFCF2229DFCC00684E03 /* Screenshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 6862DFCE2229DFCC00684E03 /* Screenshot.m */; };
|
||||
68FF44381CF6111500720EFD /* RCTBundleURLProviderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FF44371CF6111500720EFD /* RCTBundleURLProviderTests.m */; };
|
||||
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
|
||||
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
|
||||
@@ -286,13 +287,6 @@
|
||||
remoteGlobalIDString = 2D2A28611D9B046600D4039D;
|
||||
remoteInfo = "RCTSettings-tvOS";
|
||||
};
|
||||
2DD323CB1DA2DD8B000FE1B8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 58005BE41ABA80530062E044 /* RCTTest.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A286E1D9B047700D4039D;
|
||||
remoteInfo = "RCTTest-tvOS";
|
||||
};
|
||||
2DD323CF1DA2DD8B000FE1B8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */;
|
||||
@@ -419,13 +413,20 @@
|
||||
remoteGlobalIDString = ADD01A681E09402E00F6D226;
|
||||
remoteInfo = "RCTBlob-tvOS";
|
||||
};
|
||||
58005BED1ABA80530062E044 /* PBXContainerItemProxy */ = {
|
||||
6862DFAB2229DCC400684E03 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 58005BE41ABA80530062E044 /* RCTTest.xcodeproj */;
|
||||
containerPortal = 6862DF932229DCC400684E03 /* RCTTest.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 580C376F1AB104AF0015E709;
|
||||
remoteInfo = RCTTest;
|
||||
};
|
||||
6862DFAD2229DCC400684E03 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 6862DF932229DCC400684E03 /* RCTTest.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A286E1D9B047700D4039D;
|
||||
remoteInfo = "RCTTest-tvOS";
|
||||
};
|
||||
834C36D11AF8DA610019C93C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */;
|
||||
@@ -558,7 +559,9 @@
|
||||
3DB99D0B1BA0340600302749 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = "<group>"; };
|
||||
3DD981D51D33C6FB007DC7BE /* RNTesterUnitTestsBundle.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = RNTesterUnitTestsBundle.js; sourceTree = "<group>"; };
|
||||
5281CA4B1EEAC9A700AC40CD /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = ../Libraries/Blob/RCTBlob.xcodeproj; sourceTree = "<group>"; };
|
||||
58005BE41ABA80530062E044 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = ../Libraries/RCTTest/RCTTest.xcodeproj; sourceTree = "<group>"; };
|
||||
6862DF932229DCC400684E03 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = RCTTest/RCTTest.xcodeproj; sourceTree = "<group>"; };
|
||||
6862DFCD2229DFCB00684E03 /* Screenshot.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Screenshot.h; sourceTree = "<group>"; };
|
||||
6862DFCE2229DFCC00684E03 /* Screenshot.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Screenshot.m; sourceTree = "<group>"; };
|
||||
68FF44371CF6111500720EFD /* RCTBundleURLProviderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBundleURLProviderTests.m; sourceTree = "<group>"; };
|
||||
83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = "<group>"; };
|
||||
8385CEF41B873B5C00C6273E /* RCTImageLoaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageLoaderTests.m; sourceTree = "<group>"; };
|
||||
@@ -588,7 +591,7 @@
|
||||
14D6D7221B2222EF001FB087 /* libRCTNetwork.a in Frameworks */,
|
||||
14D6D7231B2222EF001FB087 /* libRCTPushNotification.a in Frameworks */,
|
||||
14D6D7241B2222EF001FB087 /* libRCTSettings.a in Frameworks */,
|
||||
14D6D7251B2222EF001FB087 /* libRCTTest.a in Frameworks */,
|
||||
6862DFC62229DCE600684E03 /* libRCTTest.a in Frameworks */,
|
||||
14D6D7261B2222EF001FB087 /* libRCTText.a in Frameworks */,
|
||||
14D6D7271B2222EF001FB087 /* libRCTVibration.a in Frameworks */,
|
||||
14D6D7281B2222EF001FB087 /* libRCTWebSocket.a in Frameworks */,
|
||||
@@ -624,7 +627,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
14B6DA821B276C5900BF4DD1 /* libRCTTest.a in Frameworks */,
|
||||
6862DFC72229DD1000684E03 /* libRCTTest.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -632,7 +635,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2D4625351DA2EBBE00C74D09 /* libRCTTest-tvOS.a in Frameworks */,
|
||||
6862DFC92229DD2100684E03 /* libRCTTest-tvOS.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -659,6 +662,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6862DFC82229DD1900684E03 /* libRCTTest-tvOS.a in Frameworks */,
|
||||
2DE7E7FD1FB2A4F3009E225D /* libRCTAnimation.a in Frameworks */,
|
||||
2DE7E7FE1FB2A4F3009E225D /* libRCTBlob-tvOS.a in Frameworks */,
|
||||
2DE7E7FF1FB2A4F3009E225D /* libRCTImage-tvOS.a in Frameworks */,
|
||||
@@ -666,7 +670,6 @@
|
||||
2DE7E8011FB2A4F3009E225D /* libRCTNetwork-tvOS.a in Frameworks */,
|
||||
2DE7E8021FB2A4F3009E225D /* libRCTPushNotification-tvOS.a in Frameworks */,
|
||||
2DE7E8031FB2A4F3009E225D /* libRCTSettings-tvOS.a in Frameworks */,
|
||||
2DE7E8041FB2A4F3009E225D /* libRCTTest-tvOS.a in Frameworks */,
|
||||
2DE7E8051FB2A4F3009E225D /* libRCTText-tvOS.a in Frameworks */,
|
||||
2DE7E8061FB2A4F3009E225D /* libRCTWebSocket-tvOS.a in Frameworks */,
|
||||
2DE7E8071FB2A4F3009E225D /* libReact.a in Frameworks */,
|
||||
@@ -699,7 +702,7 @@
|
||||
134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
|
||||
14DC67E71AB71876001358AB /* RCTPushNotification.xcodeproj */,
|
||||
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */,
|
||||
58005BE41ABA80530062E044 /* RCTTest.xcodeproj */,
|
||||
6862DF932229DCC400684E03 /* RCTTest.xcodeproj */,
|
||||
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
|
||||
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */,
|
||||
139FDECA1B0651EA00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
@@ -778,6 +781,7 @@
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
AFEACAB12223EB2C004E5198 /* NativeExampleModules */,
|
||||
6862DFD02229E1DE00684E03 /* NativeModuleExample */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
1323F18D1C04ABAC0091BED0 /* Supporting Files */,
|
||||
@@ -976,15 +980,24 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58005BE51ABA80530062E044 /* Products */ = {
|
||||
6862DF942229DCC400684E03 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
58005BEE1ABA80530062E044 /* libRCTTest.a */,
|
||||
2DD323CC1DA2DD8B000FE1B8 /* libRCTTest-tvOS.a */,
|
||||
6862DFAC2229DCC400684E03 /* libRCTTest.a */,
|
||||
6862DFAE2229DCC400684E03 /* libRCTTest-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6862DFD02229E1DE00684E03 /* NativeModuleExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6862DFCD2229DFCB00684E03 /* Screenshot.h */,
|
||||
6862DFCE2229DFCC00684E03 /* Screenshot.m */,
|
||||
);
|
||||
path = NativeModuleExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
834C36CE1AF8DA610019C93C /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1261,8 +1274,8 @@
|
||||
ProjectRef = 13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 58005BE51ABA80530062E044 /* Products */;
|
||||
ProjectRef = 58005BE41ABA80530062E044 /* RCTTest.xcodeproj */;
|
||||
ProductGroup = 6862DF942229DCC400684E03 /* Products */;
|
||||
ProjectRef = 6862DF932229DCC400684E03 /* RCTTest.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 13417FEB1AA914B8003F314A /* Products */;
|
||||
@@ -1428,13 +1441,6 @@
|
||||
remoteRef = 2DD323C71DA2DD8B000FE1B8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DD323CC1DA2DD8B000FE1B8 /* libRCTTest-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTTest-tvOS.a";
|
||||
remoteRef = 2DD323CB1DA2DD8B000FE1B8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DD323D01DA2DD8B000FE1B8 /* libRCTText-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
@@ -1554,11 +1560,18 @@
|
||||
remoteRef = 5281CA521EEAC9A700AC40CD /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
58005BEE1ABA80530062E044 /* libRCTTest.a */ = {
|
||||
6862DFAC2229DCC400684E03 /* libRCTTest.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTTest.a;
|
||||
remoteRef = 58005BED1ABA80530062E044 /* PBXContainerItemProxy */;
|
||||
remoteRef = 6862DFAB2229DCC400684E03 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
6862DFAE2229DCC400684E03 /* libRCTTest-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTTest-tvOS.a";
|
||||
remoteRef = 6862DFAD2229DCC400684E03 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
834C36D21AF8DA610019C93C /* libRCTSettings.a */ = {
|
||||
@@ -1739,6 +1752,7 @@
|
||||
27F441EC1BEBE5030039B79C /* FlexibleSizeExampleView.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
AFEACA842223EB05004E5198 /* CrashyCrash.m in Sources */,
|
||||
6862DFCF2229DFCC00684E03 /* Screenshot.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -15,11 +15,12 @@ const ReactNative = require('react-native');
|
||||
const {
|
||||
ActionSheetIOS,
|
||||
StyleSheet,
|
||||
takeSnapshot,
|
||||
Text,
|
||||
View,
|
||||
Alert,
|
||||
NativeModules,
|
||||
} = ReactNative;
|
||||
const ScreenshotManager = NativeModules.ScreenshotManager;
|
||||
|
||||
const BUTTONS = ['Option 0', 'Option 1', 'Option 2', 'Delete', 'Cancel'];
|
||||
const DESTRUCTIVE_INDEX = 3;
|
||||
@@ -199,7 +200,7 @@ class ShareScreenshotExample extends React.Component<
|
||||
|
||||
showShareActionSheet = () => {
|
||||
// Take the snapshot (returns a temp file uri)
|
||||
takeSnapshot('window')
|
||||
ScreenshotManager.takeScreenshot('window')
|
||||
.then(uri => {
|
||||
// Share image data
|
||||
ActionSheetIOS.showShareActionSheetWithOptions(
|
||||
@@ -254,7 +255,7 @@ class ShareScreenshotAnchorExample extends React.Component<
|
||||
|
||||
showShareActionSheet = () => {
|
||||
// Take the snapshot (returns a temp file uri)
|
||||
takeSnapshot('window')
|
||||
ScreenshotManager.takeScreenshot('window')
|
||||
.then(uri => {
|
||||
// Share image data
|
||||
ActionSheetIOS.showShareActionSheetWithOptions(
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {Alert, Image, StyleSheet, Text, View} = ReactNative;
|
||||
const {Alert, Image, NativeModules, StyleSheet, Text, View} = ReactNative;
|
||||
const ScreenshotManager = NativeModules.ScreenshotManager;
|
||||
|
||||
class ScreenshotExample extends React.Component<{}, $FlowFixMeState> {
|
||||
state = {
|
||||
@@ -30,7 +31,7 @@ class ScreenshotExample extends React.Component<{}, $FlowFixMeState> {
|
||||
}
|
||||
|
||||
takeScreenshot = () => {
|
||||
ReactNative.takeSnapshot('window', {format: 'jpeg', quality: 0.8}) // See UIManager.js for options
|
||||
ScreenshotManager.takeScreenshot('window', {format: 'jpeg', quality: 0.8}) // See UIManager.js for options
|
||||
.then(uri => this.setState({uri}))
|
||||
.catch(error => Alert.alert(error));
|
||||
};
|
||||
|
||||
@@ -1364,73 +1364,6 @@ RCT_EXPORT_METHOD(measureLayoutRelativeToParent:(nonnull NSNumber *)reactTag
|
||||
RCTMeasureLayout(shadowView, shadowView.reactSuperview, callback);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(takeSnapshot:(id /* NSString or NSNumber */)target
|
||||
withOptions:(NSDictionary *)options
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
|
||||
// Get view
|
||||
UIView *view;
|
||||
if (target == nil || [target isEqual:@"window"]) {
|
||||
view = RCTKeyWindow();
|
||||
} else if ([target isKindOfClass:[NSNumber class]]) {
|
||||
view = viewRegistry[target];
|
||||
if (!view) {
|
||||
RCTLogError(@"No view found with reactTag: %@", target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get options
|
||||
CGSize size = [RCTConvert CGSize:options];
|
||||
NSString *format = [RCTConvert NSString:options[@"format"] ?: @"png"];
|
||||
|
||||
// Capture image
|
||||
if (size.width < 0.1 || size.height < 0.1) {
|
||||
size = view.bounds.size;
|
||||
}
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
|
||||
BOOL success = [view drawViewHierarchyInRect:(CGRect){CGPointZero, size} afterScreenUpdates:YES];
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
if (!success || !image) {
|
||||
reject(RCTErrorUnspecified, @"Failed to capture view snapshot.", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert image to data (on a background thread)
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
NSData *data;
|
||||
if ([format isEqualToString:@"png"]) {
|
||||
data = UIImagePNGRepresentation(image);
|
||||
} else if ([format isEqualToString:@"jpeg"]) {
|
||||
CGFloat quality = [RCTConvert CGFloat:options[@"quality"] ?: @1];
|
||||
data = UIImageJPEGRepresentation(image, quality);
|
||||
} else {
|
||||
RCTLogError(@"Unsupported image format: %@", format);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save to a temp file
|
||||
NSError *error = nil;
|
||||
NSString *tempFilePath = RCTTempFilePath(format, &error);
|
||||
if (tempFilePath) {
|
||||
if ([data writeToFile:tempFilePath options:(NSDataWritingOptions)0 error:&error]) {
|
||||
resolve(tempFilePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached here, something went wrong
|
||||
reject(RCTErrorUnspecified, error.localizedDescription, error);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* JS sets what *it* considers to be the responder. Later, scroll views can use
|
||||
* this in order to determine if scrolling is appropriate.
|
||||
|
||||
Reference in New Issue
Block a user