Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions CHANGES_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Summary of Changes - IOSWatchAppService Enhancements

## Problem Statement

The user requested several enhancements to the IOSWatchAppService and watchapp.json handling:

1. Support for custom Info.plist path configuration
2. Support for glob pattern-based file exclusions for resources and source files
3. Support for custom xcprivacy file path configuration
4. Fix for Xcode build error: "Multiple commands produce"

## Solutions Implemented

### 1. Custom Info.plist Path Support

**File Modified:** `lib/services/ios-watch-app-service.ts`

**Changes:**
- Added `infoPlistPath` configuration option to watchapp.json
- The service now reads this path, copies the custom Info.plist to the target directory
- Automatically sets the `INFOPLIST_FILE` build setting to point to the custom file

**Code Location:** Lines 451-468 in configureTarget method

**Usage Example:**
```json
{
"infoPlistPath": "../custom-config/WatchApp-Info.plist"
}
```

### 2. Custom xcprivacy File Path Support

**File Modified:** `lib/services/ios-watch-app-service.ts`

**Changes:**
- Added `xcprivacyPath` configuration option to watchapp.json
- The service now reads this path, copies the custom Privacy Manifest file to the target directory
- Automatically adds the file as a resource to the watch app target

**Code Location:** Lines 470-487 in configureTarget method

**Usage Example:**
```json
{
"xcprivacyPath": "../custom-config/WatchApp-PrivacyInfo.xcprivacy"
}
```

### 3. Glob Pattern-Based File Exclusions

**File Modified:** `lib/services/ios-watch-app-service.ts`

**Changes:**
- Added `resourcesExclude` configuration option for excluding resource files
- Added `srcExclude` configuration option for excluding source files
- Implemented `shouldExclude` helper method using minimatch library for glob pattern matching
- Updated `addSourceFilesFromDirectory` and `addResourcesFromDirectory` to accept and use exclusion patterns

**Code Location:**
- Lines 501-503 in configureTarget method
- Lines 208-242 in addSourceFilesFromDirectory method
- Lines 279-322 in addResourcesFromDirectory method
- Lines 999-1009 shouldExclude helper method

**Usage Example:**
```json
{
"resourcesExclude": [
"**/Info.plist",
"**/PrivacyInfo.xcprivacy"
],
"srcExclude": [
"**/Debug/**",
"**/*.template.swift"
]
}
```

### 4. Fix for "Multiple Commands Produce" Build Error

**File Modified:** `lib/services/ios-watch-app-service.ts`

**Problem:** The error occurred because files were being added to the Xcode target multiple times:
1. First by `addTargetToProject` in ios-native-target-service.ts which automatically added all files
2. Again by `addWatchAppSourceFiles` and `addWatchAppResources` methods

**Solution:**
- Created new `addTargetWithoutFiles` method that creates the target structure without automatically adding files
- This method creates build phases and groups but with empty file lists
- Files are then explicitly added through the controlled source and resource scanning process
- This prevents duplicate file additions and resolves the build error

**Code Location:** Lines 159-215 in addTargetWithoutFiles method

## Additional Changes

### Import Statements

Added necessary imports:
- `IXcodeTargetBuildConfigurationProperty` from project definitions
- `Minimatch` from minimatch package for glob pattern matching

### Method Signature Updates

Updated the following methods to accept optional exclusion patterns:
- `addWatchAppSourceFiles` - Added `excludePatterns?: string[]` parameter
- `addWatchAppResources` - Added `excludePatterns?: string[]` parameter
- `addSourceFilesFromDirectory` - Added `excludePatterns?: string[]` parameter
- `addResourcesFromDirectory` - Added `excludePatterns?: string[]` parameter

## Documentation

Created comprehensive documentation file `WATCHAPP_CONFIG.md` that includes:
- Overview of watchapp.json configuration
- Detailed explanation of new configuration options
- Usage examples
- Complete configuration example
- Migration guide
- Troubleshooting section

## Testing

The changes compile successfully with no TypeScript errors. The build process completes without issues.

**Note:** Manual testing of the watch app functionality would require an actual NativeScript project with iOS watch app setup.

## Security Considerations

- File paths are validated using `this.$fs.exists()` before operations
- Files are copied rather than symlinked for security
- Glob patterns use the well-established `minimatch` library which is already a dependency

## Backward Compatibility

All changes are backward compatible:
- New configuration options are optional
- Default behavior unchanged if new options are not specified
- Existing watchapp.json configurations continue to work without modification

## Benefits

