dpogue commented on code in PR #1421:
URL: https://github.com/apache/cordova-docs/pull/1421#discussion_r2186028046


##########
www/docs/en/dev/guide/platforms/ios/plugin.md:
##########
@@ -159,84 +205,130 @@ specification to the local platform's `config.xml` file:
             <param name="ios-package" value="Echo" />
         </feature>
     </config-file>
+
+    <!-- If your plugin uses Swift -->
+    <source-file src="src/ios/Echo.swift" />
+
+    <!-- If your plugin uses Objective-C -->
+    <!-- <header-file src="src/ios/Echo.h" /> -->
+    <!-- <source-file src="src/ios/Echo.m" /> -->
 </platform>
 ```
 
+Specify the plugin's `<feature>` tag ensures that the necessary configuration 
is automatically injected into the Cordova-iOS project, as described in the 
[Plugin Development Guide][plugin-dev].
 
-Then we would add the following `Echo.h` and `Echo.m` files to the
-`Plugins` folder within the Cordova-iOS application directory:
+Lets break down what each element and attribute means.
 
+- `<feature>`
+    - The `name` attribute should match with the `service` parameter' value 
that is used in the JavaScript `cordova.exec` method call.
+- `<param>`
+    - The `value` attribute should match the name of the plugin'sObjective-C 
or Swift class name.
+    - The `name` attribute should always have the value of `ios-package` for 
iOS plugins.
 
-```objective_c
-/********* Echo.h Cordova Plugin Header *******/
+If the follow guidelines are not met, the plugin may compile but Cordova will 
not be able to access it.
 
-#import <Cordova/CDVPlugin.h>
+**IMPORTANT NOTE:** During the platform preparation for building the app, an 
auto-generated merged `config.xml` file is created. This file contains all 
platform-specific application configurations and plugin data gathered from the 
application's `config.xml` and the plugin's `plugin.xml`. The `config-file` 
block, as shown in the example above, ensures that the plugin's feature is 
injected into the merged `config.xml`, allowing the plugin to function 
properly. This `config.xml` is separate from the application's root 
`config.xml`.
 
-@interface Echo : CDVPlugin
+#### Configuring Plugin Initialization Timing
 
-- (void)echo:(CDVInvokedUrlCommand*)command;
+A single instance of a plugin object is typically created for the lifecycle of 
each `WKWebView`, though the instantiation timing depends on the plugin's 
implementation.
 
-@end
+By default, plugins are instantiated when they are first referenced by a call 
from JavaScript. However, plugins can be configured to instantiate when the app 
loads by defining the `onload` attribute within a `<param>` element in the 
plugin's `plugin.xml` configuration file. This `<param>` should be added to the 
plugin's `<feature>` element.
 
-/********* Echo.m Cordova Plugin Implementation *******/
+For example:
 
-#import "Echo.h"
-#import <Cordova/CDVPlugin.h>
+```xml
+<feature name="Echo">
+    <param name="ios-package" value="Echo" />
+    <param name="onload" value="true" /> <!-- Initialize plugin on app load -->
+</feature>
+```
 
-@implementation Echo
+### Supporting Swift Package Manager (SPM)
+
+Starting from Cordova-iOS 8 and greater, support for the Swift Package Manager 
(SPM) has been implemented. To start using SPM with your plugin, a 
`Package.swift` file will need to be created in the plugin's root directory and 
a couple of things needs to be set and made aware in the `plugin.xml`.
+
+#### Creating SPM's `Package.swift` File
+
+In the plugin's root directory, create a new file called `Package.swift` with 
the following content:
+
+```swift
+// swift-tools-version:5.5
+
+import PackageDescription
+
+let package = Package(
+    name: "cordova-plugin-echo",
+    platforms: [.iOS(.v13)],
+    products: [
+        .library(name: "cordova-plugin-echo", targets: ["cordova-plugin-echo"])
+    ],
+    dependencies: [
+        // This must be included as a dependency, with this format for it to 
work.
+        .package(url: "https://github.com/apache/cordova-ios.git";, branch: 
"master")
+    ],
+    targets: [
+        .target(
+            name: "cordova-plugin-echo",
+            dependencies: [
+                .product(name: "Cordova", package: "cordova-ios")
+            ],
+            path: "src/ios",
+            resources: [],
+            publicHeadersPath: "."
+        )
+    ]
+)
+```
 
