Files
daily-notification-plugin/BUILDING.md
Jose Olarte III d0155f0b22 docs(building): update BUILDING.md with iOS prerequisites and clean-build script
Updates BUILDING.md to reflect recent changes in build-native.sh, especially
the Xcode Command Line Tools prerequisite check and the clean-build script.

Problem:
- BUILDING.md didn't mention Xcode Command Line Tools prerequisite
  (recently added to build-native.sh)
- clean-build.sh script exists but wasn't documented
- iOS build troubleshooting lacked Command Line Tools guidance

Changes:
- Add Xcode Command Line Tools to Prerequisites section
  - Document installation command (xcode-select --install)
  - Include verification steps (xcode-select -p, xcodebuild -version)
  - Note that build script automatically checks for these tools
  - Explain that sqlite3 is part of Command Line Tools

- Document clean-build.sh script in Build Scripts section
  - Basic usage: ./scripts/clean-build.sh
  - All options: --all, --clean-gradle-cache, --clean-derived-data,
    --reinstall-node
  - Explain when to use clean builds

- Enhance iOS Native Build Process section
  - Add prerequisite note about Command Line Tools
  - Include troubleshooting commands for pod install issues
  - Reference prerequisites section for details

- Add comprehensive troubleshooting sections
  - Clean Build section at start of Troubleshooting
    - Recommends clean-build as first step for many issues
    - Lists when to use clean builds
  - iOS Build Issues section
    - Command Line Tools configuration errors
    - SQLite/linker issues and pkgx conflicts
    - CocoaPods installation problems
    - All with clear solutions and commands

The documentation now accurately reflects:
- Xcode Command Line Tools as required iOS prerequisite
- clean-build.sh as available build tool
- Complete iOS troubleshooting workflow

Files modified:
- BUILDING.md
2026-01-16 15:38:41 +08:00

36 KiB

Building the DailyNotification Plugin

Author: Matthew Raymer
Last Updated: 2025-10-21 09:03:53 UTC
Version: 1.0.0

Overview

This document provides comprehensive instructions for building the DailyNotification Capacitor plugin using various methods, including Android Studio, command line, and integration testing.

Table of Contents

Quick Start

For Plugin Development

# Build plugin source code
./scripts/build-native.sh --platform android

# Test in Capacitor app
cd /path/to/test-capacitor-app
npx cap sync android
npx cap run android

For Android Studio

# 1. Open Android Studio
# 2. File → Open → /path/to/daily-notification-plugin/android
# 3. Wait for Gradle sync
# 4. Build → Make Project (Ctrl+F9)

Prerequisites

Required Software

  • Android Studio (latest stable version) - for Android development
  • Java 11+ (for Kotlin compilation)
  • Android SDK with API level 21+
  • Xcode (latest stable version) - for iOS development (macOS only)
  • Xcode Command Line Tools - required for iOS builds (includes xcodebuild, sqlite3, etc.)
  • Node.js 16+ (for TypeScript compilation)
  • npm or yarn (for dependency management)

Required Tools

  • Gradle Wrapper (included in project)
  • Kotlin (configured in build.gradle)
  • TypeScript (for plugin interface)
  • CocoaPods - for iOS dependency management

iOS-Specific Prerequisites

Xcode Command Line Tools are required for iOS builds. The build script will verify these are installed:

# Install Xcode Command Line Tools (if not already installed)
xcode-select --install

Verification:

# Check if Command Line Tools are configured
xcode-select -p

# Verify xcodebuild is available
xcodebuild -version

# Verify sqlite3 is available (part of Command Line Tools)
sqlite3 --version

Note: The build script automatically checks for Command Line Tools and will fail with clear error messages if they're missing.

System Requirements

  • RAM: 4GB minimum, 8GB recommended
  • Storage: 2GB free space
  • OS: Windows 10+, macOS 10.14+, or Linux (iOS development requires macOS)

Build Methods

The project includes an automated build script that handles both TypeScript and native compilation:

# Build all platforms
./scripts/build-native.sh

# Build specific platform
./scripts/build-native.sh --platform android
./scripts/build-native.sh --platform ios

# Build with verbose output
./scripts/build-native.sh --verbose