1. **Flexibility:** Developers can now use existing Info.plist and xcprivacy files
2. **Control:** Fine-grained control over which files to include/exclude
3. **Reliability:** Fixes the "Multiple commands produce" build error
4. **Maintainability:** Cleaner separation of concerns with explicit file management
158 changes: 158 additions & 0 deletions WATCHAPP_CONFIG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Watch App Configuration Guide

This document describes the configuration options available in `watchapp.json` and `extension.json` files for iOS Watch app development.

## Overview

The `watchapp.json` and `extension.json` files allow you to configure how the NativeScript CLI builds your iOS Watch app targets. These files should be placed in the respective watch app folders:

- `App_Resources/iOS/watchapp/<WatchAppFolder>/watchapp.json`
- `App_Resources/iOS/watchextension/<ExtensionFolder>/extension.json`

## New Configuration Options

### Custom Info.plist Path

You can now specify a custom `Info.plist` file path. The CLI will copy this file to the appropriate location for your watch app target.

```json
{
"infoPlistPath": "path/to/custom/Info.plist"
}
```

**Notes:**
- The path is relative to the `watchapp.json` file location
- The file will be copied to the target directory if it doesn't exist there
- The `INFOPLIST_FILE` build setting will be automatically configured

### Custom xcprivacy File Path

You can specify a custom Privacy Manifest (`PrivacyInfo.xcprivacy`) file path.

```json
{
"xcprivacyPath": "path/to/custom/PrivacyInfo.xcprivacy"
}
```

**Notes:**
- The path is relative to the `watchapp.json` file location
- The file will be copied to the target directory as `PrivacyInfo.xcprivacy`
- The file will be automatically added as a resource to the watch app target

### Excluding Files with Glob Patterns

You can now exclude files from being added to the watch app target using glob patterns.

#### Exclude Resources

```json
{
"resourcesExclude": [
"**/Info.plist",
"**/*.xcprivacy",
"**/unwanted-folder/**"
]
}
```

#### Exclude Source Files

```json
{
"srcExclude": [
"**/Debug/**",
"**/*.template.swift",
"**/old-code/**"
]
}
```

**Glob Pattern Examples:**
- `**/Info.plist` - Excludes all Info.plist files in any directory
- `*.xcprivacy` - Excludes all xcprivacy files in the current directory
- `Debug/**` - Excludes all files in the Debug directory and subdirectories
- `**/*.template.*` - Excludes all template files with any extension

## Complete Example

Here's a complete example of a `watchapp.json` configuration:

```json
{
"infoPlistPath": "../custom-config/WatchApp-Info.plist",
"xcprivacyPath": "../custom-config/WatchApp-PrivacyInfo.xcprivacy",
"resourcesExclude": [
"**/Info.plist",
"**/PrivacyInfo.xcprivacy",
"**/node_modules/**"
],
"srcExclude": [
"**/Debug/**",
"**/*.backup.swift"
],
"importSourcesFromWatchFolder": true,
"importResourcesFromWatchFolder": true,
"modules": [
{
"name": "DataModule",
"path": "../../frameworks/Data.xcframework",
"embed": true
}
],
"SPMPackages": [
{
"name": "SomePackage",
"repositoryURL": "https://github.com/example/package",
"version": "1.0.0",
"libs": ["SomeLib"]
}
]
}
```

## Build Error Fix

### "Multiple commands produce" Error

This update fixes the Xcode build error:
```
Multiple commands produce '.../ActivelookWatch.app/ActivelookWatch'
```

This error was caused by files being added to the target multiple times. The fix ensures that:
1. Watch app targets are created without automatically adding all files from the directory
2. Files are explicitly added through the source and resource scanning process
3. Exclusion patterns prevent duplicate additions

## Migration Guide

If you're migrating from an older version:

1. **Custom Info.plist**: If you manually configured `INFOPLIST_FILE`, you can now use the `infoPlistPath` option instead
2. **File Exclusions**: If you manually excluded files, you can now use `resourcesExclude` and `srcExclude` glob patterns
3. **Privacy Manifest**: If you manually added xcprivacy files, you can now use `xcprivacyPath` option

## Troubleshooting

### Files Not Being Excluded

Make sure your glob patterns are correct:
- Use `**/` to match any directory depth
- Use `*` to match any file name
- Paths are relative to the platform project root

### Custom Info.plist Not Found

The path should be relative to the location of `watchapp.json`. For example:
- If `watchapp.json` is at `App_Resources/iOS/watchapp/MyWatch/watchapp.json`
- And your Info.plist is at `App_Resources/iOS/watchapp/custom/Info.plist`
- Then use: `"infoPlistPath": "../custom/Info.plist"`

### xcprivacy File Not Added

Ensure:
- The path is correct and relative to `watchapp.json`
- The file has the `.xcprivacy` extension
- The file exists at the specified location
Loading