Fixed critical compilation errors preventing iOS plugin build: - Updated logger API calls from logger.debug(TAG, msg) to logger.log(.debug, msg) across all iOS plugin files to match DailyNotificationLogger interface - Fixed async/await concurrency in makeConditionalRequest using semaphore pattern - Fixed NotificationContent immutability by creating new instances instead of mutation - Changed private access control to internal for extension-accessible methods - Added iOS 15.0+ availability checks for interruptionLevel property - Fixed static member references using Self.MEMBER_NAME syntax - Added missing .scheduling case to exhaustive switch statement - Fixed variable initialization in retry state closures Added DailyNotificationStorage.swift implementation matching Android pattern. Updated build scripts with improved error reporting and full log visibility. iOS plugin now compiles successfully. All build errors resolved.
186 lines
6.0 KiB
Markdown
186 lines
6.0 KiB
Markdown
# iOS Native Interface Structure
|
|
|
|
**Author**: Matthew Raymer
|
|
**Date**: November 4, 2025
|
|
|
|
## Overview
|
|
|
|
The iOS native interface mirrors the Android structure, providing the same functionality through iOS-specific implementations.
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
ios/App/App/
|
|
├── AppDelegate.swift # Application lifecycle (equivalent to PluginApplication.java)
|
|
├── ViewController.swift # Main view controller (equivalent to MainActivity.java)
|
|
├── SceneDelegate.swift # Scene-based lifecycle (iOS 13+)
|
|
├── Info.plist # App configuration (equivalent to AndroidManifest.xml)
|
|
├── capacitor.config.json # Capacitor configuration
|
|
├── config.xml # Cordova compatibility
|
|
└── public/ # Web assets (equivalent to assets/public/)
|
|
├── index.html
|
|
├── capacitor.js
|
|
└── capacitor_plugins.js
|
|
```
|
|
|
|
## File Descriptions
|
|
|
|
### AppDelegate.swift
|
|
|
|
**Purpose**: Application lifecycle management
|
|
**Equivalent**: `PluginApplication.java` on Android
|
|
|
|
- Handles app lifecycle events (launch, background, foreground, termination)
|
|
- Registers for push notifications
|
|
- Handles URL schemes and universal links
|
|
- Initializes plugin demo fetcher (equivalent to Android's `PluginApplication.onCreate()`)
|
|
|
|
**Key Methods**:
|
|
- `application(_:didFinishLaunchingWithOptions:)` - App initialization
|
|
- `applicationDidEnterBackground(_:)` - Background handling
|
|
- `applicationWillEnterForeground(_:)` - Foreground handling
|
|
- `application(_:didRegisterForRemoteNotificationsWithDeviceToken:)` - Push notification registration
|
|
|
|
### ViewController.swift
|
|
|
|
**Purpose**: Main view controller extending Capacitor's bridge
|
|
**Equivalent**: `MainActivity.java` on Android
|
|
|
|
- Extends `CAPBridgeViewController` (Capacitor's bridge view controller)
|
|
- Initializes plugin and registers native fetcher
|
|
- Handles view lifecycle events
|
|
|
|
**Key Methods**:
|
|
- `viewDidLoad()` - View initialization
|
|
- `initializePlugin()` - Plugin registration (equivalent to Android's plugin registration)
|
|
|
|
### SceneDelegate.swift
|
|
|
|
**Purpose**: Scene-based lifecycle management (iOS 13+)
|
|
**Equivalent**: None on Android (iOS-specific)
|
|
|
|
- Handles scene creation and lifecycle
|
|
- Manages window and view controller setup
|
|
- Required for modern iOS apps using scene-based architecture
|
|
|
|
### Info.plist
|
|
|
|
**Purpose**: App configuration and permissions
|
|
**Equivalent**: `AndroidManifest.xml` on Android
|
|
|
|
**Key Entries**:
|
|
- `CFBundleIdentifier` - App bundle ID
|
|
- `NSUserNotificationsUsageDescription` - Notification permission description
|
|
- `UIBackgroundModes` - Background modes (fetch, processing, remote-notification)
|
|
- `BGTaskSchedulerPermittedIdentifiers` - Background task identifiers
|
|
- `UIApplicationSceneManifest` - Scene configuration
|
|
|
|
## Comparison: Android vs iOS
|
|
|
|
| Component | Android | iOS |
|
|
|-----------|---------|-----|
|
|
| **Application Class** | `PluginApplication.java` | `AppDelegate.swift` |
|
|
| **Main Activity** | `MainActivity.java` | `ViewController.swift` |
|
|
| **Config File** | `AndroidManifest.xml` | `Info.plist` |
|
|
| **Web Assets** | `assets/public/` | `public/` |
|
|
| **Lifecycle** | `onCreate()`, `onResume()`, etc. | `viewDidLoad()`, `viewWillAppear()`, etc. |
|
|
| **Bridge** | `BridgeActivity` | `CAPBridgeViewController` |
|
|
|
|
## Plugin Registration
|
|
|
|
### Android
|
|
|
|
```java
|
|
public class PluginApplication extends Application {
|
|
@Override
|
|
public void onCreate() {
|
|
super.onCreate();
|
|
NativeNotificationContentFetcher demoFetcher = new DemoNativeFetcher();
|
|
DailyNotificationPlugin.setNativeFetcher(demoFetcher);
|
|
}
|
|
}
|
|
```
|
|
|
|
### iOS
|
|
|
|
```swift
|
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
func application(_ application: UIApplication,
|
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
// Plugin registration happens in ViewController after Capacitor bridge is initialized
|
|
return true
|
|
}
|
|
}
|
|
|
|
class ViewController: CAPBridgeViewController {
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
initializePlugin()
|
|
}
|
|
|
|
private func initializePlugin() {
|
|
// Register demo native fetcher if implementing SPI
|
|
// DailyNotificationPlugin.setNativeFetcher(DemoNativeFetcher())
|
|
}
|
|
}
|
|
```
|
|
|
|
## Build Process
|
|
|
|
1. **Swift Compilation**: Compiles `AppDelegate.swift`, `ViewController.swift`, `SceneDelegate.swift`
|
|
2. **Capacitor Integration**: Links with Capacitor framework and plugin
|
|
3. **Web Assets**: Copies `public/` directory to app bundle
|
|
4. **Info.plist**: Processes app configuration and permissions
|
|
5. **App Bundle**: Creates `.app` bundle for installation
|
|
|
|
## Permissions
|
|
|
|
### Android (AndroidManifest.xml)
|
|
|
|
```xml
|
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
```
|
|
|
|
### iOS (Info.plist)
|
|
|
|
```xml
|
|
<key>NSUserNotificationsUsageDescription</key>
|
|
<string>This app uses notifications to deliver daily updates and reminders.</string>
|
|
|
|
<key>UIBackgroundModes</key>
|
|
<array>
|
|
<string>background-fetch</string>
|
|
<string>background-processing</string>
|
|
<string>remote-notification</string>
|
|
</array>
|
|
```
|
|
|
|
## Background Tasks
|
|
|
|
### Android
|
|
|
|
- Uses `WorkManager` and `AlarmManager`
|
|
- Declared in `AndroidManifest.xml` receivers
|
|
|
|
### iOS
|
|
|
|
- Uses `BGTaskScheduler` and `UNUserNotificationCenter`
|
|
- Declared in `Info.plist` with `BGTaskSchedulerPermittedIdentifiers`
|
|
|
|
## Next Steps
|
|
|
|
1. Ensure Xcode project includes these Swift files
|
|
2. Configure build settings in Xcode project
|
|
3. Add app icons and launch screen
|
|
4. Test plugin registration and native fetcher
|
|
5. Verify background tasks work correctly
|
|
|
|
## References
|
|
|
|
- [Capacitor iOS Documentation](https://capacitorjs.com/docs/ios)
|
|
- [iOS App Lifecycle](https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle)
|
|
- [Background Tasks](https://developer.apple.com/documentation/backgroundtasks)
|
|
|