What it does:

  1. Compiles TypeScript to JavaScript
  2. Bundles plugin code with Rollup
  3. Builds native Android/iOS code
  4. Handles plugin development project detection
  5. Provides helpful warnings and guidance

Method 2: Manual Command Line

TypeScript Compilation

# Clean previous builds
npm run clean

# Build TypeScript and bundle
npm run build

# Watch mode for development
npm run build:watch

Android Native Build

# Navigate to Android directory
cd android

# Build plugin library (recommended for plugin development)
./gradlew :plugin:assembleRelease

# Build test app (requires proper Capacitor integration)
./gradlew :app:assembleRelease

# Build all modules
./gradlew build

# Run tests
./gradlew test

iOS Native Build

# Navigate to iOS directory
cd ios

# Install CocoaPods dependencies
pod install

# Build using Xcode (command line)
xcodebuild -workspace DailyNotificationPlugin.xcworkspace -scheme DailyNotificationPlugin -configuration Release

Method 3: Android Studio

See Android Studio Setup for detailed instructions.

Android Studio Setup

Opening the Project

Important: Open the Correct Directory

# ✅ CORRECT: Open the android/ folder
File → Open → /path/to/daily-notification-plugin/android

# ❌ WRONG: Don't open the root project folder
# This will cause Gradle sync issues

Initial Configuration

1. Gradle Sync

  • Android Studio will prompt to sync Gradle
  • Click "Sync Now" or use the sync button in the toolbar
  • Wait for sync to complete (may take a few minutes)

2. SDK Configuration

File → Project Structure → SDK Location
- Android SDK: /path/to/Android/Sdk
- JDK Location: /path/to/jdk-11

3. Gradle Settings

File → Settings → Build → Gradle
- Use Gradle from: 'gradle-wrapper.properties' file
- Gradle JVM: Project SDK (Java 11)

4. Kotlin Configuration

File → Settings → Languages & Frameworks → Kotlin
- Target JVM version: 1.8
- Language version: 1.5

Building in Android Studio

Build Commands

# Build the project
Build → Make Project (Ctrl+F9)

# Clean and rebuild
Build → Clean Project
Build → Rebuild Project

# Generate signed APK/AAR
Build → Generate Signed Bundle / APK

Build Output

The built plugin AAR will be located at:

android/build/outputs/aar/android-release.aar

Project Structure in Android Studio

When opened correctly, you'll see:

android/
├── app/                           # Main Android test app
│   ├── build.gradle               # App build configuration
│   ├── src/main/java/             # MainActivity.java
│   ├── src/main/assets/           # Capacitor assets (HTML/JS)
│   └── build/outputs/apk/         # Built APK files
├── plugin/                        # Plugin library module
│   ├── build.gradle               # Plugin build configuration
│   ├── src/main/java/
│   │   └── com/timesafari/dailynotification/
│   │       ├── DailyNotificationPlugin.java
│   │       ├── DailyNotificationWorker.java
│   │       ├── DailyNotificationScheduler.java
│   │       └── ...
│   └── build/outputs/aar/
│       └── plugin-release.aar    # Built plugin AAR
├── build.gradle                  # Root build file
├── settings.gradle               # Project settings
├── gradle.properties             # Gradle properties
└── gradle/wrapper/               # Gradle wrapper files

Note: There's also a separate Vue 3 test app at test-apps/daily-notification-test/android/ with its own Android module.

Important Distinctions

Standard Capacitor Plugin Structure

The plugin now follows the standard Capacitor Android structure:

  • Plugin Code: android/src/main/java/...
  • Plugin Build: android/build.gradle
  • Test App: test-apps/android-test-app/app/ (separate from plugin)

This structure is compatible with Capacitor's auto-generated files and requires no path fixes.
Test plugin without host app (needs Capacitor runtime)

Command Line Building

TypeScript Build Process

1. Clean Previous Builds

npm run clean
# Removes: dist/, build/, out/

2. Compile TypeScript

npm run build
# Compiles: src/ → dist/
# Bundles: dist/plugin.js, dist/esm/index.js

3. Watch Mode (Development)

npm run build:watch
# Automatically rebuilds on file changes

Android Native Build Process

1. Navigate to Android Directory

cd android

2. Build Commands

# Build all variants
./gradlew build

# Build debug variant
./gradlew assembleDebug