-- (void)echo:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* pluginResult = nil;
-    NSString* echo = [command.arguments objectAtIndex:0];
+If the plugin is required to provide a privacy manifest file, the following 
line should be added to the `resources` element of the `cordova-plugin-echo` 
target: `.copy("Resources/PrivacyInfo.xcprivacy")`.
+On top of the SPM declaration, be sure to also refer to the section titled 
[Adding a Privacy Manifest File](#adding-a-privacy-manifest-file) to ensure 
that the actual resource file is properly declared in the `plugin.xml` so it is 
correctly injected into the app.
+
+If the plugin requires for any third-party dependencies, it should be added to 
the `dependencies` element, and the `target`'s `dependencies`.
+
+For example:
+
+```swift
+dependencies: [
+    ...
+    .package(name: "SomePackageName", url: "...", from: "1.0.0"),
+],
+targets: [
+    .target(
+        ...
+        dependencies: [
+            .product(name: "Cordova", package: "cordova-ios"),
+            .product(name: "SomePackageLibraryName", package: 
"SomePackageName")
+        ],
+    )
+]
+```
 
-    if (echo != nil && [echo length] > 0) {
-        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK 
messageAsString:echo];
-    } else {
-        pluginResult = [CDVPluginResult 
resultWithStatus:CDVCommandStatus_ERROR];
-    }
+### Additional Native Side Implementation
 
-    [self.commandDelegate sendPluginResult:pluginResult 
callbackId:command.callbackId];
-}
+#### Executing Plugin Initialization Logic
 
-@end
-```
+If the plugin has any logic that should execute on the during the plugin's 
initialization process, the `pluginInitialize` method should be defined in the 
plugin's class.
 
-The necessary imports at the top of the file extends the class from
-`CDVPlugin`.  In this case, the plugin only supports a single `echo`
-action. It obtains the echo string by calling the `objectAtIndex`
-method get the first parameter of the `arguments` array, which
-corresponds to the arguments passed in by the JavaScript `exec()`
-function.
+For example, if the plugin has defined `onload` as `true`, when the app loads, 
the `pluginInitialize` method will be executed. Because this is triggered 
during app load, there is no `callbackID` so the `pluginInitialize` method can 
not return any results to the WebView. If results matter, they would need to be 
stored in some manar and later fetched with a JavaScript API call.
 
-It checks the parameter to make sure it is not `nil` or an empty
-string, returning a `PluginResult` with an `ERROR` status if so.  If
-the parameter passes the check, it returns a `PluginResult` with an
-`OK` status, passing in the original `echo` string.  Finally, it sends
-the result to `self.commandDelegate`, which executes the `exec`
-method's success or failure callbacks on the JavaScript side. If the
-success callback is called, it passes in the `echo` parameter.
+#### Handeling Long-running & Background Activities
 
-## iOS Integration
+Plugins with long-running requests or background activities, such as media 
playback, listeners, or those that maintain internal state, should implement 
the `onReset` method to cancel these requests or clean up after those 
activities.
 
-The `CDVPlugin` class features other methods that your plugin can
-override.  For example, you can capture the [pause][PauseEvent], 
[resume][ResumeEvent], app
-terminate and `handleOpenURL` events. See the
-[CDVPlugin.h][CDVPlugin.h] and [CDVPlugin.m][CDVPlugin.m]
-classes for guidance.
+The `onReset` method is called when the `WKWebView` navigates to a new page or 
refreshes, triggering a reload of the JavaScript.
 
-### WKURLSchemeTask Hook
+#### Hooking into WKURLSchemeTask
 
-The 
[WKURLSchemeTask](https://developer.apple.com/documentation/webkit/wkurlschemetask)
 is an interface Cordova's main WKWebView uses to load files from your app's 
bundle. You can create your own custom schemes or custom loading code for the 
webview by implementing the `- (BOOL) overrideSchemeTask: (id 
<WKURLSchemeTask>)urlSchemeTask` method in a plugin.
+The 
[WKURLSchemeTask](https://developer.apple.com/documentation/webkit/wkurlschemetask)
 is an interface Cordova's main WKWebView uses to load files from your app's 
bundle. You can create your own custom schemes or custom loading code for the 
WebView by implementing the `- (BOOL) overrideSchemeTask: (id 
<WKURLSchemeTask>)urlSchemeTask` method in a plugin.
 
-## Threading
+#### Using Background Threads
 
-Plugin methods ordinarily execute in the same thread as the main
-interface. If your plugin requires a great deal of processing or
-requires a blocking call, you should use a background thread. For
-example:
+Plugin methods ordinarily execute in the same thread as the main interface. If 
your plugin requires a great deal of processing or requires a blocking call, 
you should use a background thread.

Review Comment:
   Worth mentioning that certain operations involving UI stuff (showing alerts, 
changing colours, etc.) can only run on the main thread



##########
www/docs/en/dev/guide/platforms/ios/plugin.md:
##########
@@ -250,19 +342,117 @@ example:
 }
 ```
 
