- Add BGTask identifiers and background modes to iOS Info.plist - Fix permission method calls (checkPermissionStatus vs checkPermissions) - Implement Android-style permission checking pattern - Add "Request Permissions" action card with check-then-request flow - Fix simulator selection in build script (use device ID for reliability) - Add Podfile auto-fix to fix-capacitor-plugins.js - Update build documentation with unified script usage Fixes: - BGTask registration errors (Info.plist missing identifiers) - Permission method not found errors (checkPermissions -> checkPermissionStatus) - Simulator selection failures (now uses device ID) - Podfile incorrect pod name (TimesafariDailyNotificationPlugin -> DailyNotificationPlugin) The permission flow now matches Android: check status first, then show system dialog if needed. iOS system dialog appears automatically when requestNotificationPermissions() is called. Files changed: - test-apps/daily-notification-test/ios/App/App/Info.plist (new) - test-apps/daily-notification-test/src/lib/typed-plugin.ts - test-apps/daily-notification-test/src/views/HomeView.vue - test-apps/daily-notification-test/scripts/build.sh (new) - test-apps/daily-notification-test/scripts/fix-capacitor-plugins.js - test-apps/daily-notification-test/docs/BUILD_QUICK_REFERENCE.md - test-apps/daily-notification-test/README.md - test-apps/daily-notification-test/package.json - test-apps/daily-notification-test/package-lock.json
220 lines
7.7 KiB
JavaScript
Executable File
220 lines
7.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Post-sync script to fix Capacitor auto-generated files
|
||
*
|
||
* Fixes:
|
||
* 1. capacitor.plugins.json - Ensures DailyNotification plugin is registered
|
||
* 2. capacitor.settings.gradle - Verifies plugin path points to android/ (standard structure)
|
||
*
|
||
* This script should run automatically after 'npx cap sync android'
|
||
* to verify Capacitor's auto-generated files are correct.
|
||
*
|
||
* @author Matthew Raymer
|
||
*/
|
||
|
||
import fs from 'fs';
|
||
import path from 'path';
|
||
import { fileURLToPath } from 'url';
|
||
|
||
const __filename = fileURLToPath(import.meta.url);
|
||
const __dirname = path.dirname(__filename);
|
||
|
||
const PLUGINS_JSON_PATH = path.join(__dirname, '../android/app/src/main/assets/capacitor.plugins.json');
|
||
const SETTINGS_GRADLE_PATH = path.join(__dirname, '../android/capacitor.settings.gradle');
|
||
const PODFILE_PATH = path.join(__dirname, '../ios/App/Podfile');
|
||
|
||
const PLUGIN_ENTRY = {
|
||
name: "DailyNotification",
|
||
classpath: "com.timesafari.dailynotification.DailyNotificationPlugin"
|
||
};
|
||
|
||
/**
|
||
* Fix capacitor.plugins.json to ensure DailyNotification is registered
|
||
*/
|
||
function fixCapacitorPlugins() {
|
||
console.log('🔧 Fixing capacitor.plugins.json...');
|
||
|
||
try {
|
||
// Read current content
|
||
let plugins = [];
|
||
if (fs.existsSync(PLUGINS_JSON_PATH)) {
|
||
const content = fs.readFileSync(PLUGINS_JSON_PATH, 'utf8');
|
||
plugins = JSON.parse(content);
|
||
}
|
||
|
||
// Check if our plugin is already there
|
||
const hasPlugin = plugins.some(p => p.name === PLUGIN_ENTRY.name);
|
||
|
||
if (!hasPlugin) {
|
||
plugins.push(PLUGIN_ENTRY);
|
||
fs.writeFileSync(PLUGINS_JSON_PATH, JSON.stringify(plugins, null, 2));
|
||
console.log('✅ Added DailyNotification plugin to capacitor.plugins.json');
|
||
} else {
|
||
console.log('✅ DailyNotification plugin already exists in capacitor.plugins.json');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ Error fixing capacitor.plugins.json:', error.message);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Fix capacitor.settings.gradle to verify plugin path points to android/ (standard structure)
|
||
*/
|
||
function fixCapacitorSettingsGradle() {
|
||
console.log('🔧 Verifying capacitor.settings.gradle...');
|
||
|
||
if (!fs.existsSync(SETTINGS_GRADLE_PATH)) {
|
||
console.log('ℹ️ capacitor.settings.gradle not found (may not be a test-app)');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
let content = fs.readFileSync(SETTINGS_GRADLE_PATH, 'utf8');
|
||
const originalContent = content;
|
||
|
||
// Check if the path correctly points to android/ (standard structure)
|
||
const correctPath = "project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android')";
|
||
const oldPluginPath = "project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android/plugin')";
|
||
|
||
// Check if it's using the old android/plugin/ path (needs fixing)
|
||
if (content.includes('android/plugin')) {
|
||
console.log('⚠️ capacitor.settings.gradle uses old path (android/plugin/) - fixing to standard structure');
|
||
content = content.replace(
|
||
oldPluginPath,
|
||
`// Plugin uses standard Capacitor structure: android/ (not android/plugin/)
|
||
${correctPath}`
|
||
);
|
||
|
||
if (content !== originalContent) {
|
||
fs.writeFileSync(SETTINGS_GRADLE_PATH, content);
|
||
console.log('✅ Fixed plugin path in capacitor.settings.gradle (android/plugin -> android)');
|
||
}
|
||
} else if (content.includes(correctPath) || content.includes("android')")) {
|
||
console.log('✅ capacitor.settings.gradle has correct path (android/)');
|
||
} else {
|
||
console.log('ℹ️ capacitor.settings.gradle doesn\'t reference the plugin or uses a different structure');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ Error verifying capacitor.settings.gradle:', error.message);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Fix iOS Podfile to use correct plugin pod name and path
|
||
*/
|
||
function fixPodfile() {
|
||
console.log('🔧 Verifying iOS Podfile...');
|
||
|
||
if (!fs.existsSync(PODFILE_PATH)) {
|
||
console.log('ℹ️ Podfile not found (iOS platform may not be added yet)');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
let content = fs.readFileSync(PODFILE_PATH, 'utf8');
|
||
const originalContent = content;
|
||
|
||
// The correct pod reference should be:
|
||
// pod 'DailyNotificationPlugin', :path => '../../node_modules/@timesafari/daily-notification-plugin/ios'
|
||
const correctPodLine = "pod 'DailyNotificationPlugin', :path => '../../node_modules/@timesafari/daily-notification-plugin/ios'";
|
||
|
||
// Check if Podfile already has the correct reference
|
||
if (content.includes("pod 'DailyNotificationPlugin'")) {
|
||
// Check if path is correct
|
||
if (content.includes('@timesafari/daily-notification-plugin/ios')) {
|
||
console.log('✅ Podfile has correct DailyNotificationPlugin reference');
|
||
} else {
|
||
// Fix the path
|
||
console.log('⚠️ Podfile has DailyNotificationPlugin but wrong path - fixing...');
|
||
content = content.replace(
|
||
/pod ['"]DailyNotificationPlugin['"].*:path.*/,
|
||
correctPodLine
|
||
);
|
||
|
||
// Also fix if it's using the wrong name (TimesafariDailyNotificationPlugin)
|
||
content = content.replace(
|
||
/pod ['"]TimesafariDailyNotificationPlugin['"].*:path.*/,
|
||
correctPodLine
|
||
);
|
||
|
||
if (content !== originalContent) {
|
||
fs.writeFileSync(PODFILE_PATH, content);
|
||
console.log('✅ Fixed DailyNotificationPlugin path in Podfile');
|
||
}
|
||
}
|
||
} else if (content.includes("TimesafariDailyNotificationPlugin")) {
|
||
// Fix wrong pod name
|
||
console.log('⚠️ Podfile uses wrong pod name (TimesafariDailyNotificationPlugin) - fixing...');
|
||
content = content.replace(
|
||
/pod ['"]TimesafariDailyNotificationPlugin['"].*:path.*/,
|
||
correctPodLine
|
||
);
|
||
|
||
if (content !== originalContent) {
|
||
fs.writeFileSync(PODFILE_PATH, content);
|
||
console.log('✅ Fixed pod name in Podfile (TimesafariDailyNotificationPlugin -> DailyNotificationPlugin)');
|
||
}
|
||
} else {
|
||
// Add the pod reference if it's missing
|
||
console.log('⚠️ Podfile missing DailyNotificationPlugin - adding...');
|
||
|
||
// Find the capacitor_pods function or target section
|
||
if (content.includes('def capacitor_pods')) {
|
||
// Add after capacitor_pods function
|
||
content = content.replace(
|
||
/(def capacitor_pods[\s\S]*?end)/,
|
||
`$1\n\n # Daily Notification Plugin\n ${correctPodLine}`
|
||
);
|
||
} else if (content.includes("target 'App'")) {
|
||
// Add in target section
|
||
content = content.replace(
|
||
/(target 'App' do)/,
|
||
`$1\n ${correctPodLine}`
|
||
);
|
||
} else {
|
||
// Add at end before post_install
|
||
content = content.replace(
|
||
/(post_install)/,
|
||
`${correctPodLine}\n\n$1`
|
||
);
|
||
}
|
||
|
||
if (content !== originalContent) {
|
||
fs.writeFileSync(PODFILE_PATH, content);
|
||
console.log('✅ Added DailyNotificationPlugin to Podfile');
|
||
}
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ Error fixing Podfile:', error.message);
|
||
// Don't exit - iOS might not be set up yet
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Run all fixes
|
||
*/
|
||
function fixAll() {
|
||
console.log('🔧 DailyNotification Plugin - Post-Sync Fix Script');
|
||
console.log('================================================\n');
|
||
|
||
fixCapacitorPlugins();
|
||
fixCapacitorSettingsGradle();
|
||
fixPodfile();
|
||
|
||
console.log('\n✅ All fixes applied successfully!');
|
||
console.log('💡 These fixes will persist until the next "npx cap sync"');
|
||
}
|
||
|
||
// Run if called directly
|
||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||
fixAll();
|
||
}
|
||
|
||
export { fixCapacitorPlugins, fixCapacitorSettingsGradle, fixPodfile, fixAll };
|