# Build release variant
./gradlew assembleRelease

# Clean build
./gradlew clean build

# Run tests
./gradlew test

3. Build Outputs

# Plugin AAR files
android/build/outputs/aar/
├── android-debug.aar
└── android-release.aar

# Test results
android/build/reports/tests/test/index.html

iOS Native Build Process

Prerequisites: Ensure Xcode Command Line Tools are installed (see Prerequisites section). The build script will verify this automatically.

1. Navigate to iOS Directory

cd ios

2. Install Dependencies

pod install

Note: If you encounter issues with pod install, ensure Xcode Command Line Tools are properly configured:

xcode-select --install  # Install if missing
xcode-select -p          # Verify installation path

3. Build Commands

# Build using Xcode command line
xcodebuild -workspace DailyNotificationPlugin.xcworkspace \
           -scheme DailyNotificationPlugin \
           -configuration Release \
           -destination generic/platform=iOS

# Build for simulator
xcodebuild -workspace DailyNotificationPlugin.xcworkspace \
           -scheme DailyNotificationPlugin \
           -configuration Debug \
           -destination 'platform=iOS Simulator,name=iPhone 14'

Testing Strategies

Unit Testing

Android Unit Tests

# Run all tests
./gradlew test

# Run specific test class
./gradlew test --tests "DailyNotificationPluginTest"

# Run tests with coverage
./gradlew test jacocoTestReport

iOS Unit Tests

# Run tests using Xcode
xcodebuild test -workspace DailyNotificationPlugin.xcworkspace \
                -scheme DailyNotificationPlugin \
                -destination 'platform=iOS Simulator,name=iPhone 14'

Test Apps Within Project

Vue 3 Test Application

The project includes a comprehensive Vue 3 test app for interactive plugin testing:

# Navigate to Vue 3 test app
cd test-apps/daily-notification-test

# Install dependencies
npm install

# Build Vue 3 app
npm run build

# Add Capacitor platforms
npm install @capacitor/android @capacitor/ios

# Sync with Capacitor
npx cap sync android

# For iOS: Use the npm script (handles Podfile fixes automatically)
npm run cap:sync:ios
# This runs: cap copy ios + fix Podfile + pod install

# Run on Android device/emulator
npx cap run android

# Run on iOS device/simulator
npx cap run ios

iOS Setup (Vue 3 Test App)

The iOS setup requires additional steps to configure the plugin correctly:

1. Install Dependencies

cd test-apps/daily-notification-test
npm install

2. Build Vue App

npm run build

3. Add iOS Platform (if not already added)

npx cap add ios

4. Fix Podfile Configuration

Critical: Capacitor's npx cap sync ios regenerates the Podfile with incorrect plugin references (TimesafariDailyNotificationPlugin instead of DailyNotificationPlugin).

Solution: Use the npm script npm run cap:sync:ios which:

  1. Copies assets without running pod install (npx cap copy ios)
  2. Automatically fixes the Podfile
  3. Then runs pod install with the corrected Podfile
# Use the npm script (recommended)
npm run cap:sync:ios

# Or manually fix after copy
npx cap copy ios
node scripts/fix-capacitor-plugins.js
cd ios/App && pod install && cd ../..

The fix script will:

  • Change TimesafariDailyNotificationPluginDailyNotificationPlugin
  • Fix the path from '../../../..''../../node_modules/@timesafari/daily-notification-plugin/ios'

5. Install CocoaPods Dependencies

After the Podfile is fixed, install the iOS dependencies:

cd ios/App
pod install
cd ../..

Expected Podfile Configuration:

The Podfile should reference the plugin like this:

def capacitor_pods
  pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
  pod 'DailyNotificationPlugin', :path => '../../node_modules/@timesafari/daily-notification-plugin/ios'
end