-## Debugging iOS Plugins
+#### Adding a Privacy Manifest File
+
+As of May 1, 2024, Apple requires a privacy manifest file to be created for 
apps and third-party SDKs. The purpose of the privacy manifest file is to 
explain the data being collected and the reasons for the required APIs it uses.
+
+Plugins can include a pre-bundled `PrivacyInfo.xcprivacy` file that lists any 
privacy-sensitive APIs they use, along with the reasons for their usage.
+
+It is recommended to review the following Apple Developer document, 
"[Describing data use in privacy 
manifests](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests)",
 to understand the list of known `NSPrivacyCollectedDataTypes` and 
`NSPrivacyCollectedDataTypePurposes`.
+
+Ensure all four keys—`NSPrivacyTracking`, `NSPrivacyTrackingDomains`, 
`NSPrivacyAccessedAPITypes`, and `NSPrivacyCollectedDataTypes`—are defined, 
even if you are not making an addition to the other items. Apple requires all 
to be defined.
+
+Once you've identified what the contents of the `PrivacyInfo.xcprivacy` will 
look like, lets start creating the bundle and loading it as a resource.
+
+1. Create a directory named `CDVEcho.bundle` inside the `src/ios` directory. 
Make sure the bundle name is unique enough to avoid conflicts with other 
plugins.
+
+2. Inside the new `CDVEcho.bundle` directory, create a privacy manifest file 
named `PrivacyInfo.xcprivacy`.
+
+3. Add the contents you've identified for this file. Here's an example:
+
+   ```xml
+   <!-- Example PrivacyInfo.xcprivacy Contents -->
+   <?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>NSPrivacyTracking</key>
+       <false/>
+       <key>NSPrivacyTrackingDomains</key>
+       <array/>
+       <key>NSPrivacyAccessedAPITypes</key>
+       <array/>
+       <key>NSPrivacyCollectedDataTypes</key>
+       <array/>
+   </dict>
+   </plist>
+   ```
+
+4. Update your `plugin.xml` to load the `CDVEcho.bundle` into the app's 
resources.
+
+   Inside the iOS `<platform>` element, add a `<resource-file>` element 
pointing to the `CDVEcho.bundle` directory:
+
+   ```xml
+   <platform name="ios">
+       <resource-file src="src/ios/CDVEcho.bundle" target="CDVEcho.bundle" />
+   </platform>
+   ```
+
+5. **Optional:** If your plugin supports Swift Package Manager, refer to the 
section [Creating SPM's `Package.swift` File](#creating-spms-packageswift-file) 
to ensure the privacy manifest is also included as a resource file.
+
+## CDVPluginResult Message Types
+
+You can use `CDVPluginResult` to return a variety of result types back to the 
JavaScript callbacks, using class methods that follow this pattern:

Review Comment:
   Would be nice to link to 
https://apache.github.io/cordova-ios/documentation/cordova/cdvpluginresult 
around here
   
   (and then also improve the comments in the ObjC code so that documentation 
is more useful)



##########
www/docs/en/dev/guide/platforms/ios/plugin.md:
##########
@@ -250,19 +342,117 @@ example:
 }
 ```
 
-## Debugging iOS Plugins
+#### Adding a Privacy Manifest File
+
+As of May 1, 2024, Apple requires a privacy manifest file to be created for 
apps and third-party SDKs. The purpose of the privacy manifest file is to 
explain the data being collected and the reasons for the required APIs it uses.
+
+Plugins can include a pre-bundled `PrivacyInfo.xcprivacy` file that lists any 
privacy-sensitive APIs they use, along with the reasons for their usage.
+
+It is recommended to review the following Apple Developer document, 
"[Describing data use in privacy 
manifests](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests)",
 to understand the list of known `NSPrivacyCollectedDataTypes` and 
`NSPrivacyCollectedDataTypePurposes`.
+
+Ensure all four keys—`NSPrivacyTracking`, `NSPrivacyTrackingDomains`, 
`NSPrivacyAccessedAPITypes`, and `NSPrivacyCollectedDataTypes`—are defined, 
even if you are not making an addition to the other items. Apple requires all 
to be defined.
+
+Once you've identified what the contents of the `PrivacyInfo.xcprivacy` will 
look like, lets start creating the bundle and loading it as a resource.
+
+1. Create a directory named `CDVEcho.bundle` inside the `src/ios` directory. 
Make sure the bundle name is unique enough to avoid conflicts with other 
plugins.
+
+2. Inside the new `CDVEcho.bundle` directory, create a privacy manifest file 
named `PrivacyInfo.xcprivacy`.
+
+3. Add the contents you've identified for this file. Here's an example:
+
+   ```xml
+   <!-- Example PrivacyInfo.xcprivacy Contents -->
+   <?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>NSPrivacyTracking</key>
+       <false/>
+       <key>NSPrivacyTrackingDomains</key>
+       <array/>
+       <key>NSPrivacyAccessedAPITypes</key>
+       <array/>
+       <key>NSPrivacyCollectedDataTypes</key>
+       <array/>
+   </dict>
+   </plist>
+   ```
+
+4. Update your `plugin.xml` to load the `CDVEcho.bundle` into the app's 
resources.
+
+   Inside the iOS `<platform>` element, add a `<resource-file>` element 
pointing to the `CDVEcho.bundle` directory:
+
+   ```xml
+   <platform name="ios">
+       <resource-file src="src/ios/CDVEcho.bundle" target="CDVEcho.bundle" />
+   </platform>
+   ```
+
+5. **Optional:** If your plugin supports Swift Package Manager, refer to the 
section [Creating SPM's `Package.swift` File](#creating-spms-packageswift-file) 
to ensure the privacy manifest is also included as a resource file.
+
+## CDVPluginResult Message Types
+
+You can use `CDVPluginResult` to return a variety of result types back to the 
JavaScript callbacks, using class methods that follow this pattern:
+
+```objc
++ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal 
messageAs...
+```
+
+The following types can be used:
+
+- `String`
+- `Int`
+- `Double`
+- `Bool`
+- `Array`
+- `Dictionary`
+- `ArrayBuffer`
+- `Multipart`
+
+You can also leave out any arguments to send a status, or return an error, or 
even choose not to send any plugin result, in which case neither callback fires.
+
+Note the following for complex return values:
+
+- `messageAsArrayBuffer` expects `NSData*` and will convert it to an 
`ArrayBuffer` in the JavaScript callback. Likewise, any `ArrayBuffer` the 
JavaScript sends to a native side will be converted to `NSData*`.
+
+- `messageAsMultipart` expects an `NSArray*` containing any of the other 
supported types, and sends the entire array as the `arguments` to your 
JavaScript callback.  This way, all of the arguments are serialized or 
deserialized as necessary, so it is safe to return `NSData*` as multipart, but 
not as `Array`/`Dictionary`.
+
+## Other Supported `CDVPlugin` Features
+
+The `CDVPlugin` class features other methods that a plugin can override.
+
+For example, the plugin can capture:
+- [`pause`][PauseEvent] Event
+- [`resume`][ResumeEvent] Event
+- App Terminate Event
+- `handleOpenURL` events
+
+For additional reference, see the following classes:
+
+- [CDVPlugin.h][CDVPlugin.h]
+- [CDVPlugin.m][CDVPlugin.m]

Review Comment:
   Would be nice to link to 
https://apache.github.io/cordova-ios/documentation/cordova/cdvplugin here



##########
www/docs/en/dev/guide/platforms/ios/plugin.md:
##########
@@ -159,84 +205,130 @@ specification to the local platform's `config.xml` file:
             <param name="ios-package" value="Echo" />
         </feature>
     </config-file>
+
+    <!-- If your plugin uses Swift -->
+    <source-file src="src/ios/Echo.swift" />
+
+    <!-- If your plugin uses Objective-C -->
+    <!-- <header-file src="src/ios/Echo.h" /> -->
+    <!-- <source-file src="src/ios/Echo.m" /> -->
 </platform>
 ```
 
