PWA to Native Conversion
This guide covers the integration with the PWA to iOS wrapper service for converting Progressive Web Apps into native iOS applications.
PWA Wrapping Workflow & API Documentation
Workflow Overview
The wrapping process is asynchronous and follows these steps:
- POST
/wrap– Start the wrapping process (returns immediately with a draft ID) - GET
/draft/{draft_id}– Poll for status updates until completion or failure - Download the build – When completed, download the
.zipfile fromdownload_url
Endpoints
1. Start Wrapping Process
POST /wrapper/wrap
/wrapper/wrapInitiates the PWA wrapping process. Returns immediately with a draft ID for tracking progress.
Request Body
{
"url": "https://example.com",
"bundle_id": "com.example.app",
"team_id": "A1B2C3D4E5",
"auth_redirects": {
"accounts.google.com": "https://example.com/auth/google/callback"
}
}Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| url | string (URL) | ✅ Yes | The PWA URL to wrap |
| bundle_id | string | ✅ Yes | iOS bundle identifier (com.company.app) |
| team_id | string | ❌ No | Apple Developer Team ID — only for native authentication |
| auth_redirects | object | ❌ No | Auth redirect paths — only for native authentication |
Native Authentication vs WebView Authentication
✅ Provide team_id and auth_redirects when:
team_id and auth_redirects when:- You want to handle authentication natively using Universal Links
- Enables device-stored logins (Google, Facebook, etc.)
- More reliable — uses Safari/native browser for authentication
⚠️ Omit team_id and auth_redirects when:
team_id and auth_redirects when:- You want authentication inside the WebView
- Less reliable (some providers block WebView auth)
- Worse UX (no stored logins for social providers)
Example Response (201 Created)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"pwa_url": "https://example.com",
"status": "created",
"manifest_url": null,
"project_zip_filename": null,
"build_zip_filename": null,
"download_url": null,
"error_message": null,
"created_at": "2025-11-10T12:00:00Z",
"updated_at": "2025-11-10T12:00:00Z"
}2. Get Draft Status
GET /wrapper/draft/{draft_id}
/wrapper/draft/{draft_id}Poll this endpoint to track wrapping progress.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| draft_id | string (UUID) | Draft ID from POST /wrap |
Example Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"pwa_url": "https://example.com",
"status": "completed",
"manifest_url": "https://example.com/manifest.json",
"project_zip_filename": "550e8400-e29b-41d4-a716-446655440000.zip",
"build_zip_filename": "550e8400-e29b-41d4-a716-446655440000.zip",
"download_url": "https://pwa-ios.aptoide.com/pwa-ios/8.20251013/storage/file/550e8400-e29b-41d4-a716-446655440000.zip",
"error_message": null,
"created_at": "2025-11-10T12:00:00Z",
"updated_at": "2025-11-10T12:05:00Z"
}Status Flow
| Status | Description |
|---|---|
created | Draft created, wrapping process starting |
fetching_manifest | Fetching and validating PWA manifest |
generating_project | Generating Xcode project files |
building | Building the iOS application |
completed | ✅ Build finished — download_url available |
failed | ❌ Process failed — see error_message |
Response Fields
| Field | Type | Description |
|---|---|---|
| id | string | Unique draft identifier |
| pwa_url | string | Original PWA URL |
| status | string | Current status |
| manifest_url | string? | URL of fetched manifest |
| project_zip_filename | string? | Generated Xcode project filename |
| build_zip_filename | string? | Final build filename |
| download_url | string? | Download URL (only when completed) |
| error_message | string? | Error details (only if failed) |
| created_at | datetime | Draft creation timestamp |
| updated_at | datetime | Last updated timestamp |
Download Contents
When status is completed, the .zip contains:
Always Included
-
Unsigned
.app(Simulator) Run directly on iOS Simulator for testing. -
Unsigned
.ipaRequires manual signing before distribution. -
Xcode Project Folder Use this to manually sign and publish the application.
Included Only With Native Authentication (team_id provided)
team_id provided)-
OAUTH_SETUP.mdInstructions for setting up native authentication and Universal Links. -
apple-app-site-associationPreconfigured file to place at:{base_url}/.well-known/apple-app-site-association
⚠️ Not included if native auth is not configured.
Polling Recommendations
| Parameter | Recommended |
|---|---|
| Poll interval | 5–10 seconds |
| Timeout | 20–25 minutes |
| Typical build time | 3–8 minutes |
Next Steps After Download
✅ With Native Authentication (team_id + auth_redirects)
team_id + auth_redirects)- Extract
.zip - Test in Simulator
- Read
OAUTH_SETUP.md - Place
apple-app-site-associationon your website - Open Xcode project & configure code signing
- Build & archive in Xcode
- Submit to App Store
⚠️ Without Native Authentication (WebView auth)
- Extract
.zip - Test in Simulator
- Open Xcode project & configure code signing
- Build & archive in Xcode
- Submit to App Store
Important Notes
✅ Key Points
- Wrapping runs asynchronously in background
- Build time: 3–8 minutes
download_urlonly available when status = completed- Drafts are kept for historical tracking
⚠️ Important Warnings
-
Unsigned
.ipamust be signed before distribution -
Native authentication requires:
team_idauth_redirects- proper hosting of
apple-app-site-association
-
WebView authentication works but has:
- worse UX
- unreliable social login support
Updated 11 days ago