Important Notes:

  • The pod name must be DailyNotificationPlugin (not TimesafariDailyNotificationPlugin)
  • The path must point to ../../node_modules/@timesafari/daily-notification-plugin/ios
  • The plugin must be installed in node_modules via npm install (it's installed as a local file dependency)

6. Sync and Build

Important: npx cap sync ios tries to run pod install automatically, but it will fail because the Podfile has incorrect plugin references. Use the npm script instead:

# Option 1: Use the npm script (recommended - handles everything)
npm run cap:sync:ios

# This script:
# 1. Copies web assets (npx cap copy ios)
# 2. Fixes the Podfile (node scripts/fix-capacitor-plugins.js)
# 3. Installs pods (cd ios/App && pod install)

# Option 2: Manual steps (if you need more control)
npx cap copy ios                    # Copy assets without pod install
node scripts/fix-capacitor-plugins.js  # Fix Podfile
cd ios/App && pod install && cd ../..  # Install pods

# Open in Xcode
npx cap open ios

Why this approach?

  • npx cap sync ios regenerates the Podfile with wrong references, then tries to run pod install which fails
  • npx cap copy ios only copies files, allowing us to fix the Podfile before pod install
  • The npm script automates the entire workflow correctly

Troubleshooting iOS Setup:

Error: [!] No podspec found for 'TimesafariDailyNotificationPlugin'

This means the Podfile has the wrong pod name or path. Solutions:

  1. Run the fix script:

    node scripts/fix-capacitor-plugins.js
    
  2. Manually fix the Podfile:

    • Open ios/App/Podfile
    • Change TimesafariDailyNotificationPlugin to DailyNotificationPlugin
    • Change path from '../../../..' to '../../node_modules/@timesafari/daily-notification-plugin/ios'
  3. Verify plugin is installed:

    ls -la node_modules/@timesafari/daily-notification-plugin/ios/DailyNotificationPlugin.podspec
    
  4. Reinstall dependencies if needed:

    rm -rf node_modules package-lock.json
    npm install
    

Error: pod install fails

  1. Update CocoaPods:

    sudo gem install cocoapods
    
  2. Clean CocoaPods cache:

    cd ios/App
    rm -rf Pods Podfile.lock
    pod install --repo-update
    
  3. Verify Xcode Command Line Tools:

    xcode-select --install
    

Test App Features:

  • Interactive plugin testing interface
  • Plugin diagnostics and status checking
  • Notification scheduling and management
  • Permission testing and management
  • Comprehensive logging and debugging

Test App Structure:

test-apps/daily-notification-test/
├── src/                    # Vue 3 source code
│   ├── views/              # Test interface views
│   ├── components/         # Reusable UI components
│   └── stores/             # Pinia state management
├── android/                # Android Capacitor app
├── ios/                    # iOS Capacitor app
│   └── App/
│       ├── Podfile         # CocoaPods dependencies
│       └── App.xcworkspace # Xcode workspace
├── docs/                   # Test app documentation
└── scripts/                # Test app build scripts
│   └── fix-capacitor-plugins.js  # Auto-fixes Podfile

Android Test Apps

The project includes two separate Android test applications:

1. Main Android Test App (test-apps/android-test-app/app)

A Capacitor-based Android test app with full plugin integration:

# Build main Android test app
cd test-apps/android-test-app
./gradlew :app:assembleDebug

# Install on device
adb install app/build/outputs/apk/debug/app-debug.apk

# Run tests
./gradlew :app:test

# Run in Android Studio
# File → Open → /path/to/daily-notification-plugin/test-apps/android-test-app
# Select 'app' module and run

Test App Structure:

test-apps/android-test-app/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── AndroidManifest.xml      # App manifest with permissions
│   │   │   ├── assets/                   # Capacitor web assets
│   │   │   │   ├── capacitor.config.json # Capacitor configuration
│   │   │   │   ├── capacitor.plugins.json # Plugin registry
│   │   │   │   └── public/               # Web app files
│   │   │   ├── java/
│   │   │   │   └── com/timesafari/dailynotification/
│   │   │   │       └── MainActivity.java # Capacitor BridgeActivity
│   │   │   └── res/                      # Android resources
│   │   ├── androidTest/                  # Instrumented tests
│   │   └── test/                         # Unit tests
│   ├── build.gradle                      # App build configuration
│   ├── capacitor.build.gradle            # Auto-generated Capacitor config
│   └── proguard-rules.pro               # Code obfuscation rules

Key Files Explained:

MainActivity.java - Entry point extending Capacitor's BridgeActivity:

public class MainActivity extends BridgeActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

AndroidManifest.xml - App permissions and configuration:

  • Notification permissions
  • Background execution permissions
  • Exact alarm permissions
  • Capacitor plugin declarations

assets/public/index.html - Main test interface:

  • Interactive plugin testing buttons
  • Plugin diagnostics and status checking
  • Notification scheduling interface
  • Permission management UI

capacitor.plugins.json - Plugin registry:

{
  "plugins": {
    "DailyNotification": {
      "class": "com.timesafari.dailynotification.DailyNotificationPlugin"
    }
  }
}

Build Process:

  1. Web Assets: Capacitor copies assets/public/ to APK
  2. Java Compilation: Compiles MainActivity.java and dependencies
  3. Resource Processing: Processes Android resources and assets
  4. APK Generation: Packages everything into installable APK
  5. Plugin Integration: Links with plugin from node_modules/@timesafari/daily-notification-plugin/android

Editing Guidelines:

  • HTML/JS: Edit assets/public/index.html for UI changes
  • Java: Edit src/main/java/ for native Android code
  • Resources: Edit src/main/res/ for icons, strings, layouts
  • Configuration: Edit AndroidManifest.xml for permissions
  • Build: Modify build.gradle for dependencies and build settings

Features:

  • Full Capacitor integration
  • Plugin testing interface (HTML/JS)
  • Native Android testing capabilities
  • Complete app lifecycle testing
2. Vue 3 Test App Android Module (/test-apps/daily-notification-test/android)

Android module within the Vue 3 test application:

# Build Vue 3 test app Android module
cd test-apps/daily-notification-test/android
./gradlew assembleDebug

# Install on device
adb install app/build/outputs/apk/debug/app-debug.apk

# Run tests
./gradlew test

Features:

  • Integrated with Vue 3 frontend
  • Plugin diagnostics and management
  • Interactive testing interface
  • Comprehensive logging and debugging

Plugin Integration Approach: The Vue 3 test app uses a project reference approach for plugin integration:

  1. Project Reference Configuration:

    // capacitor.settings.gradle
    include ':timesafari-daily-notification-plugin'
    project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android')
    
    // capacitor.build.gradle
    implementation project(':timesafari-daily-notification-plugin')
    
  2. Required Dependencies:

    // app/build.gradle
    implementation 'androidx.work:work-runtime:2.9.0'
    implementation 'androidx.lifecycle:lifecycle-service:2.7.0'
    implementation 'com.google.code.gson:gson:2.10.1'
    
  3. Plugin Discovery:

    // assets/capacitor.plugins.json
    [
      {
        "id": "DailyNotification",
        "name": "DailyNotification", 
        "class": "com.timesafari.dailynotification.DailyNotificationPlugin"
      }
    ]
    

Troubleshooting Integration Issues:

  • Duplicate Classes: Use project reference instead of AAR to avoid conflicts
  • Gradle Cache: Clear completely (rm -rf ~/.gradle) when switching approaches
  • Path Issues: Ensure correct project path (../../../android)
  • Dependencies: Include required WorkManager and Gson dependencies

Integration Testing

1. Create External Test Capacitor App

# Create new Capacitor app
npx @capacitor/create-app@latest TestApp
cd TestApp

# Install your plugin
npm install /path/to/daily-notification-plugin

# Add platforms
npx cap add android
npx cap add ios

# Sync with Capacitor
npx cap sync android
npx cap sync ios

2. Test in Android Studio

# Open test app in Android Studio
File → Open → TestApp/android

# Now you can:
# - Run the app
# - Test notifications
# - Debug full integration
# - Test background tasks

3. Test on Device

# Run on Android device
npx cap run android

# Run on iOS device
npx cap run ios

Manual Testing Checklist

Basic Functionality

  • Plugin loads without errors
  • DailyNotification.configure() works
  • Background fetching works
  • Notifications appear
  • Settings are persisted

Integration Testing

  • ActiveDid change handling
  • Settings synchronization
  • Request pattern matching
  • Error handling
  • Network failure recovery

Edge Cases

  • Network failures
  • ActiveDid changes during fetch
  • App backgrounding/foregrounding
  • Battery optimization settings
  • Low storage conditions

Build Scripts and Automation

Available Build Scripts

The project includes several automated build scripts in the scripts/ directory:

Core Build Scripts

# Main build script (handles TypeScript + native)
./scripts/build-native.sh --platform android
./scripts/build-native.sh --platform ios
./scripts/build-native.sh --verbose

# Clean build (removes all build artifacts and caches)
./scripts/clean-build.sh
./scripts/clean-build.sh --all  # Also cleans caches and reinstalls dependencies
./scripts/clean-build.sh --clean-gradle-cache  # Clean Gradle cache
./scripts/clean-build.sh --clean-derived-data  # Clean Xcode DerivedData
./scripts/clean-build.sh --reinstall-node  # Reinstall node_modules

# TimeSafari-specific builds
node scripts/build-timesafari.js

# Comprehensive testing
./scripts/comprehensive-test-v2.sh

# Capacitor build fixes
./scripts/fix-capacitor-build.sh

Setup and Configuration Scripts

# Gradle setup automation
./scripts/setup-gradle.sh

# Native environment setup
node scripts/setup-native.js

# Environment checking
node scripts/check-environment.js

Testing and Validation Scripts

# Chaos testing for reliability
node scripts/chaos-test.js

# API changes detection
node scripts/check-api-changes.js

# Bundle size monitoring
node scripts/check-bundle-size.js

# Daily notification testing
./scripts/daily-notification-test.sh
node scripts/daily-notification-test.py

Release and Deployment Scripts

# Release notes generation
node scripts/update-release-notes.js

# Type checksum generation
node scripts/generate-types-checksum.js

Deployment to External Projects

1. Publishing to npm Registry

# Build the plugin
npm run build

# Run tests
npm test

# Update version
npm version patch  # or minor, major

# Publish to npm
npm publish

# Verify publication
npm view @timesafari/daily-notification-plugin

2. Installing in External Capacitor Projects

# Install from npm
npm install @timesafari/daily-notification-plugin

# Install from local development
npm install /path/to/daily-notification-plugin

# Install from git repository
npm install git+https://github.com/timesafari/daily-notification-plugin.git

3. Integration in Host Applications

# Add to Capacitor project
npx cap add android
npx cap add ios

# Sync with Capacitor
npx cap sync android
npx cap sync ios

# Build and run
npx cap run android
npx cap run ios

4. Version Management

# Check current version
npm list @timesafari/daily-notification-plugin

# Update to latest version
npm update @timesafari/daily-notification-plugin

# Install specific version
npm install @timesafari/daily-notification-plugin@1.2.3

For Plugin Development

1. Edit Plugin Code

# Edit TypeScript interface
vim src/definitions.ts

# Edit Android native code
vim android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt

# Edit iOS native code
vim ios/Plugin/DailyNotificationPlugin.swift

2. Build and Test

# Build plugin
./scripts/build-native.sh --platform android

# Test in Capacitor app
cd /path/to/test-capacitor-app
npx cap sync android
npx cap run android

3. Iterate

# Make changes
# Build again
# Test again
# Repeat until working

For Production Testing

1. Test in TimeSafari PWA

# Install plugin in TimeSafari PWA
npm install @timesafari/daily-notification-plugin

# Sync with Capacitor
npx cap sync android
npx cap sync ios

# Test on real devices
npx cap run android
npx cap run ios

2. Monitor and Debug

# Check logs
adb logcat | grep DailyNotification

# Check plugin metrics
# Use observability dashboards

Troubleshooting

Clean Build (First Step for Many Issues)

If you encounter persistent build issues, try a clean build first:

# Clean all build artifacts (recommended first step)
./scripts/clean-build.sh

# Clean everything including caches (for stubborn issues)
./scripts/clean-build.sh --all

# Then rebuild
./scripts/build-native.sh --platform all

When to use clean-build:

  • Build errors that don't make sense
  • Dependency conflicts
  • Stale build artifacts
  • After switching branches
  • After updating dependencies

Common Issues

Gradle Sync Failures

# Problem: Gradle sync fails
# Solution: Check Java version
java -version  # Should be 11+

# Solution: Clear Gradle cache
./gradlew clean
rm -rf ~/.gradle/caches ~/.gradle/daemon

Build Failures

# Problem: Build fails with "Could not read script"
# Solution: This is a plugin development project
# The build script handles this automatically
./scripts/build-native.sh --platform android

# Problem: Build fails with "Could not resolve project :capacitor-cordova-android-plugins"
# Solution: Build the plugin module instead of the test app
./gradlew :plugin:assembleRelease

# Problem: Build fails with "Cannot locate tasks that match ':android:assembleRelease'"
# Solution: Use correct project name - available projects are:
# - :app (test app, may have Capacitor issues)
# - :plugin (plugin library, recommended)
# - :capacitor-android
# - :capacitor-cordova-android-plugins
./gradlew :plugin:assembleRelease

# Problem: Build fails with "Plugin with id 'kotlin-android' not found"
# Solution: The plugin module doesn't need Kotlin plugin for Java/Kotlin code
# Check the plugin/build.gradle file

Capacitor Integration Warnings

# ⚠️  WARNING: capacitor.build.gradle is auto-generated!
# Any manual fixes will be lost when running:
# - npx cap sync
# - npx cap update  
# - npx cap add android

# ⚠️  NOTE: npx cap sync will fail in plugin development projects!
# This is expected - plugin projects don't have www/ directory
# Error: "Could not find the web assets directory: ./www"
# This is normal for plugin development projects

# To fix after Capacitor operations:
./scripts/fix-capacitor-build.sh

# Or use the build script (applies fix automatically):
./scripts/build-native.sh --platform android

Capacitor Settings Path Fix (Test App)

Note: The plugin now uses standard Capacitor structure, so no path fixes are needed for consuming apps. The test app at test-apps/android-test-app/ references the plugin correctly.

Android Studio Issues

# Problem: Android Studio can't find SDK
# Solution: Configure SDK location
File → Project Structure → SDK Location

# Problem: Kotlin compilation errors
# Solution: Check Kotlin version in build.gradle

iOS Build Issues

# Problem: "Xcode Command Line Tools not configured"
# Error: xcode-select -p fails or xcodebuild not found
# Solution: Install Command Line Tools
xcode-select --install

# Verify installation
xcode-select -p
xcodebuild -version
sqlite3 --version

# Problem: "sqlite3 not found" or linker errors with SQLite
# Solution: Ensure Command Line Tools are properly installed
# The build script checks for this automatically, but if you see linker errors:
xcode-select --install

# Problem: pkgx SQLite conflicts with iOS builds
# Error: Linker errors about libsqlite3.dylib
# Solution: The build script automatically handles this by unsetting problematic
# environment variables. If issues persist:
unset PKGX_DIR DYLD_LIBRARY_PATH LD_LIBRARY_PATH
./scripts/build-native.sh --platform ios

# Problem: "pod install" fails
# Solution: Ensure Command Line Tools are installed
xcode-select --install
# Then reinstall CocoaPods dependencies
cd ios
pod deintegrate
pod install

Capacitor Integration Issues

# Problem: Plugin not found in Capacitor app
# Solution: Check plugin installation
npm list @timesafari/daily-notification-plugin

# Solution: Re-sync Capacitor
npx cap sync android

AAR Duplicate Class Issues

# Problem: Duplicate class errors when integrating plugin AAR
# Error: "Duplicate class com.timesafari.dailynotification.BootReceiver found in modules"
# Root Cause: Plugin being included both as project reference and as AAR file

# Solution 1: Use Project Reference Approach (Recommended)
# 1. Clear Gradle cache completely
./gradlew --stop
rm -rf ~/.gradle
rm -rf app/build
rm -rf build

# 2. Configure project reference in capacitor.settings.gradle
include ':timesafari-daily-notification-plugin'
project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin')

# 3. Add dependency in capacitor.build.gradle
implementation project(':timesafari-daily-notification-plugin')

# 4. Remove AAR dependency from app/build.gradle
# Comment out: implementation(name: 'plugin-debug', ext: 'aar')

# Solution 2: AAR-Only Approach (Alternative)
# 1. Remove project references from capacitor.settings.gradle and capacitor.build.gradle
# 2. Ensure only AAR dependency in app/build.gradle
# 3. Remove any duplicate classes.jar files from libs/ directory
# 4. Clear Gradle cache and rebuild

# Verification: Check that plugin is included only once
./gradlew :app:dependencies | grep timesafari

Debug Commands

Android Debugging

# View Android logs
adb logcat | grep DailyNotification

# Check plugin installation
adb shell pm list packages | grep timesafari

# Test background tasks
adb shell am start -n com.capacitorjs.app/.MainActivity

iOS Debugging

# View iOS logs
xcrun simctl spawn booted log stream --predicate 'subsystem contains "DailyNotification"'

# Check plugin installation
# Use Xcode Organizer or Device Manager

Performance Issues

Build Performance

# Enable Gradle daemon
echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties

# Increase memory
echo "org.gradle.jvmargs=-Xmx4g" >> ~/.gradle/gradle.properties

# Enable parallel builds
echo "org.gradle.parallel=true" >> ~/.gradle/gradle.properties

Android Studio Performance

# Increase Android Studio memory
# Help → Edit Custom VM Options
-Xmx4g
-XX:ReservedCodeCacheSize=1g

Project Structure

Root Directory

daily-notification-plugin/
├── android/                 # Android native code
├── ios/                     # iOS native code
├── src/                     # TypeScript plugin interface
├── dist/                    # Built plugin files
├── scripts/                 # Build scripts and automation
├── test-apps/               # Test applications
│   └── daily-notification-test/  # Vue 3 test app
├── docs/                    # Documentation
├── examples/                # Usage examples
├── tests/                   # Test files
├── package.json             # Node.js dependencies
├── tsconfig.json            # TypeScript configuration
├── rollup.config.js         # Bundler configuration
└── BUILDING.md              # This file

Android Structure

android/
├── src/main/java/       # Plugin source code
├── build.gradle         # Plugin build configuration
└── variables.gradle     # Gradle variables

iOS Structure

ios/
├── Plugin/                  # Swift plugin code
├── DailyNotificationPlugin.xcodeproj/  # Xcode project
├── DailyNotificationPlugin.xcworkspace/ # Xcode workspace
├── Podfile                  # CocoaPods dependencies
└── Tests/                   # iOS unit tests

Test Apps Structure

test-apps/
└── daily-notification-test/     # Vue 3 test application
    ├── src/                     # Vue 3 source code
    │   ├── views/               # Test interface views
    │   ├── components/          # Reusable UI components
    │   ├── stores/              # Pinia state management
    │   └── router/              # Vue Router configuration
    ├── android/                 # Android Capacitor app
    │   ├── app/                 # Android app module
    │   ├── dailynotification/   # Plugin module
    │   └── build.gradle         # Android build config
    ├── docs/                    # Test app documentation
    ├── scripts/                 # Test app build scripts
    ├── package.json             # Vue 3 dependencies
    └── vite.config.ts           # Vite build configuration

Scripts Structure

scripts/
├── build-native.sh              # Main build script
├── build-timesafari.js          # TimeSafari-specific builds
├── comprehensive-test-v2.sh     # Full test suite
├── fix-capacitor-build.sh       # Capacitor build fixes
├── setup-gradle.sh              # Gradle setup automation
├── setup-native.js              # Native environment setup
├── check-environment.js         # Environment validation
├── chaos-test.js                # Reliability testing
├── check-api-changes.js         # API change detection
├── check-bundle-size.js         # Bundle size monitoring
├── daily-notification-test.sh   # Notification testing
├── daily-notification-test.py   # Python test runner
├── update-release-notes.js     # Release notes generation
└── generate-types-checksum.js   # Type checksum generation

Best Practices

Code Organization

  • Keep plugin code modular and testable
  • Use consistent naming conventions
  • Document all public APIs
  • Follow platform-specific coding standards

Build Optimization

  • Use incremental builds when possible
  • Cache build artifacts
  • Parallelize builds where supported
  • Monitor build times and optimize

Testing Strategy

  • Write unit tests for all plugin logic
  • Test on real devices, not just simulators
  • Test edge cases and error conditions
  • Monitor performance and memory usage

Documentation

  • Keep BUILDING.md updated
  • Document all build requirements
  • Provide troubleshooting guides
  • Include examples and best practices

Support

Getting Help

Contributing

  • Follow the contributing guidelines
  • Test all changes thoroughly
  • Update documentation as needed
  • Submit pull requests with clear descriptions

Remember: This is a Capacitor plugin development project. For full functionality testing, use it in a Capacitor host application, not as a standalone Android/iOS app.