+Specify the plugin's `<feature>` tag ensures that the necessary configuration 
is automatically injected into the Cordova-iOS project, as described in the 
[Plugin Development Guide][plugin-dev].
 
-Then we would add the following `Echo.h` and `Echo.m` files to the
-`Plugins` folder within the Cordova-iOS application directory:
+Lets break down what each element and attribute means.
 
+- `<feature>`
+    - The `name` attribute should match with the `service` parameter' value 
that is used in the JavaScript `cordova.exec` method call.
+- `<param>`
+    - The `value` attribute should match the name of the plugin'sObjective-C 
or Swift class name.
+    - The `name` attribute should always have the value of `ios-package` for 
iOS plugins.
 
-```objective_c
-/********* Echo.h Cordova Plugin Header *******/
+If the follow guidelines are not met, the plugin may compile but Cordova will 
not be able to access it.
 
-#import <Cordova/CDVPlugin.h>
+**IMPORTANT NOTE:** During the platform preparation for building the app, an 
auto-generated merged `config.xml` file is created. This file contains all 
platform-specific application configurations and plugin data gathered from the 
application's `config.xml` and the plugin's `plugin.xml`. The `config-file` 
block, as shown in the example above, ensures that the plugin's feature is 
injected into the merged `config.xml`, allowing the plugin to function 
properly. This `config.xml` is separate from the application's root 
`config.xml`.
 
-@interface Echo : CDVPlugin
+#### Configuring Plugin Initialization Timing
 
-- (void)echo:(CDVInvokedUrlCommand*)command;
+A single instance of a plugin object is typically created for the lifecycle of 
each `WKWebView`, though the instantiation timing depends on the plugin's 
implementation.
 
-@end
+By default, plugins are instantiated when they are first referenced by a call 
from JavaScript. However, plugins can be configured to instantiate when the app 
loads by defining the `onload` attribute within a `<param>` element in the 
plugin's `plugin.xml` configuration file. This `<param>` should be added to the 
plugin's `<feature>` element.
 
-/********* Echo.m Cordova Plugin Implementation *******/
+For example:
 
-#import "Echo.h"
-#import <Cordova/CDVPlugin.h>
+```xml
+<feature name="Echo">
+    <param name="ios-package" value="Echo" />
+    <param name="onload" value="true" /> <!-- Initialize plugin on app load -->
+</feature>
+```
 
-@implementation Echo
+### Supporting Swift Package Manager (SPM)
+
+Starting from Cordova-iOS 8 and greater, support for the Swift Package Manager 
(SPM) has been implemented. To start using SPM with your plugin, a 
`Package.swift` file will need to be created in the plugin's root directory and 
a couple of things needs to be set and made aware in the `plugin.xml`.

Review Comment:
   Should mention in here the `package="swift"` attribute in plugin.xml



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to