Add `react-native-macos-init` for adding macOS apps to existing `react-native init` projects. (#291)
* Got npx command line working. * Generating project folder. * Added macOS template files. * Lint fixes * Remove temp workarounds. * Make react-native.config.js mac and windows compatible. * Restore parity of macOS components with iOS because the `react-native init` sample app depends on them: e.g. StatusBar. * Updated NewAppScreen language for macOS. * Added `--prerelease` switch to allow installing pre-rerelease versions without prompting as this will be needed in CI. Made tweaks to templates and fixed template schemes to rename to project name.
This commit is contained in:
Родитель
feed0ac06b
Коммит
ef31e51828
|
@ -5,6 +5,8 @@
|
|||
Libraries/vendor/**/*
|
||||
Libraries/Renderer/*
|
||||
packages/*/node_modules
|
||||
packages/*/lib
|
||||
packages/*/lib-commonjs
|
||||
pr-inactivity-bookmarklet.js
|
||||
question-bookmarklet.js
|
||||
flow/
|
||||
|
|
|
@ -68,7 +68,8 @@ package-lock.json
|
|||
|
||||
/coverage
|
||||
/third-party
|
||||
/packages/
|
||||
/packages/*
|
||||
!/packages/react-native-macos-init/
|
||||
|
||||
# Root dir shouldn't have Xcode project
|
||||
/*.xcodeproj
|
||||
|
|
|
@ -24,7 +24,7 @@ import type {SyntheticEvent} from '../../Types/CoreEventTypes';
|
|||
import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
|
||||
import type {ViewProps} from '../View/ViewPropTypes';
|
||||
import type {TextStyleProp} from '../../StyleSheet/StyleSheet';
|
||||
import type {NativeOrDynamicColorType} from '../../Color/NativeOrDynamicColorType'; // ]TODO(macOS ISS#2323203)
|
||||
import type {NativeOrDynamicColorType} from '../../Color/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203)
|
||||
|
||||
type PickerIOSChangeEvent = SyntheticEvent<
|
||||
$ReadOnly<{|
|
||||
|
|
|
@ -12,4 +12,156 @@
|
|||
|
||||
// TODO(macOS ISS#2323203)
|
||||
|
||||
module.exports = require('../UnimplementedViews/UnimplementedView');
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('../../Renderer/shims/ReactNative');
|
||||
const StyleSheet = require('../../StyleSheet/StyleSheet');
|
||||
const View = require('../View/View');
|
||||
const processColor = require('../../StyleSheet/processColor');
|
||||
const RCTPickerNativeComponent = require('./RCTPickerNativeComponent');
|
||||
|
||||
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
|
||||
import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
|
||||
import type {ViewProps} from '../View/ViewPropTypes';
|
||||
import type {TextStyleProp} from '../../StyleSheet/StyleSheet';
|
||||
import type {NativeOrDynamicColorType} from '../../Color/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203)
|
||||
|
||||
type PickerIOSChangeEvent = SyntheticEvent<
|
||||
$ReadOnly<{|
|
||||
newValue: number | string,
|
||||
newIndex: number,
|
||||
|}>,
|
||||
>;
|
||||
|
||||
type RCTPickerIOSItemType = $ReadOnly<{|
|
||||
label: ?Label,
|
||||
value: ?(number | string),
|
||||
textColor: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203)
|
||||
|}>;
|
||||
|
||||
type RCTPickerIOSType = Class<
|
||||
ReactNative.NativeComponent<
|
||||
$ReadOnly<{|
|
||||
items: $ReadOnlyArray<RCTPickerIOSItemType>,
|
||||
onChange: (event: PickerIOSChangeEvent) => void,
|
||||
onResponderTerminationRequest: () => boolean,
|
||||
onStartShouldSetResponder: () => boolean,
|
||||
selectedIndex: number,
|
||||
style?: ?TextStyleProp,
|
||||
testID?: ?string,
|
||||
|}>,
|
||||
>,
|
||||
>;
|
||||
|
||||
type Label = Stringish | number;
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
children: React.ChildrenArray<React.Element<typeof PickerIOSItem>>,
|
||||
itemStyle?: ?TextStyleProp,
|
||||
onChange?: ?(event: PickerIOSChangeEvent) => mixed,
|
||||
onValueChange?: ?(itemValue: string | number, itemIndex: number) => mixed,
|
||||
selectedValue: ?(number | string),
|
||||
|}>;
|
||||
|
||||
type State = {|
|
||||
selectedIndex: number,
|
||||
items: $ReadOnlyArray<RCTPickerIOSItemType>,
|
||||
|};
|
||||
|
||||
type ItemProps = $ReadOnly<{|
|
||||
label: ?Label,
|
||||
value?: ?(number | string),
|
||||
color?: ?ColorValue,
|
||||
|}>;
|
||||
|
||||
const PickerIOSItem = (props: ItemProps) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
class PickerIOS extends React.Component<Props, State> {
|
||||
_picker: ?React.ElementRef<RCTPickerIOSType> = null;
|
||||
|
||||
state = {
|
||||
selectedIndex: 0,
|
||||
items: [],
|
||||
};
|
||||
|
||||
static Item = PickerIOSItem;
|
||||
|
||||
static getDerivedStateFromProps(props: Props): State {
|
||||
let selectedIndex = 0;
|
||||
const items = [];
|
||||
React.Children.toArray(props.children)
|
||||
.filter(child => child !== null)
|
||||
.forEach(function(child, index) {
|
||||
if (child.props.value === props.selectedValue) {
|
||||
selectedIndex = index;
|
||||
}
|
||||
items.push({
|
||||
value: child.props.value,
|
||||
label: child.props.label,
|
||||
textColor: processColor(child.props.color),
|
||||
});
|
||||
});
|
||||
return {selectedIndex, items};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={this.props.style}>
|
||||
<RCTPickerNativeComponent
|
||||
ref={picker => {
|
||||
this._picker = picker;
|
||||
}}
|
||||
testID={this.props.testID}
|
||||
style={[styles.pickerIOS, this.props.itemStyle]}
|
||||
items={this.state.items}
|
||||
selectedIndex={this.state.selectedIndex}
|
||||
onChange={this._onChange}
|
||||
onStartShouldSetResponder={() => true}
|
||||
onResponderTerminationRequest={() => false}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_onChange = event => {
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(event);
|
||||
}
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(
|
||||
event.nativeEvent.newValue,
|
||||
event.nativeEvent.newIndex,
|
||||
);
|
||||
}
|
||||
|
||||
// The picker is a controlled component. This means we expect the
|
||||
// on*Change handlers to be in charge of updating our
|
||||
// `selectedValue` prop. That way they can also
|
||||
// disallow/undo/mutate the selection of certain values. In other
|
||||
// words, the embedder of this component should be the source of
|
||||
// truth, not the native component.
|
||||
if (
|
||||
this._picker &&
|
||||
this.state.selectedIndex !== event.nativeEvent.newIndex
|
||||
) {
|
||||
this._picker.setNativeProps({
|
||||
selectedIndex: this.state.selectedIndex,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
pickerIOS: {
|
||||
// The picker will conform to whatever width is given, but we do
|
||||
// have to set the component's height explicitly on the
|
||||
// surrounding view to ensure it gets rendered.
|
||||
height: 216,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = PickerIOS;
|
||||
|
|
|
@ -12,15 +12,14 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
var StyleSheet = require('StyleSheet');
|
||||
const React = require('react');
|
||||
const StyleSheet = require('../../StyleSheet/StyleSheet');
|
||||
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
const RCTProgressViewNativeComponent = require('./RCTProgressViewNativeComponent');
|
||||
|
||||
import type {NativeComponent} from 'ReactNative';
|
||||
import type {ImageSource} from 'ImageSource';
|
||||
import type {ColorValue} from 'StyleSheetTypes';
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
import type {ImageSource} from '../../Image/ImageSource';
|
||||
import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
|
||||
import type {ViewProps} from '../View/ViewPropTypes';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
|
@ -56,20 +55,14 @@ type Props = $ReadOnly<{|
|
|||
trackImage?: ?ImageSource,
|
||||
|}>;
|
||||
|
||||
type NativeProgressViewIOS = Class<NativeComponent<Props>>;
|
||||
|
||||
const RCTProgressView = ((requireNativeComponent(
|
||||
'RCTProgressView',
|
||||
): any): NativeProgressViewIOS);
|
||||
|
||||
/**
|
||||
* Use `ProgressViewIOS` to render a UIProgressView on iOS.
|
||||
*/
|
||||
const ProgressViewIOS = (
|
||||
props: Props,
|
||||
forwardedRef?: ?React.Ref<typeof RCTProgressView>,
|
||||
forwardedRef?: ?React.Ref<typeof RCTProgressViewNativeComponent>,
|
||||
) => (
|
||||
<RCTProgressView
|
||||
<RCTProgressViewNativeComponent
|
||||
{...props}
|
||||
style={[styles.progressView, props.style]}
|
||||
ref={forwardedRef}
|
||||
|
@ -82,11 +75,9 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
// $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet.
|
||||
const ProgressViewIOSWithRef = React.forwardRef(ProgressViewIOS);
|
||||
|
||||
/* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an
|
||||
* error found when Flow v0.89 was deployed. To see the error, delete this
|
||||
* comment and run Flow. */
|
||||
// $FlowFixMe
|
||||
module.exports = (ProgressViewIOSWithRef: NativeProgressViewIOS);
|
||||
module.exports = (ProgressViewIOSWithRef: typeof RCTProgressViewNativeComponent);
|
||||
|
|
|
@ -25,6 +25,13 @@ const DebugInstructions = Platform.select({
|
|||
Native debug menu.
|
||||
</Text>
|
||||
),
|
||||
// [TODO(macOS ISS#2323203)
|
||||
macos: () => (
|
||||
<Text>
|
||||
Secondary click in this window to open the React Native debug menu.
|
||||
</Text>
|
||||
),
|
||||
// ]TODO(macOS ISS#2323203)
|
||||
default: () => (
|
||||
<Text>
|
||||
Press <Text style={styles.highlight}>menu button</Text> or{' '}
|
||||
|
|
|
@ -24,6 +24,14 @@ const ReloadInstructions = Platform.select({
|
|||
reload your app's code.
|
||||
</Text>
|
||||
),
|
||||
// [TODO(macOS ISS#2323203)
|
||||
macos: () => (
|
||||
<Text>
|
||||
Secondary click in this window and choose{' '}
|
||||
<Text style={styles.highlight}>Reload</Text> to reload your app's code.
|
||||
</Text>
|
||||
),
|
||||
// ]TODO(macOS ISS#2323203)
|
||||
default: () => (
|
||||
<Text>
|
||||
Double tap <Text style={styles.highlight}>R</Text> on your keyboard to
|
||||
|
|
|
@ -16,10 +16,9 @@ const warnOnce = require('warnOnce');
|
|||
// Export React, plus some native additions.
|
||||
module.exports = {
|
||||
// Components
|
||||
/*
|
||||
get AccessibilityInfo() {
|
||||
return require('AccessibilityInfo');
|
||||
},*/
|
||||
},
|
||||
get ActivityIndicator() {
|
||||
return require('ActivityIndicator');
|
||||
},
|
||||
|
@ -57,8 +56,7 @@ module.exports = {
|
|||
/*
|
||||
get ImageEditor() {
|
||||
return require('ImageEditor');
|
||||
},
|
||||
*/
|
||||
},*/
|
||||
get ImageStore() {
|
||||
warnOnce(
|
||||
'imagestore-deprecation',
|
||||
|
@ -76,15 +74,14 @@ module.exports = {
|
|||
get KeyboardAvoidingView() {
|
||||
return require('KeyboardAvoidingView');
|
||||
},
|
||||
get ListView() {
|
||||
get ListView() {
|
||||
warnOnce(
|
||||
'listview-deprecation',
|
||||
'ListView is deprecated and will be removed in a future release. ' +
|
||||
'See https://fb.me/nolistview for more information',
|
||||
);
|
||||
return require('ListView');
|
||||
},
|
||||
/*
|
||||
},*/
|
||||
get MaskedViewIOS() {
|
||||
warnOnce(
|
||||
'maskedviewios-moved',
|
||||
|
@ -94,6 +91,7 @@ module.exports = {
|
|||
);
|
||||
return require('MaskedViewIOS');
|
||||
},
|
||||
/*
|
||||
get Modal() {
|
||||
return require('Modal');
|
||||
},*/
|
||||
|
@ -103,13 +101,12 @@ module.exports = {
|
|||
get PickerIOS() {
|
||||
return require('../Components/Picker/PickerIOS');
|
||||
},
|
||||
/*
|
||||
get ProgressBarAndroid() {
|
||||
return require('ProgressBarAndroid');
|
||||
},
|
||||
get ProgressViewIOS() {
|
||||
return require('ProgressViewIOS');
|
||||
},*/
|
||||
},
|
||||
get SafeAreaView() {
|
||||
return require('SafeAreaView');
|
||||
},
|
||||
|
@ -119,11 +116,9 @@ module.exports = {
|
|||
get SectionList() {
|
||||
return require('SectionList');
|
||||
},
|
||||
/*
|
||||
get SegmentedControlIOS() {
|
||||
return require('SegmentedControlIOS');
|
||||
},
|
||||
*/
|
||||
get Slider() {
|
||||
warnOnce(
|
||||
'slider-moved',
|
||||
|
@ -139,10 +134,11 @@ module.exports = {
|
|||
/*
|
||||
get RefreshControl() {
|
||||
return require('RefreshControl');
|
||||
},
|
||||
},*/
|
||||
get StatusBar() {
|
||||
return require('StatusBar');
|
||||
},
|
||||
/*
|
||||
get SwipeableFlatList() {
|
||||
return require('SwipeableFlatList');
|
||||
},*/
|
||||
|
|
|
@ -135,6 +135,8 @@
|
|||
2DE7E8061FB2A4F3009E225D /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D51DA2DD8B000FE1B8 /* libRCTWebSocket-tvOS.a */; };
|
||||
2DE7E8071FB2A4F3009E225D /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D91DA2DD8B000FE1B8 /* libReact.a */; };
|
||||
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
|
||||
383C517F243447EC00CCBC30 /* UpdatePropertiesExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.m */; };
|
||||
383C51A624344A4600CCBC30 /* FlexibleSizeExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */; };
|
||||
38C500E222D3CF2E00BCD999 /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 38C500E122D3CF2E00BCD999 /* RCTConvert_UIColorTests.m */; };
|
||||
39AA31A41DC1DFDC000F7EBB /* RCTUnicodeDecodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 39AA31A31DC1DFDC000F7EBB /* RCTUnicodeDecodeTests.m */; };
|
||||
3D05746D1DE6008900184BB4 /* libRCTPushNotification-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D05746C1DE6008900184BB4 /* libRCTPushNotification-tvOS.a */; };
|
||||
|
@ -3130,6 +3132,8 @@
|
|||
18FC77901EF4770B002B3F17 /* ViewController.m in Sources */,
|
||||
18FC778D1EF4770B002B3F17 /* main.m in Sources */,
|
||||
18FC778A1EF4770B002B3F17 /* AppDelegate.m in Sources */,
|
||||
383C51A624344A4600CCBC30 /* FlexibleSizeExampleView.m in Sources */,
|
||||
383C517F243447EC00CCBC30 /* UpdatePropertiesExampleView.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <React/RCTUIKit.h> // TODO(macOS ISS#2323203)
|
||||
|
||||
#import <React/RCTView.h>
|
||||
|
||||
|
|
|
@ -13,7 +13,12 @@
|
|||
#import <React/RCTRootViewDelegate.h>
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
#import "AppDelegate.h"
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
#import "../../RNTester-macOS/AppDelegate.h"
|
||||
#define UITextView NSTextView
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
|
||||
@interface FlexibleSizeExampleViewManager : RCTViewManager
|
||||
|
||||
|
@ -23,7 +28,7 @@
|
|||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (UIView *)view
|
||||
- (RCTUIView *)view // TODO(macOS ISS#2323203)
|
||||
{
|
||||
return [FlexibleSizeExampleView new];
|
||||
}
|
||||
|
@ -60,9 +65,13 @@ RCT_EXPORT_MODULE();
|
|||
#ifndef TARGET_OS_TV
|
||||
_currentSizeTextView.editable = NO;
|
||||
#endif
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.text = @"Resizable view has not been resized yet";
|
||||
_currentSizeTextView.textColor = [UIColor blackColor];
|
||||
_currentSizeTextView.backgroundColor = [UIColor whiteColor];
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.string = @"Resizable view has not been resized yet";
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.textColor = [RCTUIColor blackColor]; // TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.backgroundColor = [RCTUIColor whiteColor]; // TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.font = [UIFont boldSystemFontOfSize:10];
|
||||
|
||||
_resizableRootView.delegate = self;
|
||||
|
@ -82,7 +91,8 @@ RCT_EXPORT_MODULE();
|
|||
}
|
||||
|
||||
|
||||
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
|
||||
- (NSArray<RCTUIView<RCTComponent> *> *)reactSubviews // TODO(macOS ISS#2323203)
|
||||
|
||||
{
|
||||
// this is to avoid unregistering our RCTRootView when the component is removed from RN hierarchy
|
||||
(void)[super reactSubviews];
|
||||
|
@ -99,10 +109,20 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
if (!_sizeUpdated) {
|
||||
_sizeUpdated = TRUE;
|
||||
_currentSizeTextView.text = [NSString stringWithFormat:@"RCTRootViewDelegate: content with initially unknown size has appeared, updating root view's size so the content fits."];
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.text =
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.string =
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
[NSString stringWithFormat:@"RCTRootViewDelegate: content with initially unknown size has appeared, updating root view's size so the content fits."];
|
||||
|
||||
} else {
|
||||
_currentSizeTextView.text = [NSString stringWithFormat:@"RCTRootViewDelegate: content size has been changed to (%ld, %ld), updating root view's size.",
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.text =
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
_currentSizeTextView.string =
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
[NSString stringWithFormat:@"RCTRootViewDelegate: content size has been changed to (%ld, %ld), updating root view's size.",
|
||||
(long)newFrame.size.width,
|
||||
(long)newFrame.size.height];
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <React/RCTUIKit.h> // TODO(macOS ISS#2323203)
|
||||
|
||||
#import <React/RCTView.h>
|
||||
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
#import "AppDelegate.h"
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
#import "../../RNTester-macOS/AppDelegate.h"
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
|
||||
@interface UpdatePropertiesExampleViewManager : RCTViewManager
|
||||
|
||||
|
@ -21,7 +25,7 @@
|
|||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (UIView *)view
|
||||
- (RCTUIView *)view // TODO(macOS ISS#2323203)
|
||||
{
|
||||
return [UpdatePropertiesExampleView new];
|
||||
}
|
||||
|
@ -31,7 +35,11 @@ RCT_EXPORT_MODULE();
|
|||
@implementation UpdatePropertiesExampleView
|
||||
{
|
||||
RCTRootView *_rootView;
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
UIButton *_button;
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
NSButton *_button;
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
BOOL _beige;
|
||||
}
|
||||
|
||||
|
@ -47,6 +55,7 @@ RCT_EXPORT_MODULE();
|
|||
moduleName:@"SetPropertiesExampleApp"
|
||||
initialProperties:@{@"color":@"beige"}];
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
_button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
[_button setTitle:@"Native Button" forState:UIControlStateNormal];
|
||||
[_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
|
@ -55,6 +64,12 @@ RCT_EXPORT_MODULE();
|
|||
[_button addTarget:self
|
||||
action:@selector(changeColor)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
#else // [TODO(macOS ISS#2323203)
|
||||
_button = [[NSButton alloc] init];
|
||||
[_button setTitle:@"Native Button"];
|
||||
[_button setTarget:self];
|
||||
[_button setAction:@selector(changeColor)];
|
||||
#endif // ]TODO(macOS ISS#2323203)
|
||||
|
||||
[self addSubview:_button];
|
||||
[self addSubview:_rootView];
|
||||
|
@ -79,7 +94,7 @@ RCT_EXPORT_MODULE();
|
|||
[_rootView setAppProperties:@{@"color":_beige ? @"beige" : @"purple"}];
|
||||
}
|
||||
|
||||
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
|
||||
- (NSArray<RCTUIView<RCTComponent> *> *)reactSubviews // TODO(macOS ISS#2323203)
|
||||
{
|
||||
// this is to avoid unregistering our RCTRootView when the component is removed from RN hierarchy
|
||||
(void)[super reactSubviews];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* 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.
|
||||
|
@ -16,17 +16,17 @@ const ComponentExamples: Array<RNTesterExample> = [
|
|||
{
|
||||
key: 'ActivityIndicatorExample',
|
||||
module: require('./ActivityIndicatorExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'ARTExample',
|
||||
module: require('./ARTExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'ButtonExample',
|
||||
module: require('./ButtonExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'DarkModeExample',
|
||||
|
@ -41,26 +41,52 @@ const ComponentExamples: Array<RNTesterExample> = [
|
|||
{
|
||||
key: 'FlatListExample',
|
||||
module: require('./FlatListExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
// [TODO(OSS Candidate ISS#2710739)
|
||||
{
|
||||
key: 'FocusEvents',
|
||||
module: require('./FocusEventsExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
}, // ]TODO(OSS Candidate ISS#2710739)
|
||||
{
|
||||
key: 'ImageExample',
|
||||
module: require('./ImageExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'InputAccessoryViewExample',
|
||||
module: require('./InputAccessoryViewExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'KeyboardAvoidingViewExample',
|
||||
module: require('./KeyboardAvoidingViewExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'LayoutEventsExample',
|
||||
module: require('./LayoutEventsExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'MaskedViewExample',
|
||||
module: require('./MaskedViewExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
/* {
|
||||
key: 'ModalExample',
|
||||
module: require('./ModalExample'),
|
||||
supportsTVOS: true,
|
||||
}, */
|
||||
{
|
||||
key: 'MultiColumnExample',
|
||||
module: require('./MultiColumnExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'NewAppScreenExample',
|
||||
module: require('./NewAppScreenExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
|
@ -68,14 +94,44 @@ const ComponentExamples: Array<RNTesterExample> = [
|
|||
module: require('./PickerExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
/* {
|
||||
key: 'PickerIOSExample',
|
||||
module: require('./PickerIOSExample'),
|
||||
supportsTVOS: false,
|
||||
}, */
|
||||
{
|
||||
key: 'ProgressViewIOSExample',
|
||||
module: require('./ProgressViewIOSExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'RefreshControlExample',
|
||||
module: require('./RefreshControlExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'ScrollViewSimpleExample',
|
||||
module: require('./ScrollViewSimpleExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'SafeAreaViewExample',
|
||||
module: require('./SafeAreaViewExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'ScrollViewExample',
|
||||
module: require('./ScrollViewExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'SectionListExample',
|
||||
module: require('./SectionListExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'SegmentedControlIOSExample',
|
||||
module: require('./SegmentedControlIOSExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
|
@ -83,6 +139,11 @@ const ComponentExamples: Array<RNTesterExample> = [
|
|||
module: require('./SliderExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
/* { Depends on Modal which is not implemented for macOS
|
||||
key: 'StatusBarExample',
|
||||
module: require('./StatusBarExample'),
|
||||
supportsTVOS: false,
|
||||
}, */
|
||||
{
|
||||
key: 'SwitchExample',
|
||||
module: require('./SwitchExample'),
|
||||
|
@ -91,17 +152,17 @@ const ComponentExamples: Array<RNTesterExample> = [
|
|||
{
|
||||
key: 'TextExample',
|
||||
module: require('./TextExample.macos'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'TextInputExample',
|
||||
module: require('./TextInputExample.macos'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'TouchableExample',
|
||||
module: require('./TouchableExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'TransparentHitTestExample',
|
||||
|
@ -111,44 +172,64 @@ const ComponentExamples: Array<RNTesterExample> = [
|
|||
{
|
||||
key: 'ViewExample',
|
||||
module: require('./ViewExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
];
|
||||
|
||||
const APIExamples: Array<RNTesterExample> = [
|
||||
{
|
||||
key: 'AccessibilityExample',
|
||||
module: require('./AccessibilityExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'AccessibilityIOSExample',
|
||||
module: require('./AccessibilityIOSExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'ActionSheetIOSExample',
|
||||
module: require('./ActionSheetMacOSExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'AnimatedExampleMacOS',
|
||||
module: require('./AnimatedExampleMacOS'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'AlertExample',
|
||||
module: require('./AlertExample').AlertExample,
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'AnExApp',
|
||||
module: require('./AnimatedGratuitousApp/AnExApp'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'AlertMacOSExample',
|
||||
module: require('./AlertMacOSExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'AsyncStorageExample',
|
||||
module: require('./AsyncStorageExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'BorderExample',
|
||||
module: require('./BorderExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'BoxShadowExample',
|
||||
module: require('./BoxShadowExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'CameraRollExample',
|
||||
module: require('./CameraRollExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
|
@ -156,24 +237,44 @@ const APIExamples: Array<RNTesterExample> = [
|
|||
module: require('./ClipboardExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'CrashExample',
|
||||
module: require('./CrashExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'Dimensions',
|
||||
module: require('./DimensionsExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'ImageEditingExample',
|
||||
module: require('./ImageEditingExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'LayoutAnimationExample',
|
||||
module: require('./LayoutAnimationExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'LayoutExample',
|
||||
module: require('./LayoutExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'LinkingExample',
|
||||
module: require('./LinkingExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'NativeAnimationsExample',
|
||||
module: require('./NativeAnimationsExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'OrientationChangeExample',
|
||||
module: require('./OrientationChangeExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
|
@ -191,26 +292,61 @@ const APIExamples: Array<RNTesterExample> = [
|
|||
module: require('./PushNotificationIOSExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'RCTRootViewIOSExample',
|
||||
module: require('./RCTRootViewIOSExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'RTLExample',
|
||||
module: require('./RTLExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'ShareExample',
|
||||
module: require('./ShareExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'SnapshotExample',
|
||||
module: require('./SnapshotExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'TimerExample',
|
||||
module: require('./TimerExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'TransformExample',
|
||||
module: require('./TransformExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
/* {
|
||||
key: 'TurboModuleExample',
|
||||
module: require('./TurboModuleExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'TVEventHandlerExample',
|
||||
module: require('./TVEventHandlerExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'VibrationExample',
|
||||
module: require('./VibrationExample'),
|
||||
supportsTVOS: false,
|
||||
}, */
|
||||
{
|
||||
key: 'WebSocketExample',
|
||||
module: require('./WebSocketExample'),
|
||||
supportsTVOS: false,
|
||||
supportsTVOS: true,
|
||||
},
|
||||
/* {
|
||||
key: 'XHRExample',
|
||||
module: require('./XHRExample'),
|
||||
supportsTVOS: true,
|
||||
}, */
|
||||
];
|
||||
|
||||
const Modules = {};
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <React/RCTUIKit.h> // TODO(macOS ISS#2323203)
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface RCTConvert (UIStatusBar)
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
+ (UIStatusBarStyle)UIStatusBarStyle:(id)json;
|
||||
+ (UIStatusBarAnimation)UIStatusBarAnimation:(id)json;
|
||||
#endif
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#import "RCTLog.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
@implementation RCTConvert (UIStatusBar)
|
||||
|
||||
RCT_ENUM_CONVERTER(UIStatusBarStyle, (@{
|
||||
|
@ -51,7 +51,7 @@ RCT_EXPORT_MODULE()
|
|||
@"statusBarFrameWillChange"];
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_OSX // TODO(macOS ISS#2323203)
|
||||
|
||||
- (void)startObserving
|
||||
{
|
||||
|
|
|
@ -817,6 +817,8 @@
|
|||
2D74EAFA1DAE9590003B751B /* RCTMultipartDataTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 006FC4131D9B20820057AAAD /* RCTMultipartDataTask.m */; };
|
||||
2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 001BFCCF1D8381DE008E587E /* RCTMultipartStreamReader.m */; };
|
||||
352DCFF01D19F4C20056D623 /* RCTI18nUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */; };
|
||||
383C517D2434412900CCBC30 /* RCTProgressViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13513F3B1B1F43F400FCE529 /* RCTProgressViewManager.m */; };
|
||||
383C517E243446D900CCBC30 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */; };
|
||||
385362722283369800B0989C /* RCTSRWebSocket.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D7BFD2C1EA8E3FA008DFB7A /* RCTSRWebSocket.h */; };
|
||||
38B6D1FF228C879400AC0F0E /* (null) in Sources */ = {isa = PBXBuildFile; };
|
||||
38BF7CDF22AF1B9900240972 /* JSCExecutorFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8507BBBC21EDACC200AEAFCA /* JSCExecutorFactory.mm */; };
|
||||
|
@ -5685,6 +5687,7 @@
|
|||
657734931EE8356100A0E9EA /* RCTInspector.mm in Sources */,
|
||||
59EB6DBE1EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.mm in Sources */,
|
||||
18B8F97E21431D6900CE911A /* RCTPlatform.m in Sources */,
|
||||
383C517E243446D900CCBC30 /* RCTStatusBarManager.m in Sources */,
|
||||
2D3B5E971D9B089000451313 /* RCTBridge.m in Sources */,
|
||||
2D3B5E9B1D9B08A000451313 /* RCTFrameUpdate.m in Sources */,
|
||||
2D3B5EE41D9B09BB00451313 /* RCTSegmentedControlManager.m in Sources */,
|
||||
|
@ -5694,6 +5697,7 @@
|
|||
1968A2621F67275300EB3D1D /* RCTComponentEvent.m in Sources */,
|
||||
2D3B5EE31D9B09B700451313 /* RCTSegmentedControl.m in Sources */,
|
||||
189727D42141CE7E002A4E2A /* RCTSwitchManager.m in Sources */,
|
||||
383C517D2434412900CCBC30 /* RCTProgressViewManager.m in Sources */,
|
||||
130443A41E3FEAC600D93A67 /* RCTFollyConvert.mm in Sources */,
|
||||
3D7BFD201EA8E351008DFB7A /* RCTPackagerConnection.mm in Sources */,
|
||||
59E604A51FE9CCE300BD90C5 /* RCTScrollContentShadowView.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {
|
||||
copyProjectTemplateAndReplace,
|
||||
installDependencies,
|
||||
} = require('./generator-macos');
|
||||
|
||||
/**
|
||||
* Simple utility for running the macOS generator.
|
||||
*
|
||||
* @param {String} projectDir root project directory (i.e. contains index.js)
|
||||
* @param {String} name name of the root JS module for this app
|
||||
* @param {Object} options command line options container
|
||||
*/
|
||||
function generateWindows (projectDir, name, options) {
|
||||
if (!fs.existsSync(projectDir)) {
|
||||
fs.mkdirSync(projectDir);
|
||||
}
|
||||
|
||||
installDependencies(options);
|
||||
|
||||
copyProjectTemplateAndReplace(
|
||||
path.join(__dirname, 'generator-macos', 'templates'),
|
||||
projectDir,
|
||||
name,
|
||||
{ overwrite: options.overwrite }
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = generateWindows;
|
|
@ -0,0 +1,103 @@
|
|||
const fs = require('fs');
|
||||
const chalk = require('chalk');
|
||||
const path = require('path');
|
||||
const copyAndReplace = require('@react-native-community/cli/build/tools/copyAndReplace').default;
|
||||
const walk = require('@react-native-community/cli/build/tools/walk').default;
|
||||
const prompt = require('@react-native-community/cli/build/tools/generator/promptSync').default();
|
||||
|
||||
function createDir(destPath) {
|
||||
if (!fs.existsSync(destPath)) {
|
||||
fs.mkdirSync(destPath);
|
||||
}
|
||||
}
|
||||
|
||||
function copyAndReplaceWithChangedCallback(srcPath, destRoot, relativeDestPath, replacements, alwaysOverwrite) {
|
||||
if (!replacements) {
|
||||
replacements = {};
|
||||
}
|
||||
const contentChangedCallback = alwaysOverwrite ? (_, contentChanged) =>
|
||||
alwaysOverwriteContentChangedCallback(
|
||||
srcPath,
|
||||
relativeDestPath,
|
||||
contentChanged
|
||||
) : (_, contentChanged) =>
|
||||
upgradeFileContentChangedCallback(
|
||||
srcPath,
|
||||
relativeDestPath,
|
||||
contentChanged
|
||||
);
|
||||
|
||||
copyAndReplace(
|
||||
srcPath,
|
||||
path.join(destRoot, relativeDestPath),
|
||||
replacements,
|
||||
contentChangedCallback
|
||||
);
|
||||
}
|
||||
|
||||
function copyAndReplaceAll(srcPath, destPath, relativeDestDir, replacements, alwaysOverwrite) {
|
||||
walk(srcPath).forEach(absoluteSrcFilePath => {
|
||||
const filename = path.relative(srcPath, absoluteSrcFilePath);
|
||||
const relativeDestPath = path.join(relativeDestDir, filename);
|
||||
copyAndReplaceWithChangedCallback(absoluteSrcFilePath, destPath, relativeDestPath, replacements, alwaysOverwrite);
|
||||
});
|
||||
}
|
||||
|
||||
function alwaysOverwriteContentChangedCallback( absoluteSrcFilePath,
|
||||
relativeDestPath,
|
||||
contentChanged
|
||||
) {
|
||||
if (contentChanged === 'new') {
|
||||
console.log(`${chalk.bold('new')} ${relativeDestPath}`);
|
||||
return 'overwrite';
|
||||
}
|
||||
if (contentChanged === 'changed') {
|
||||
console.log(`${chalk.bold('changed')} ${relativeDestPath} ${chalk.yellow('[overwriting]')}`);
|
||||
return 'overwrite';
|
||||
}
|
||||
if (contentChanged === 'identical') {
|
||||
return 'keep';
|
||||
}
|
||||
throw new Error(
|
||||
`Unknown file changed state: ${relativeDestPath}, ${contentChanged}`
|
||||
);
|
||||
}
|
||||
|
||||
function upgradeFileContentChangedCallback(
|
||||
absoluteSrcFilePath,
|
||||
relativeDestPath,
|
||||
contentChanged
|
||||
) {
|
||||
if (contentChanged === 'new') {
|
||||
console.log(`${chalk.bold('new')} ${relativeDestPath}`);
|
||||
return 'overwrite';
|
||||
}
|
||||
if (contentChanged === 'changed') {
|
||||
console.log(
|
||||
`${chalk.bold(relativeDestPath)} ` +
|
||||
`has changed in the new version.\nDo you want to keep your ${relativeDestPath} or replace it with the ` +
|
||||
'latest version?\nIf you ever made any changes ' +
|
||||
'to this file, you\'ll probably want to keep it.\n' +
|
||||
`You can see the new version here: ${absoluteSrcFilePath}\n` +
|
||||
`Do you want to replace ${relativeDestPath}? ` +
|
||||
'Answer y to replace, n to keep your version: '
|
||||
);
|
||||
const answer = prompt();
|
||||
if (answer === 'y') {
|
||||
console.log(`Replacing ${relativeDestPath}`);
|
||||
return 'overwrite';
|
||||
}
|
||||
console.log(`Keeping your ${relativeDestPath}`);
|
||||
return 'keep';
|
||||
}
|
||||
if (contentChanged === 'identical') {
|
||||
return 'keep';
|
||||
}
|
||||
throw new Error(
|
||||
`Unknown file changed state: ${relativeDestPath}, ${contentChanged}`
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createDir, copyAndReplaceWithChangedCallback, copyAndReplaceAll,
|
||||
};
|
|
@ -0,0 +1,86 @@
|
|||
'use strict';
|
||||
const chalk = require('chalk');
|
||||
const path = require('path');
|
||||
const childProcess = require('child_process');
|
||||
const fs = require('fs');
|
||||
const {
|
||||
createDir,
|
||||
copyAndReplaceAll,
|
||||
copyAndReplaceWithChangedCallback,
|
||||
} = require('../generator-common');
|
||||
|
||||
const macOSDir = 'macos';
|
||||
|
||||
function copyProjectTemplateAndReplace(
|
||||
srcRootPath,
|
||||
destPath,
|
||||
newProjectName,
|
||||
options = {}
|
||||
) {
|
||||
if (!srcRootPath) {
|
||||
throw new Error('Need a path to copy from');
|
||||
}
|
||||
|
||||
if (!destPath) {
|
||||
throw new Error('Need a path to copy to');
|
||||
}
|
||||
|
||||
if (!newProjectName) {
|
||||
throw new Error('Need a project name');
|
||||
}
|
||||
|
||||
const projectNameMacOS = newProjectName + '-macOS';
|
||||
const projectNameIOS = newProjectName;
|
||||
const xcodeProjName = newProjectName + '.xcodeproj';
|
||||
const schemeNameMacOS = newProjectName + '-macOS.xcscheme';
|
||||
const schemeNameIOS = newProjectName + '.xcscheme';
|
||||
|
||||
createDir(path.join(destPath, macOSDir));
|
||||
createDir(path.join(destPath, macOSDir, projectNameIOS));
|
||||
createDir(path.join(destPath, macOSDir, projectNameMacOS));
|
||||
createDir(path.join(destPath, macOSDir, xcodeProjName));
|
||||
createDir(path.join(destPath, macOSDir, xcodeProjName, 'xcshareddata'));
|
||||
createDir(path.join(destPath, macOSDir, xcodeProjName, 'xcshareddata/xcschemes'));
|
||||
|
||||
const templateVars = {
|
||||
'HelloWorld': newProjectName,
|
||||
};
|
||||
|
||||
[
|
||||
{ from: path.join(srcRootPath, 'macos/HelloWorld'), to: path.join(macOSDir, projectNameIOS) },
|
||||
{ from: path.join(srcRootPath, 'macos/HelloWorld-macOS'), to: path.join(macOSDir, projectNameMacOS) },
|
||||
{ from: path.join(srcRootPath, 'macos/HelloWorld.xcodeproj'), to: path.join(macOSDir, xcodeProjName) },
|
||||
{ from: path.join(srcRootPath, 'macos/xcschemes/HelloWorld-macOS.xcscheme'), to: path.join(macOSDir, xcodeProjName, 'xcshareddata/xcschemes', schemeNameMacOS) },
|
||||
{ from: path.join(srcRootPath, 'macos/xcschemes/HelloWorld.xcscheme'), to: path.join(macOSDir, xcodeProjName, 'xcshareddata/xcschemes', schemeNameIOS) },
|
||||
].forEach((mapping) => copyAndReplaceAll(mapping.from, destPath, mapping.to, templateVars, options.overwrite));
|
||||
|
||||
[
|
||||
{ from: path.join(srcRootPath, 'react-native.config.js'), to: 'react-native.config.js' },
|
||||
{ from: path.join(srcRootPath, 'metro.config.macos.js'), to: 'metro.config.macos.js' },
|
||||
].forEach((mapping) => copyAndReplaceWithChangedCallback(mapping.from, destPath, mapping.to, templateVars, options.overwrite));
|
||||
|
||||
console.log(chalk.white.bold('To run your app on macOS:'));
|
||||
console.log(chalk.white(` open ${macOSDir}/${xcodeProjName}`));
|
||||
console.log(chalk.white(' yarn start:macos'));
|
||||
console.log(chalk.white.bold(`In Xcode switch to the ${projectNameMacOS} scheme then click Run.`));
|
||||
}
|
||||
|
||||
function installDependencies(options) {
|
||||
const cwd = process.cwd();
|
||||
|
||||
// Patch package.json to have start:macos
|
||||
const projectPackageJsonPath = path.join(cwd, 'package.json');
|
||||
const projectPackageJson = JSON.parse(fs.readFileSync(projectPackageJsonPath, { encoding: 'UTF8' }));
|
||||
projectPackageJson.scripts['start:macos'] = 'node node_modules/react-native-macos/local-cli/cli.js start --use-react-native-macos';
|
||||
fs.writeFileSync(projectPackageJsonPath, JSON.stringify(projectPackageJson, null, 2));
|
||||
|
||||
// Install dependencies using correct package manager
|
||||
const isYarn = fs.existsSync(path.join(cwd, 'yarn.lock'));
|
||||
const execOptions = options && options.verbose ? { stdio: 'inherit' } : {};
|
||||
childProcess.execSync(isYarn ? 'yarn' : 'npm i', execOptions);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
copyProjectTemplateAndReplace,
|
||||
installDependencies,
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (nonatomic, readonly) RCTBridge *bridge;
|
||||
|
||||
@end
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
|
||||
@interface AppDelegate () <RCTBridgeDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
|
||||
_bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
// Insert code here to initialize your application
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||
// Insert code here to tear down your application
|
||||
}
|
||||
|
||||
#pragma mark - RCTBridgeDelegate Methods
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge {
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:@"main"]; // .jsbundle;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,713 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
<scene sceneID="JPo-4y-FX3">
|
||||
<objects>
|
||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="HelloWorld" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="HelloWorld" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About HelloWorld" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide HelloWorld" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit HelloWorld" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="dMs-cI-mzQ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<connections>
|
||||
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
|
||||
<connections>
|
||||
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||
<connections>
|
||||
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||
<connections>
|
||||
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||
<connections>
|
||||
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<connections>
|
||||
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||
<connections>
|
||||
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||
<menuItem title="Find" id="4EN-yA-p0u">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
|
||||
<items>
|
||||
<menuItem title="Font" id="Gi5-1S-RQB">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
|
||||
<connections>
|
||||
<action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
|
||||
<menuItem title="Kern" id="jBQ-r6-VK2">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="GUa-eO-cwY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="cDB-IK-hbR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="46P-cB-AYj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="ogc-rX-tC1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="o6e-r0-MWq">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="agt-UL-0e3">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="J7y-lM-qPV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="xQD-1f-W4t">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="OaQ-X3-Vso">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="3Om-Ey-2VK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="Rqc-34-cIF">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="I0S-gh-46l">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="2h7-ER-AoG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="1tx-W0-xDw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="Fal-I4-PZk">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="d9c-me-L2H">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="J5U-5w-g23">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
|
||||
<menuItem title="Writing Direction" id="H1b-Si-o9J">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title=" Default" id="YGs-j5-SAR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title=" Left to Right" id="Lbh-J2-qVU">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title=" Right to Left" id="jFq-tB-4Kx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
|
||||
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title=" Default" id="Nop-cj-93Q">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title=" Left to Right" id="BgM-ve-c93">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title=" Right to Left" id="RB4-Sm-HuC">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
|
||||
<menuItem title="Show Ruler" id="vLm-3I-IUL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
|
||||
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="HelloWorld Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
||||
</connections>
|
||||
</application>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="0.0"/>
|
||||
</scene>
|
||||
<!--Window Controller-->
|
||||
<scene sceneID="R2V-B0-nI4">
|
||||
<objects>
|
||||
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
||||
<window key="window" title="HelloWorld" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="480" height="720"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
|
||||
</connections>
|
||||
</window>
|
||||
<connections>
|
||||
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
|
||||
</connections>
|
||||
</windowController>
|
||||
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="467"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="hIz-AP-VOD">
|
||||
<objects>
|
||||
<viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
|
||||
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="720"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="640" y="467"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +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.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface ViewController : NSViewController
|
||||
|
||||
@end
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "ViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
RCTBridge *bridge = [((AppDelegate *)[NSApp delegate])bridge];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"HelloWorld" initialProperties:nil];
|
||||
|
||||
NSView *view = [self view];
|
||||
|
||||
[view addSubview:rootView];
|
||||
[rootView setBackgroundColor:[NSColor windowBackgroundColor]];
|
||||
[rootView setFrame:[view bounds]];
|
||||
[rootView setAutoresizingMask:(NSViewMinXMargin | NSViewMinXMargin | NSViewMinYMargin | NSViewMaxYMargin | NSViewWidthSizable | NSViewHeightSizable)];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +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.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Original</string>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"HelloWorld"
|
||||
initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="HelloWorld" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>HelloWorld</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1120"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "6B857DA21EC51FC600A9D063"
|
||||
BuildableName = "libReact.a"
|
||||
BlueprintName = "React-macOS"
|
||||
ReferencedContainer = "container:../node_modules/react-native-macos/React/React.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "38C1415723BBE33000902604"
|
||||
BuildableName = "HelloWorld-macOS.app"
|
||||
BlueprintName = "HelloWorld-macOS"
|
||||
ReferencedContainer = "container:HelloWorld.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "38C1415723BBE33000902604"
|
||||
BuildableName = "HelloWorld-macOS.app"
|
||||
BlueprintName = "HelloWorld-macOS"
|
||||
ReferencedContainer = "container:HelloWorld.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "38C1415723BBE33000902604"
|
||||
BuildableName = "HelloWorld-macOS.app"
|
||||
BlueprintName = "HelloWorld-macOS"
|
||||
ReferencedContainer = "container:HelloWorld.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1120"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
|
||||
BuildableName = "libReact.a"
|
||||
BlueprintName = "React"
|
||||
ReferencedContainer = "container:../node_modules/react-native-macos/React/React.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "HelloWorld.app"
|
||||
BlueprintName = "HelloWorld"
|
||||
ReferencedContainer = "container:HelloWorld.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "HelloWorld.app"
|
||||
BlueprintName = "HelloWorld"
|
||||
ReferencedContainer = "container:HelloWorld.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "HelloWorld.app"
|
||||
BlueprintName = "HelloWorld"
|
||||
ReferencedContainer = "container:HelloWorld.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* This cli config is needed for development purposes, e.g. for running
|
||||
* integration tests during local development or on CI services.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const blacklist = require('metro-config/src/defaults/blacklist');
|
||||
|
||||
const rnmPath = path.resolve(__dirname, 'node_modules/react-native-macos');
|
||||
|
||||
module.exports = {
|
||||
resolver: {
|
||||
extraNodeModules: {
|
||||
'react-native': rnmPath,
|
||||
},
|
||||
platforms: ['macos', 'ios', 'android'],
|
||||
blacklistRE: blacklist([/node_modules\/react-native\/.*/]),
|
||||
},
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* This cli config is needed for the coexistance of react-native and other
|
||||
* out-of-tree implementations such react-native-macos.
|
||||
* The following issue is tracked by
|
||||
* https://github.com/react-native-community/discussions-and-proposals/issues/182
|
||||
*
|
||||
* The work-around involves having a metro.config.js for each out-of-tree
|
||||
* platform, i.e. metro.config.js for react-native and
|
||||
* metro.config.macos.js for react-native-macos.
|
||||
* This react-native.config.js looks for a --use-react-native-macos
|
||||
* switch and when present pushes --config=metro.config.macos.js
|
||||
* and specifies reactNativePath: 'node_modules/react-native-macos'.
|
||||
* The metro.config.js has to blacklist 'node_modules/react-native-macos',
|
||||
* and conversely metro.config.macos.js has to blacklist 'node_modules/react-native'.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const macSwitch = '--use-react-native-macos';
|
||||
const windowsSwitch = '--use-react-native-windows';
|
||||
|
||||
if (process.argv.includes(macSwitch)) {
|
||||
process.argv = process.argv.filter(arg => arg !== macSwitch);
|
||||
process.argv.push('--config=metro.config.macos.js');
|
||||
module.exports = {
|
||||
reactNativePath: 'node_modules/react-native-macos',
|
||||
};
|
||||
} else if (process.argv.includes(windowsSwitch)) {
|
||||
process.argv = process.argv.filter(arg => arg !== windowsSwitch);
|
||||
process.argv.push('--config=metro.config.windows.js');
|
||||
module.exports = {
|
||||
reactNativePath: 'node_modules/react-native-windows',
|
||||
};
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
lib/
|
||||
lib-commonjs/
|
|
@ -0,0 +1,24 @@
|
|||
# react-native-macos-init
|
||||
|
||||
CLI to bootstrap the addition of the macOS platform to `react-native` projects.
|
||||
|
||||
## Usage
|
||||
|
||||
Run this from an existing `react-native` project to install `react-native-macos` and generate initial project files for macOS.
|
||||
|
||||
|
||||
Example usage
|
||||
```
|
||||
$ npx react-native init AwesomeProject
|
||||
$ cd AwesomeProject
|
||||
$ npx react-native-macos-init
|
||||
```
|
||||
|
||||
Options:
|
||||
| option | description | type |
|
||||
|--------------|------------------------------------------------|-----------|
|
||||
| --help | Show help | [boolean] |
|
||||
| --version | The version of react-native-macos to use | [string] |
|
||||
| --verbose | Enables logging | [boolean] |
|
||||
| --overwrite | Overwrite any existing files without prompting | [boolean] |
|
||||
| --prerelease | Install prerelease version without prompting | [boolean] |
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
* Licensed under the MIT License.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
// Yarn will fail to link workspace binaries if they haven't been built yet. Add
|
||||
// a simple JS file to forward to the CLI which is built after install.
|
||||
require('./lib-commonjs/cli');
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
* Licensed under the MIT License.
|
||||
*
|
||||
* @format
|
||||
* @ts-check
|
||||
*/
|
||||
|
||||
const {eslintTask, series, task, taskPresets} = require('just-scripts');
|
||||
|
||||
taskPresets.lib();
|
||||
|
||||
task('eslint', () => {
|
||||
return eslintTask();
|
||||
});
|
||||
task('eslint:fix', () => {
|
||||
return eslintTask({fix: true});
|
||||
});
|
||||
task('lint', series('eslint'));
|
||||
task('lint:fix', series('eslint:fix'));
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "react-native-macos-init",
|
||||
"version": "0.0.9",
|
||||
"description": "CLI to add react-native-macos to an existing react-native project",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/microsoft/react-native-macos",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"build": "just-scripts build",
|
||||
"clean": "just-scripts clean",
|
||||
"lint": "just-scripts lint",
|
||||
"lint:fix": "just-scripts lint:fix"
|
||||
},
|
||||
"bin": {
|
||||
"react-native-macos-init": "./bin.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^3",
|
||||
"npm-registry": "^0.1.13",
|
||||
"prompts": "^2.3.0",
|
||||
"find-up": "^4.1.0",
|
||||
"semver": "^7.1.3",
|
||||
"valid-url": "^1.0.9",
|
||||
"yargs": "^15.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/prompts": "^2.0.3",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/valid-url": "^1.0.2",
|
||||
"@types/yargs": "^15.0.3",
|
||||
"just-scripts": "^0.36.1",
|
||||
"typescript": "3.5.3"
|
||||
},
|
||||
"files": [
|
||||
"bin.js",
|
||||
"lib-commonjs",
|
||||
"README.md"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
* Licensed under the MIT License.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import * as yargs from 'yargs';
|
||||
import * as fs from 'fs';
|
||||
import * as semver from 'semver';
|
||||
import {execSync} from 'child_process';
|
||||
import * as validUrl from 'valid-url';
|
||||
import * as prompts from 'prompts';
|
||||
import * as findUp from 'find-up';
|
||||
import * as chalk from 'chalk';
|
||||
// @ts-ignore
|
||||
import * as Registry from 'npm-registry';
|
||||
|
||||
const npmConfReg = execSync('npm config get registry')
|
||||
.toString()
|
||||
.trim();
|
||||
const NPM_REGISTRY_URL = validUrl.isUri(npmConfReg)
|
||||
? npmConfReg
|
||||
: 'http://registry.npmjs.org';
|
||||
const npm = new Registry({registry: NPM_REGISTRY_URL});
|
||||
|
||||
const argv = yargs.version(false).options({
|
||||
version: {
|
||||
type: 'string',
|
||||
describe: 'The version of react-native-macos to use',
|
||||
},
|
||||
verbose: {type: 'boolean', describe: 'Enables logging'},
|
||||
overwrite: {
|
||||
type: 'boolean',
|
||||
describe: 'Overwrite any existing files without prompting',
|
||||
},
|
||||
prerelease: {
|
||||
type: 'boolean',
|
||||
describe: 'Install prerelease version without prompting',
|
||||
},
|
||||
}).argv;
|
||||
|
||||
const EXITCODE_NO_MATCHING_RNMACOS = 2;
|
||||
const EXITCODE_UNSUPPORTED_VERION_RN = 3;
|
||||
const EXITCODE_USER_CANCEL = 4;
|
||||
const EXITCODE_NO_REACTNATIVE_FOUND = 5;
|
||||
const EXITCODE_UNKNOWN_ERROR = 6;
|
||||
const EXITCODE_NO_PACKAGE_JSON = 7;
|
||||
|
||||
function reactNativeMacOSGeneratePath() {
|
||||
return require.resolve('react-native-macos/local-cli/generate-macos.js', {
|
||||
paths: [process.cwd()],
|
||||
});
|
||||
}
|
||||
|
||||
function getReactNativeAppName() {
|
||||
console.log('Reading application name from package.json...');
|
||||
const cwd = process.cwd();
|
||||
const pkgJsonPath = findUp.sync('package.json', {cwd});
|
||||
if (!pkgJsonPath) {
|
||||
console.error(
|
||||
'Unable to find package.json. This should be run from within an existing react-native app.',
|
||||
);
|
||||
process.exit(EXITCODE_NO_PACKAGE_JSON);
|
||||
}
|
||||
let name = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')).name;
|
||||
if (!name) {
|
||||
const appJsonPath = findUp.sync('app.json', {cwd});
|
||||
if (appJsonPath) {
|
||||
console.log('Reading application name from app.json...');
|
||||
name = JSON.parse(fs.readFileSync(appJsonPath, 'utf8')).name;
|
||||
}
|
||||
}
|
||||
if (!name) {
|
||||
console.error('Please specify name in package.json or app.json');
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
function getReactNativeVersion() {
|
||||
console.log('Reading react-native version from node_modules...');
|
||||
const rnPkgJsonPath = require.resolve('react-native/package.json', {
|
||||
paths: [process.cwd()],
|
||||
});
|
||||
if (fs.existsSync(rnPkgJsonPath)) {
|
||||
return require(rnPkgJsonPath).version;
|
||||
}
|
||||
|
||||
console.error(
|
||||
'Error: Must be run from a project that already depends on react-native, and has react-native installed.',
|
||||
);
|
||||
process.exit(EXITCODE_NO_REACTNATIVE_FOUND);
|
||||
}
|
||||
|
||||
function errorOutOnUnsupportedVersionOfReactNative(rnVersion: string) {
|
||||
console.error(`Error: Unsupported version of react-native: ${chalk.cyan(
|
||||
rnVersion,
|
||||
)}
|
||||
react-native-macos supports react-native versions ${chalk.cyan('>=0.60')}`);
|
||||
process.exit(EXITCODE_UNSUPPORTED_VERION_RN);
|
||||
}
|
||||
|
||||
function getDefaultReactNativeMacOSSemVerForReactNativeVersion(
|
||||
rnVersion: string,
|
||||
reactNativeMacOSLatestVersion: string
|
||||
) {
|
||||
const validVersion = semver.valid(rnVersion);
|
||||
if (validVersion) {
|
||||
const majorRN = semver.major(validVersion);
|
||||
const minorRN = semver.minor(validVersion);
|
||||
if (majorRN === 0 && minorRN >= 60) {
|
||||
const majorRNMac = semver.major(reactNativeMacOSLatestVersion);
|
||||
const minorRNMac = semver.minor(reactNativeMacOSLatestVersion);
|
||||
const major = Math.min(majorRN, majorRNMac);
|
||||
const minor = Math.min(minorRN, minorRNMac);
|
||||
return `^${major}.${minor}.0-0`;
|
||||
}
|
||||
}
|
||||
errorOutOnUnsupportedVersionOfReactNative(rnVersion);
|
||||
}
|
||||
|
||||
function getMatchingReactNativeSemVerForReactNativeMacOSVersion(
|
||||
rnmacVersion: string,
|
||||
) {
|
||||
const validVersion = semver.valid(rnmacVersion);
|
||||
if (validVersion) {
|
||||
const major = semver.major(validVersion);
|
||||
const minor = semver.minor(validVersion);
|
||||
if (major === 0 && minor >= 60) {
|
||||
return `^${major}.${minor}`;
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
function getLatestMatchingVersion(
|
||||
pkg: string,
|
||||
versionSemVer: string,
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (semver.validRange(versionSemVer)) {
|
||||
// Ideally we'd be able to just use npm.packages.range(pkg, versionSemVer) here,
|
||||
// but alas it fails to give us the right result for react-native-macos@^0.60.0-microsoft.57
|
||||
// as it fails to return pre-release versions
|
||||
npm.packages.releases(
|
||||
pkg,
|
||||
(err: any, details: {[key: string]: object}) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else if (details) {
|
||||
const versions = Object.keys(details);
|
||||
if (versions.length > 0) {
|
||||
const candidates = versions
|
||||
.filter(v => semver.satisfies(v, versionSemVer))
|
||||
.sort(semver.rcompare);
|
||||
if (candidates && candidates.length > 0) {
|
||||
resolve(candidates[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
reject(
|
||||
new Error(`No matching version of ${pkg}@${versionSemVer} found`),
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// Assume that versionSemVer is actually a tag
|
||||
npm.packages.release(
|
||||
pkg,
|
||||
versionSemVer,
|
||||
(err: any, details: {version: string}[]) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else if (details && details.length > 0) {
|
||||
resolve(details[0].version);
|
||||
return;
|
||||
}
|
||||
reject(
|
||||
new Error(`No matching version of ${pkg}@${versionSemVer} found`),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function getLatestMatchingReactNativeMacOSVersion(
|
||||
versionSemVer: string,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const version = await getLatestMatchingVersion(
|
||||
'react-native-macos',
|
||||
versionSemVer,
|
||||
);
|
||||
return version;
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`Error: No version of react-native-macos@${versionSemVer} found`,
|
||||
);
|
||||
process.exit(EXITCODE_NO_MATCHING_RNMACOS);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if project is using Yarn (has `yarn.lock` in the tree)
|
||||
*/
|
||||
function isProjectUsingYarn(cwd: string) {
|
||||
return findUp.sync('yarn.lock', {cwd});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const name = getReactNativeAppName();
|
||||
let version = argv.version;
|
||||
|
||||
const reactNativeMacOSLatestVersion = await getLatestMatchingReactNativeMacOSVersion('latest');
|
||||
|
||||
if (!version) {
|
||||
const rnVersion = getReactNativeVersion();
|
||||
version = getDefaultReactNativeMacOSSemVerForReactNativeVersion(
|
||||
rnVersion,
|
||||
reactNativeMacOSLatestVersion
|
||||
);
|
||||
}
|
||||
|
||||
const reactNativeMacOSResolvedVersion = await getLatestMatchingReactNativeMacOSVersion(version);
|
||||
|
||||
if (!argv.version) {
|
||||
console.log(
|
||||
`Latest matching version of ${chalk.bold(
|
||||
'react-native-macos',
|
||||
)} for ${chalk.green('react-native')}@${chalk.cyan(
|
||||
getReactNativeVersion(),
|
||||
)} is ${chalk.green('react-native-macos')}@${chalk.cyan(
|
||||
reactNativeMacOSResolvedVersion,
|
||||
)}`,
|
||||
);
|
||||
|
||||
if (semver.prerelease(reactNativeMacOSResolvedVersion)) {
|
||||
console.warn(
|
||||
`
|
||||
${chalk.green('react-native-macos')}@${chalk.cyan(
|
||||
reactNativeMacOSResolvedVersion,
|
||||
)} is a ${chalk.yellow('pre-release')} version.
|
||||
The latest supported version is ${chalk.green(
|
||||
'react-native-macos',
|
||||
)}@${chalk.cyan(reactNativeMacOSLatestVersion)}.
|
||||
You can either downgrade your version of ${chalk.green(
|
||||
'react-native',
|
||||
)} to ${chalk.cyan(
|
||||
getMatchingReactNativeSemVerForReactNativeMacOSVersion(
|
||||
reactNativeMacOSLatestVersion,
|
||||
),
|
||||
)}, or continue with a ${chalk.yellow(
|
||||
'pre-release',
|
||||
)} version of ${chalk.bold('react-native-macos')}.
|
||||
`,
|
||||
);
|
||||
|
||||
if (!argv.prerelease) {
|
||||
const confirm = (await prompts({
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: `Do you wish to continue with ${chalk.green(
|
||||
'react-native-macos',
|
||||
)}@${chalk.cyan(reactNativeMacOSResolvedVersion)}?`,
|
||||
})).confirm;
|
||||
|
||||
if (!confirm) {
|
||||
process.exit(EXITCODE_USER_CANCEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pkgmgr = isProjectUsingYarn(process.cwd())
|
||||
? 'yarn add'
|
||||
: 'npm install --save';
|
||||
|
||||
const execOptions = argv.verbose ? {stdio: 'inherit' as 'inherit'} : {};
|
||||
console.log(
|
||||
`Installing ${chalk.green('react-native-macos')}@${chalk.cyan(
|
||||
version,
|
||||
)}...`,
|
||||
);
|
||||
execSync(`${pkgmgr} "react-native-macos@${version}"`, execOptions);
|
||||
console.log(
|
||||
chalk.green(`react-native-macos@${version} successfully installed.`),
|
||||
);
|
||||
|
||||
const generateMacOS = require(reactNativeMacOSGeneratePath());
|
||||
generateMacOS(process.cwd(), name, {
|
||||
overwrite: argv.overwrite,
|
||||
verbose: argv.verbose,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(chalk.red(error.message));
|
||||
console.error(error);
|
||||
process.exit(EXITCODE_UNKNOWN_ERROR);
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "es6",
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": true,
|
||||
"preserveConstEnums": true,
|
||||
"moduleResolution": "node",
|
||||
"noUnusedLocals": true,
|
||||
"skipLibCheck": true,
|
||||
"rootDirs": ["src"],
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче