From 9e2e7c271aa5deda69c47c97a87a07fbdee320ab Mon Sep 17 00:00:00 2001 From: ashutoshkhainar33-star Date: Fri, 28 Aug 2026 18:58:21 +0530 Subject: [PATCH 1/3] Revise README for FastPix Live iOS app Updated project name and description, added badges, and revised core features and setup instructions. --- README.md | 344 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 230 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index 6f6e88c..057912e 100644 --- a/README.md +++ b/README.md @@ -1,186 +1,302 @@ -# StreamGate iOS Application Project +# FastPix Live - iOS RTMP live streaming demo app (Swift, HaishinKit) -StreamGate is an open-source native iOS application designed as a technical showcase for capturing and uploading video content directly to the cloud. Built purely for developers, it demonstrates how to handle complex mobile media workflows — such as camera capture, background screen recording, and reliable direct-to-cloud resumable uploads using FastPix infrastructure. +[![Platform: iOS](https://img.shields.io/badge/platform-iOS%2013%2B-000000?logo=apple&logoColor=white)](https://developer.apple.com/ios/) +[![Swift](https://img.shields.io/badge/Swift-5.0-F05138?logo=swift&logoColor=white)](https://swift.org) +[![license](https://img.shields.io/github/license/FastPix/fastpix-iOS-live-streaming-demo-application)](https://github.com/FastPix/fastpix-iOS-live-streaming-demo-application/blob/main/LICENSE) +[![HaishinKit](https://img.shields.io/badge/RTMP-HaishinKit%201.7.1-informational)](https://github.com/shogo4405/HaishinKit.swift) +[![FastPix Live](https://img.shields.io/badge/FastPix-Live%20Streaming-5D09C7)](https://dashboard.fastpix.com) -Once an upload completes, StreamGate generates an instant, shareable playback link. +An open-source iOS app that broadcasts live video from your iPhone camera to the FastPix Live platform over secure RTMPS, built with the [HaishinKit RTMP library](https://github.com/shogo4405/HaishinKit.swift). Use it as a working reference for adding camera-based live streaming, adaptive bitrate, network reconnection, and crash-safe camera switching to your own iOS app. ---- +**Works with:** iOS 13+ · Swift · UIKit · CocoaPods · HaishinKit (RTMP/RTMPS) · FastPix Live · physical iPhone/iPad -## Core Features & Architecture +📖 **FastPix Live docs:** https://fastpix.com/docs  ·  🚀 **Dashboard:** https://dashboard.fastpix.com  ·  ⚙️ **RTMP library:** https://github.com/shogo4405/HaishinKit.swift -StreamGate is built using a modern iOS tech stack (100% Swift, SwiftUI, ReplayKit, AVFoundation) and focuses on the following core capabilities: +## Demo -1. **Camera Capture**: Integrates `UIImagePickerController` for native video recording directly within the app. -2. **Screen Recording**: Uses Apple's `ReplayKit` Broadcast Extension with `AVAssetWriter` to capture device-wide screen activity reliably in a separate sandboxed process. -3. **Direct Cloud Uploading**: Utilizes the FastPix iOS Upload SDK to push large media files securely to the cloud in resumable chunks without routing them through an intermediary backend server. -4. **Local Playback / Preview**: Integrates `AVPlayer` to preview the recorded video locally before the shareable link is generated. -5. **Auto Cleanup**: Automatically deletes previous recordings before each new session to keep on-device storage usage low. +![FastPix Live Demo](FpLive/Assets.xcassets/demo.gif) ---- +
-## Tech Stack & Dependencies +## What this app demonstrates -* **Language**: Swift -* **UI Framework**: SwiftUI -* **Screen Capture**: ReplayKit (`RPBroadcastSampleHandler`, `RPSystemBroadcastPickerView`) -* **Video Encoding**: AVFoundation (`AVAssetWriter`, H.264) -* **Inter-process Communication**: App Groups (shared `UserDefaults` + shared filesystem) -* **Uploading**: [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads) -* **Build Constraints**: `iOS 16.0+`, Xcode 15+, real device required +FastPix Live is a reference implementation for camera-to-cloud live streaming on iOS. It shows how to: ---- +- **Broadcast over RTMPS** - secure live streaming to the FastPix Live platform +- **Switch cameras live** - crash-safe front/back camera toggle during an active broadcast +- **Survive network changes** - automatic reconnection on dropouts and WiFi to cellular handoff, with exponential backoff +- **Adapt quality** - dynamic bitrate adjustment across four broadcasting profiles (1080p, 720p, 540p, 360p) +- **Monitor the stream** - live FPS and bitrate readouts, plus a full streaming state machine (idle, connecting, publishing, reconnecting, and more) +- **Keep the UI safe** - iOS 18-style notifications, haptics, screen wake lock, and thread-safe state handling -## Setup & Build Instructions +
-### Prerequisites +## Prerequisites -Before building the project, ensure you have: +Before you start, make sure you have: -* Xcode 15+ -* iOS 16.0+ -* Physical iPhone device (ReplayKit Broadcast Extensions do not work reliably on Simulator) -* Apple Developer Account -* FastPix API credentials +- A **Mac with Xcode** installed. +- **CocoaPods** installed (`sudo gem install cocoapods`), used to pull HaishinKit and the other dependencies. +- A **physical iPhone or iPad** running **iOS 13.0 or later**. The Simulator cannot access the camera, so streaming will not work on it. +- An **Apple Developer account** to sign and run the app on your device. +- A **FastPix account** with a live stream and its **RTMP stream key**. ---- +
-### 1. Clone Repository +## Get your FastPix stream key + +The app publishes to a FastPix live stream identified by your stream key, which you enter in the app at runtime: + +1. Sign up or log in at the [FastPix Dashboard](https://dashboard.fastpix.com/signup). +2. Create a **live stream** and copy its unique **stream key**. + +You will paste this key into the app's setup screen the first time you broadcast. The RTMP endpoint itself is already configured in the app (see [About the RTMP endpoint](#about-the-rtmp-endpoint)), so the stream key is the only value you need. + +
+ +## Clone the repository ```bash -git clone https://github.com/FastPix/iOS-StreamGate.git -cd StreamGate -open StreamGate.xcodeproj +git clone https://github.com/FastPix/fastpix-iOS-live-streaming-demo-application.git +cd fastpix-iOS-live-streaming-demo-application ``` ---- +> The `Podfile`, `FpLive.xcworkspace`, and `FpLive.xcodeproj` all live at the repository root. Run the next commands from this cloned root folder, not from the inner `FpLive/` source folder. + +
-### 2. Add FastPix iOS Uploads SDK +## Install dependencies with CocoaPods -StreamGate uses the [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads) for resumable chunked uploads. +This project uses CocoaPods (HaishinKit, Hue, Loaf). From the repository root, run: -**Via Swift Package Manager:** +```bash +pod install +``` -1. In Xcode go to **File → Add Package Dependencies** -2. Enter the package URL: - ``` - https://github.com/FastPix/iOS-Uploads - ``` -3. Select the latest version and add it to the **StreamGate** main target +
-After adding, verify the SDK appears under the main target's **Frameworks, Libraries, and Embedded Content** alongside `ScreenBroadcastExtension.appex`: +## Open and run the app +Open the generated workspace (not the `.xcodeproj`): + +```bash +open FpLive.xcworkspace ``` -Frameworks, Libraries, and Embedded Content -├── fp-swift-upload-sdk -└── ScreenBroadcastExtension.appex → Embed Without Signing -``` -> `ScreenBroadcastExtension.appex` must be set to **Embed Without Signing** so iOS bundles the extension inside the main app at install time. Without this the broadcast picker will show no available extension. +Then in Xcode: + +1. Select the `FpLive` scheme and choose your connected iPhone/iPad as the run destination (not a Simulator). +2. In **Signing & Capabilities**, select your Apple Developer Team so the app can be signed for your device. +3. Build and run (`⌘R`). -For full SDK setup instructions refer to the official guide: [Set up Resumable Uploads for iOS](https://fastpix.com/docs/upload-videos/set-up-resumable-uploads-for-ios) +
---- +## Start streaming and verify it works -### 3. Configure App Groups +1. Launch the app on your device and grant **camera** and **microphone** permission when prompted. +2. On the setup screen, paste your FastPix **stream key** and start the broadcast. +3. The app connects over RTMPS and begins publishing. You should see the live camera preview with real-time FPS and bitrate indicators, and the state move to `publishing`. +4. Confirm the stream is live by watching it back from your [FastPix Dashboard](https://dashboard.fastpix.com) (or any player pointed at your stream's playback ID). -Enable the same App Group for both targets: +If you see a black screen or a connection failure, see [Troubleshooting](#troubleshooting). -**Main App Target** +
+## About the RTMP endpoint + +The app is preconfigured to publish to FastPix Live over secure RTMPS. The committed source connects to: + +`rtmps://live.fastpix.com:443/live` + +FastPix endpoints are migrating from the `.io` TLD to `.com`. The old `rtmps://live.fastpix.io:443/live` host continues to serve traffic temporarily for backward compatibility, but it is planned for future deprecation, so the `.com` endpoint above is recommended. You do not need to set this manually - it is already wired into the app. + +
+ +## Streaming profiles + +The app supports four broadcasting profiles, selectable in the UI: + +```Swift +enum Preset { + case hd_1080p_30fps_5mbps // Premium quality + case hd_720p_30fps_3mbps // High quality + case sd_540p_30fps_2mbps // Standard quality + case sd_360p_30fps_1mbps // Data-saver quality +} ``` -Signing & Capabilities -→ App Groups -→ group.com.streamgate.broadcast + +> **Note:** At 1080p, older devices may drop frames to around 20 fps. Camera switching is intentionally disabled during connection states to prevent crashes, and rotation changes during reconnection may cause a connection to fail. + +
+ +## Architecture overview + +### Core components + +**`LiveStreamViewController.swift`** - the main streaming interface, containing: + +- **Camera management**: safe switching between front/back cameras +- **Stream control**: start/stop broadcasting with state management +- **Network handling**: connection monitoring and automatic retry logic +- **UI management**: modern controls with real-time feedback + +### Key classes + +- **`UltraModernNotificationView`** - iOS 18-style notifications with blur effects, haptic feedback, and auto-dismiss animations. +- **`ModernNotificationManager`** - a centralized, thread-safe notification system with success/error/warning/info styles. +- **`StreamState` enum** - comprehensive lifecycle state management with per-state UI behavior. + +
+ +## Technical implementation + +### Stream setup process + +**1. Permission handling** + +```Swift +requestCameraPermission { [weak self] granted in + if granted { + self?.setupStreamingEngine() + } else { + DispatchQueue.main.async { + self?.showPermissionAlert() + } + } +} ``` -**ScreenBroadcastExtension Target** +**2. RTMP configuration** +```Swift +rtmpStream = RTMPStream(connection: rtmpConnection) +configureStream(preset: self.preset) +rtmpStream.attachCamera(cameraDevice) +rtmpStream.attachAudio(audioDevice) ``` -Signing & Capabilities -→ App Groups -→ group.com.streamgate.broadcast + +**3. Connection management** + +```Swift +rtmpConnection.addEventListener(.rtmpStatus, selector: #selector(rtmpStatusHandler), observer: self) +rtmpConnection.connect("rtmps://live.fastpix.com:443/live") ``` -> The App Group identifier must match exactly on both targets. If they differ, the extension and main app write and read from different sandboxed directories and no recorded file will ever be detected. +### Crash protection -To learn more about App Groups and Broadcast Extensions refer to: [ReplayKit — Apple Developer Documentation](https://developer.apple.com/documentation/replaykit) +**Camera switching protection** ---- +```Swift +private var isCameraSwitching = false +private var cameraAttachmentInProgress = false -### 4. Configure Broadcast Extension +private func attachCamera() { +guard !isCameraSwitching && !cameraAttachmentInProgress else { return } -Verify the Broadcast Extension Bundle Identifier: +// Safe camera switching logic +} ``` -com.streamgate.StreamGate.ScreenBroadcastExtension -``` -And ensure the same identifier is referenced in `BroadcastPickerView.swift`: +**Status interaction safety** + +```Swift +private func handleConnectingStateInteraction() { +guard isViewLoaded, view.window != nil, presentedViewController == nil else { return } -```swift -picker.preferredExtension = "com.streamgate.StreamGate.ScreenBroadcastExtension" +// Safe UI interaction during connection states + +} ``` ---- +### Streaming state machine + +```Swift +enum StreamState { + case idle // Ready to start streaming + case connecting // Attempting RTMP connection + case connected // Connected, starting stream + case publishing // Live streaming active + case reconnecting // Recovering from connection loss + case stopping // Ending stream gracefully + case waitingForNetwork // Poor network, waiting for improvement +} +``` -### 5. Configure FastPix Credentials +### Error handling and recovery -Add your FastPix credentials in `UploadService.swift`: +- **Network change detection**: seamless transition between WiFi and cellular +- **Connection timeout**: 15-second timeout with user options +- **Poor network handling**: quality reduction and user notifications +- **Thread safety**: all UI updates on the main thread with proper guards +- **Debouncing**: prevents rapid button taps and concurrent operations -```swift -let accessTokenID = "YOUR_TOKEN_ID" -let secretKey = "YOUR_SECRET_KEY" -``` +
-For production builds, store credentials securely using environment variables or `xcconfig` files. Never commit credentials to version control. +## Troubleshooting -To get your FastPix API credentials visit: [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) +### "No Podfile found" when running `pod install` +Run `pod install` from the repository **root** (`fastpix-iOS-live-streaming-demo-application/`), not from the inner `FpLive/` folder. The `Podfile` is at the root. ---- +### Black screen during streaming +- Confirm camera and microphone permissions are granted. +- Verify your stream key is valid and copied correctly from the dashboard. +- Restart the app. -### 6. Required Permissions +### Connection failures +- Check network connectivity and try a different network (WiFi or cellular). +- Confirm the RTMPS endpoint `rtmps://live.fastpix.com:443/live` is reachable from your network. +- Confirm the live stream is active in your [FastPix Dashboard](https://dashboard.fastpix.com). -Add the following permissions to the main application's `Info.plist`: +### Nothing happens on the Simulator +Streaming and camera capture require a **physical device**. The Simulator has no camera and cannot broadcast. -```xml -NSCameraUsageDescription -Used to record videos. +### Camera switching crashes +The app includes crash protection for camera switching. Avoid switching cameras rapidly during connection/reconnection states. -NSMicrophoneUsageDescription -Used to record audio. -``` +
---- +## Which FastPix repo do I need? -### 7. Build & Run +This app **broadcasts** live video from iOS. To play FastPix video or add other capabilities, use: -**Using Xcode** +| I want to... | Repo | +|---|---| +| Play FastPix video (incl. live playback) in an iOS app | [iOS-player](https://github.com/FastPix/iOS-player) | +| Play FastPix video on the web | [web-player-component](https://github.com/FastPix/web-player-component) | +| Add playback QoE analytics for AVPlayer (iOS / tvOS) | [iOS-data-avplayer-sdk](https://github.com/FastPix/iOS-data-avplayer-sdk) | +| Add resumable uploads to an iOS app | [iOS-Uploads](https://github.com/FastPix/iOS-Uploads) | +| Add resumable uploads in the browser | [web-uploads-sdk](https://github.com/FastPix/web-uploads-sdk) | -1. Open `StreamGate.xcodeproj` -2. Select a physical iPhone as the run destination -3. Ensure your Apple Developer Team is selected for both: - * `StreamGate` - * `ScreenBroadcastExtension` -4. Verify App Groups are enabled on both targets: - * `group.com.streamgate.broadcast` -5. Build and run: +Browse everything in the [FastPix organization](https://github.com/orgs/FastPix/repositories). -``` -Product → Clean Build Folder -Product → Build -Product → Run -``` +
+ +## FAQ + +**What does this app do?** +It broadcasts live video from an iPhone/iPad camera to FastPix Live over RTMPS, with adaptive bitrate and automatic reconnection. See [What this app demonstrates](#what-this-app-demonstrates). + +**Which RTMP library does it use?** +[HaishinKit](https://github.com/shogo4405/HaishinKit.swift) (locked to version 1.7.1 via CocoaPods). + +**Where do I get my stream key?** +Create a live stream in the [FastPix Dashboard](https://dashboard.fastpix.com) and copy its stream key. See [Get your FastPix stream key](#get-your-fastpix-stream-key). + +**What RTMP endpoint does it stream to?** +`rtmps://live.fastpix.com:443/live`, already configured in the app. See [About the RTMP endpoint](#about-the-rtmp-endpoint). + +**Why won't it work on the Simulator?** +The Simulator has no camera. You need a physical iPhone or iPad running iOS 13.0+. -## Important Reference Links +**Can I stream in 1080p?** +Yes, but older devices may drop to around 20 fps at 1080p. Lower profiles (720p/540p/360p) are available for weaker networks or devices. -* FastPix Platform: [fastpix.com](https://fastpix.com) -* FastPix Access Token Guide: [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) -* FastPix VOD Upload API Docs: [Direct Upload Video Media](https://fastpix.com/docs/video-on-demand-api/upload-and-import-videos/direct-upload-video-media) -* FastPix iOS Uploads SDK: [FastPix/iOS-Uploads](https://github.com/FastPix/iOS-Uploads) -* Apple ReplayKit Docs: [ReplayKit — Apple Developer](https://developer.apple.com/documentation/replaykit) +**How do I play the live stream back?** +Use a FastPix player - for iOS use [iOS-player](https://github.com/FastPix/iOS-player), or [web-player-component](https://github.com/FastPix/web-player-component) on the web. See [Which FastPix repo do I need?](#which-fastpix-repo-do-i-need) ---- +
## License -StreamGate is licensed under the MIT License. +FastPix Live is released under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. From f9cf99c3f022bd7f7e819098b4f886680ae2071d Mon Sep 17 00:00:00 2001 From: ashutoshkhainar33-star Date: Thu, 3 Sep 2026 18:03:36 +0530 Subject: [PATCH 2/3] Revise README for StreamGate project details Updated project name and description, added new badges, and revised prerequisites and setup instructions. --- README.md | 341 +++++++++++++++++++++++++----------------------------- 1 file changed, 160 insertions(+), 181 deletions(-) diff --git a/README.md b/README.md index 057912e..5a31f9e 100644 --- a/README.md +++ b/README.md @@ -1,272 +1,241 @@ -# FastPix Live - iOS RTMP live streaming demo app (Swift, HaishinKit) +# FastPix StreamGate - iOS screen recording and camera capture with direct-to-cloud uploads (SwiftUI) -[![Platform: iOS](https://img.shields.io/badge/platform-iOS%2013%2B-000000?logo=apple&logoColor=white)](https://developer.apple.com/ios/) -[![Swift](https://img.shields.io/badge/Swift-5.0-F05138?logo=swift&logoColor=white)](https://swift.org) -[![license](https://img.shields.io/github/license/FastPix/fastpix-iOS-live-streaming-demo-application)](https://github.com/FastPix/fastpix-iOS-live-streaming-demo-application/blob/main/LICENSE) -[![HaishinKit](https://img.shields.io/badge/RTMP-HaishinKit%201.7.1-informational)](https://github.com/shogo4405/HaishinKit.swift) -[![FastPix Live](https://img.shields.io/badge/FastPix-Live%20Streaming-5D09C7)](https://dashboard.fastpix.com) +[![Platform: iOS](https://img.shields.io/badge/platform-iOS%2016%2B-000000?logo=apple&logoColor=white)](https://developer.apple.com/ios/) +[![Swift](https://img.shields.io/badge/Swift-F05138?logo=swift&logoColor=white)](https://swift.org) +[![UI: SwiftUI](https://img.shields.io/badge/UI-SwiftUI-0071E3?logo=swift&logoColor=white)](https://developer.apple.com/xcode/swiftui/) +[![license](https://img.shields.io/github/license/FastPix/iOS-StreamGate)](https://github.com/FastPix/iOS-StreamGate/blob/main/LICENSE) +[![FastPix iOS Uploads SDK](https://img.shields.io/badge/FastPix-iOS%20Uploads%20SDK-5D09C7)](https://github.com/FastPix/iOS-Uploads) -An open-source iOS app that broadcasts live video from your iPhone camera to the FastPix Live platform over secure RTMPS, built with the [HaishinKit RTMP library](https://github.com/shogo4405/HaishinKit.swift). Use it as a working reference for adding camera-based live streaming, adaptive bitrate, network reconnection, and crash-safe camera switching to your own iOS app. +StreamGate is an open-source iOS reference app that captures video (native camera or device-wide ReplayKit screen recording) and uploads it directly to the cloud in resumable chunks using the [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads), then returns an instant, shareable playback link. Use it as a working example of complex mobile media workflows. -**Works with:** iOS 13+ · Swift · UIKit · CocoaPods · HaishinKit (RTMP/RTMPS) · FastPix Live · physical iPhone/iPad +**Works with:** iOS 16+ · SwiftUI · ReplayKit · AVFoundation · FastPix iOS Uploads SDK · physical iPhone -📖 **FastPix Live docs:** https://fastpix.com/docs  ·  🚀 **Dashboard:** https://dashboard.fastpix.com  ·  ⚙️ **RTMP library:** https://github.com/shogo4405/HaishinKit.swift - -## Demo - -![FastPix Live Demo](FpLive/Assets.xcassets/demo.gif) +📖 **Upload SDK docs:** https://fastpix.com/docs/upload-videos/set-up-resumable-uploads-for-ios  ·  ⬆️ **Uploads SDK:** https://github.com/FastPix/iOS-Uploads  ·  🚀 **Dashboard:** https://dashboard.fastpix.com
## What this app demonstrates -FastPix Live is a reference implementation for camera-to-cloud live streaming on iOS. It shows how to: +StreamGate is built with a modern iOS stack (100% Swift, SwiftUI, ReplayKit, AVFoundation) and shows how to: + +1. **Camera capture** - record video natively with `UIImagePickerController`. +2. **Screen recording** - capture device-wide screen activity with Apple's `ReplayKit` Broadcast Extension and `AVAssetWriter`, running reliably in a separate sandboxed process. +3. **Direct cloud uploading** - push large media files to the cloud in resumable chunks with the FastPix iOS Uploads SDK, with no intermediary backend server. +4. **Local playback / preview** - preview the recording with `AVPlayer` before the shareable link is generated. +5. **Auto cleanup** - delete previous recordings before each new session to keep on-device storage low. -- **Broadcast over RTMPS** - secure live streaming to the FastPix Live platform -- **Switch cameras live** - crash-safe front/back camera toggle during an active broadcast -- **Survive network changes** - automatic reconnection on dropouts and WiFi to cellular handoff, with exponential backoff -- **Adapt quality** - dynamic bitrate adjustment across four broadcasting profiles (1080p, 720p, 540p, 360p) -- **Monitor the stream** - live FPS and bitrate readouts, plus a full streaming state machine (idle, connecting, publishing, reconnecting, and more) -- **Keep the UI safe** - iOS 18-style notifications, haptics, screen wake lock, and thread-safe state handling +Once an upload completes, StreamGate generates an instant, shareable playback link.
## Prerequisites -Before you start, make sure you have: +Before you build the project, make sure you have: -- A **Mac with Xcode** installed. -- **CocoaPods** installed (`sudo gem install cocoapods`), used to pull HaishinKit and the other dependencies. -- A **physical iPhone or iPad** running **iOS 13.0 or later**. The Simulator cannot access the camera, so streaming will not work on it. -- An **Apple Developer account** to sign and run the app on your device. -- A **FastPix account** with a live stream and its **RTMP stream key**. +- **Xcode** 15 or later. Note: the committed project was created with Xcode 26.5 and both targets set `IPHONEOS_DEPLOYMENT_TARGET = 26.0`, so as-is you need Xcode 26 and an iOS 26 device. To run on iOS 16 (which the app's code supports via `if #available(iOS 16.0, *)`), lower the deployment target to 16.0 on both targets. +- A **physical iPhone** - ReplayKit Broadcast Extensions do not work reliably on the Simulator. +- An **Apple Developer account** (for signing the app and the extension). +- A **FastPix account** with an Access Token ID (Token ID) and a Secret Key.
-## Get your FastPix stream key +## Get your FastPix credentials -The app publishes to a FastPix live stream identified by your stream key, which you enter in the app at runtime: +The app authenticates to FastPix to create a signed direct-upload URL, so you need your API credentials: -1. Sign up or log in at the [FastPix Dashboard](https://dashboard.fastpix.com/signup). -2. Create a **live stream** and copy its unique **stream key**. +1. Sign up or log in and follow the [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) guide. +2. Copy your **Access Token ID** (Token ID) and **Secret Key**. -You will paste this key into the app's setup screen the first time you broadcast. The RTMP endpoint itself is already configured in the app (see [About the RTMP endpoint](#about-the-rtmp-endpoint)), so the stream key is the only value you need. +You will set these as environment variables in Step 5. Never commit real credentials to version control.
-## Clone the repository +## Step 1: Clone the repository ```bash -git clone https://github.com/FastPix/fastpix-iOS-live-streaming-demo-application.git -cd fastpix-iOS-live-streaming-demo-application +git clone https://github.com/FastPix/iOS-StreamGate.git +cd StreamGate +open StreamGate.xcodeproj ``` -> The `Podfile`, `FpLive.xcworkspace`, and `FpLive.xcodeproj` all live at the repository root. Run the next commands from this cloned root folder, not from the inner `FpLive/` source folder. -
-## Install dependencies with CocoaPods - -This project uses CocoaPods (HaishinKit, Hue, Loaf). From the repository root, run: +## Step 2: Add the FastPix iOS Uploads SDK -```bash -pod install -``` +StreamGate uses the [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads) for resumable chunked uploads. -
+**Via Swift Package Manager:** -## Open and run the app +1. In Xcode go to **File → Add Package Dependencies** +2. Enter the package URL: + ``` + https://github.com/FastPix/iOS-Uploads + ``` +3. Select the latest version and add it to the **StreamGate** main target -Open the generated workspace (not the `.xcodeproj`): +After adding, verify the SDK appears under the main target's **Frameworks, Libraries, and Embedded Content** alongside `ScreenBroadcastExtension.appex`: -```bash -open FpLive.xcworkspace +``` +Frameworks, Libraries, and Embedded Content +├── fp-swift-upload-sdk +└── ScreenBroadcastExtension.appex → Embed Without Signing ``` -Then in Xcode: +> `ScreenBroadcastExtension.appex` must be set to **Embed Without Signing** so iOS bundles the extension inside the main app at install time. Without this the broadcast picker will show no available extension. -1. Select the `FpLive` scheme and choose your connected iPhone/iPad as the run destination (not a Simulator). -2. In **Signing & Capabilities**, select your Apple Developer Team so the app can be signed for your device. -3. Build and run (`⌘R`). +For full SDK setup instructions refer to the official guide: [Set up Resumable Uploads for iOS](https://fastpix.com/docs/upload-videos/set-up-resumable-uploads-for-ios)
-## Start streaming and verify it works +## Step 3: Configure App Groups -1. Launch the app on your device and grant **camera** and **microphone** permission when prompted. -2. On the setup screen, paste your FastPix **stream key** and start the broadcast. -3. The app connects over RTMPS and begins publishing. You should see the live camera preview with real-time FPS and bitrate indicators, and the state move to `publishing`. -4. Confirm the stream is live by watching it back from your [FastPix Dashboard](https://dashboard.fastpix.com) (or any player pointed at your stream's playback ID). +Enable the same App Group for both targets: -If you see a black screen or a connection failure, see [Troubleshooting](#troubleshooting). +**Main App Target** -
+``` +Signing & Capabilities +→ App Groups +→ group.com.streamgate.broadcast +``` -## About the RTMP endpoint +**ScreenBroadcastExtension Target** -The app is preconfigured to publish to FastPix Live over secure RTMPS. The committed source connects to: +``` +Signing & Capabilities +→ App Groups +→ group.com.streamgate.broadcast +``` -`rtmps://live.fastpix.com:443/live` +> The App Group identifier must match exactly on both targets. If they differ, the extension and main app write and read from different sandboxed directories and no recorded file will ever be detected. -FastPix endpoints are migrating from the `.io` TLD to `.com`. The old `rtmps://live.fastpix.io:443/live` host continues to serve traffic temporarily for backward compatibility, but it is planned for future deprecation, so the `.com` endpoint above is recommended. You do not need to set this manually - it is already wired into the app. +To learn more about App Groups and Broadcast Extensions refer to: [ReplayKit - Apple Developer Documentation](https://developer.apple.com/documentation/replaykit)
-## Streaming profiles +## Step 4: Configure the broadcast extension -The app supports four broadcasting profiles, selectable in the UI: +Verify the Broadcast Extension Bundle Identifier: -```Swift -enum Preset { - case hd_1080p_30fps_5mbps // Premium quality - case hd_720p_30fps_3mbps // High quality - case sd_540p_30fps_2mbps // Standard quality - case sd_360p_30fps_1mbps // Data-saver quality -} +``` +com.streamgate.StreamGate.ScreenBroadcastExtension ``` -> **Note:** At 1080p, older devices may drop frames to around 20 fps. Camera switching is intentionally disabled during connection states to prevent crashes, and rotation changes during reconnection may cause a connection to fail. +And ensure the same identifier is referenced in `BroadcastPickerView.swift`: -
+```swift +picker.preferredExtension = "com.streamgate.StreamGate.ScreenBroadcastExtension" +``` -## Architecture overview +
-### Core components +## Step 5: Configure your FastPix credentials -**`LiveStreamViewController.swift`** - the main streaming interface, containing: +The app reads your FastPix credentials from environment variables at runtime via `ProcessInfo` (`ACCESS_TOKEN_ID` and `SECRET_KEY`). Set them in your Xcode scheme: -- **Camera management**: safe switching between front/back cameras -- **Stream control**: start/stop broadcasting with state management -- **Network handling**: connection monitoring and automatic retry logic -- **UI management**: modern controls with real-time feedback +1. Go to **Product → Scheme → Edit Scheme** (or press `⌘ <`) +2. Select the **Run** action → **Arguments** tab +3. Under **Environment Variables**, add: -### Key classes +| Name | Value | +|------|-------| +| `ACCESS_TOKEN_ID` | Your FastPix Token ID | +| `SECRET_KEY` | Your FastPix Secret Key | -- **`UltraModernNotificationView`** - iOS 18-style notifications with blur effects, haptic feedback, and auto-dismiss animations. -- **`ModernNotificationManager`** - a centralized, thread-safe notification system with success/error/warning/info styles. -- **`StreamState` enum** - comprehensive lifecycle state management with per-state UI behavior. +Never commit credentials to version control. Get your credentials from [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account).
-## Technical implementation +## Step 6: Camera and microphone permissions -### Stream setup process +The app already requests camera and microphone access (declared in its generated `Info.plist`), so no action is needed. For reference, these are the usage descriptions it presents: -**1. Permission handling** +```xml +NSCameraUsageDescription +Used to record videos. -```Swift -requestCameraPermission { [weak self] granted in - if granted { - self?.setupStreamingEngine() - } else { - DispatchQueue.main.async { - self?.showPermissionAlert() - } - } -} +NSMicrophoneUsageDescription +Used to record audio. ``` -**2. RTMP configuration** - -```Swift -rtmpStream = RTMPStream(connection: rtmpConnection) -configureStream(preset: self.preset) -rtmpStream.attachCamera(cameraDevice) -rtmpStream.attachAudio(audioDevice) -``` - -**3. Connection management** - -```Swift -rtmpConnection.addEventListener(.rtmpStatus, selector: #selector(rtmpStatusHandler), observer: self) -rtmpConnection.connect("rtmps://live.fastpix.com:443/live") -``` - -### Crash protection - -**Camera switching protection** +
-```Swift -private var isCameraSwitching = false -private var cameraAttachmentInProgress = false +## Step 7: Build and run -private func attachCamera() { -guard !isCameraSwitching && !cameraAttachmentInProgress else { return } +**Using Xcode** -// Safe camera switching logic +1. Open `StreamGate.xcodeproj` +2. Select a physical iPhone as the run destination +3. Ensure your Apple Developer Team is selected for both: + * `StreamGate` + * `ScreenBroadcastExtension` +4. Verify App Groups are enabled on both targets: + * `group.com.streamgate.broadcast` +5. Build and run: -} +``` +Product → Clean Build Folder +Product → Build +Product → Run ``` -**Status interaction safety** +
-```Swift -private func handleConnectingStateInteraction() { -guard isViewLoaded, view.window != nil, presentedViewController == nil else { return } +## Verify it works -// Safe UI interaction during connection states +Record a video with the camera, or start a screen broadcast, then let the app upload it. On success: -} -``` +- The app uploads the file to FastPix in resumable chunks and polls until the media reaches `status: ready`. +- A shareable playback link appears in the form `https://stream.fastpix.com/.m3u8`. -### Streaming state machine - -```Swift -enum StreamState { - case idle // Ready to start streaming - case connecting // Attempting RTMP connection - case connected // Connected, starting stream - case publishing // Live streaming active - case reconnecting // Recovering from connection loss - case stopping // Ending stream gracefully - case waitingForNetwork // Poor network, waiting for improvement -} -``` +If the upload does not start or no link appears, see [Troubleshooting](#troubleshooting). + +
-### Error handling and recovery +## Tech stack -- **Network change detection**: seamless transition between WiFi and cellular -- **Connection timeout**: 15-second timeout with user options -- **Poor network handling**: quality reduction and user notifications -- **Thread safety**: all UI updates on the main thread with proper guards -- **Debouncing**: prevents rapid button taps and concurrent operations +* **Language**: Swift +* **UI Framework**: SwiftUI +* **Screen Capture**: ReplayKit (`RPBroadcastSampleHandler`, `RPSystemBroadcastPickerView`) +* **Video Encoding**: AVFoundation (`AVAssetWriter`, H.264) +* **Inter-process Communication**: App Groups (shared `UserDefaults` + shared filesystem) +* **Uploading**: [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads) +* **Build Constraints**: `iOS 16.0+`, Xcode 15+, real device required
## Troubleshooting -### "No Podfile found" when running `pod install` -Run `pod install` from the repository **root** (`fastpix-iOS-live-streaming-demo-application/`), not from the inner `FpLive/` folder. The `Podfile` is at the root. +### The broadcast picker shows no extension +Set `ScreenBroadcastExtension.appex` to **Embed Without Signing** in the main app target (see [Step 2](#step-2-add-the-fastpix-ios-uploads-sdk)). Without this, iOS does not bundle the extension and the picker is empty. -### Black screen during streaming -- Confirm camera and microphone permissions are granted. -- Verify your stream key is valid and copied correctly from the dashboard. -- Restart the app. +### A recorded file is never detected +The App Group identifier must match exactly on both targets (`group.com.streamgate.broadcast`). If they differ, the extension and app use different sandboxed directories. See [Step 3](#step-3-configure-app-groups). -### Connection failures -- Check network connectivity and try a different network (WiFi or cellular). -- Confirm the RTMPS endpoint `rtmps://live.fastpix.com:443/live` is reachable from your network. -- Confirm the live stream is active in your [FastPix Dashboard](https://dashboard.fastpix.com). +### Upload fails or no shareable link appears +1. Confirm the `ACCESS_TOKEN_ID` and `SECRET_KEY` environment variables are set in your Run scheme (see [Step 5](#step-5-configure-your-fastpix-credentials)). +2. Confirm the credentials are active in your [FastPix Dashboard](https://dashboard.fastpix.com) and not expired. +3. Check network connectivity on the device. -### Nothing happens on the Simulator -Streaming and camera capture require a **physical device**. The Simulator has no camera and cannot broadcast. +### It will not build or install on iOS 16 +The committed project targets iOS 26.0. Lower `IPHONEOS_DEPLOYMENT_TARGET` to 16.0 on both the `StreamGate` and `ScreenBroadcastExtension` targets (see [Prerequisites](#prerequisites)). -### Camera switching crashes -The app includes crash protection for camera switching. Avoid switching cameras rapidly during connection/reconnection states. +### Screen recording does not work on the Simulator +Use a physical iPhone - ReplayKit Broadcast Extensions are unreliable on the Simulator.
## Which FastPix repo do I need? -This app **broadcasts** live video from iOS. To play FastPix video or add other capabilities, use: +StreamGate shows uploads plus screen/camera capture in a full app. For the underlying SDKs and other platforms, use: | I want to... | Repo | |---|---| -| Play FastPix video (incl. live playback) in an iOS app | [iOS-player](https://github.com/FastPix/iOS-player) | -| Play FastPix video on the web | [web-player-component](https://github.com/FastPix/web-player-component) | +| Add resumable uploads to an iOS app (the SDK this demo uses) | [iOS-Uploads](https://github.com/FastPix/iOS-Uploads) | +| Play FastPix video in an iOS app | [iOS-player](https://github.com/FastPix/iOS-player) | | Add playback QoE analytics for AVPlayer (iOS / tvOS) | [iOS-data-avplayer-sdk](https://github.com/FastPix/iOS-data-avplayer-sdk) | -| Add resumable uploads to an iOS app | [iOS-Uploads](https://github.com/FastPix/iOS-Uploads) | | Add resumable uploads in the browser | [web-uploads-sdk](https://github.com/FastPix/web-uploads-sdk) | +| Add a React uploader component | [react-web-uploader](https://github.com/FastPix/react-web-uploader) | Browse everything in the [FastPix organization](https://github.com/orgs/FastPix/repositories). @@ -275,28 +244,38 @@ Browse everything in the [FastPix organization](https://github.com/orgs/FastPix/ ## FAQ **What does this app do?** -It broadcasts live video from an iPhone/iPad camera to FastPix Live over RTMPS, with adaptive bitrate and automatic reconnection. See [What this app demonstrates](#what-this-app-demonstrates). +It records video (camera or full-screen ReplayKit recording) and uploads it directly to FastPix in resumable chunks, then returns a shareable playback link. See [What this app demonstrates](#what-this-app-demonstrates). -**Which RTMP library does it use?** -[HaishinKit](https://github.com/shogo4405/HaishinKit.swift) (locked to version 1.7.1 via CocoaPods). +**Why does it need a physical iPhone?** +ReplayKit Broadcast Extensions do not work reliably on the Simulator. See [Prerequisites](#prerequisites). -**Where do I get my stream key?** -Create a live stream in the [FastPix Dashboard](https://dashboard.fastpix.com) and copy its stream key. See [Get your FastPix stream key](#get-your-fastpix-stream-key). +**Where do I get my Token ID and Secret Key?** +From the FastPix Dashboard, via the [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) guide. See [Get your FastPix credentials](#get-your-fastpix-credentials). -**What RTMP endpoint does it stream to?** -`rtmps://live.fastpix.com:443/live`, already configured in the app. See [About the RTMP endpoint](#about-the-rtmp-endpoint). +**Where do I put my credentials?** +Set `ACCESS_TOKEN_ID` and `SECRET_KEY` as environment variables in your Xcode Run scheme. See [Step 5](#step-5-configure-your-fastpix-credentials). -**Why won't it work on the Simulator?** -The Simulator has no camera. You need a physical iPhone or iPad running iOS 13.0+. +**The broadcast picker is empty - why?** +The broadcast extension is not embedded. Set it to Embed Without Signing. See [Troubleshooting](#troubleshooting). + +**Which iOS versions does it support?** +The app's code supports iOS 16.0+, but the committed project currently targets iOS 26.0. See [Prerequisites](#prerequisites) for how to lower it. + +**How do I add resumable uploads to my own app?** +Use the FastPix iOS Uploads SDK directly. See [Which FastPix repo do I need?](#which-fastpix-repo-do-i-need) + +
-**Can I stream in 1080p?** -Yes, but older devices may drop to around 20 fps at 1080p. Lower profiles (720p/540p/360p) are available for weaker networks or devices. +## Important reference links -**How do I play the live stream back?** -Use a FastPix player - for iOS use [iOS-player](https://github.com/FastPix/iOS-player), or [web-player-component](https://github.com/FastPix/web-player-component) on the web. See [Which FastPix repo do I need?](#which-fastpix-repo-do-i-need) +* FastPix Platform: [fastpix.com](https://fastpix.com) +* FastPix Access Token Guide: [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) +* FastPix VOD Upload API Docs: [Direct Upload Video Media](https://fastpix.com/docs/video-on-demand-api/upload-and-import-videos/direct-upload-video-media) +* FastPix iOS Uploads SDK: [FastPix/iOS-Uploads](https://github.com/FastPix/iOS-Uploads) +* Apple ReplayKit Docs: [ReplayKit - Apple Developer](https://developer.apple.com/documentation/replaykit)
## License -FastPix Live is released under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. +StreamGate is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. From d310aca8a8d05a118b0b4523bb5873d1dd415573 Mon Sep 17 00:00:00 2001 From: ashutoshkhainar33-star Date: Thu, 3 Sep 2026 18:48:37 +0530 Subject: [PATCH 3/3] Revise README for setup and prerequisites clarity --- README.md | 225 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 5a31f9e..bc0cfd9 100644 --- a/README.md +++ b/README.md @@ -28,52 +28,150 @@ Once an upload completes, StreamGate generates an instant, shareable playback li
-## Prerequisites +## Start here -Before you build the project, make sure you have: +If you are setting up this demo for the first time, follow these steps in order: -- **Xcode** 15 or later. Note: the committed project was created with Xcode 26.5 and both targets set `IPHONEOS_DEPLOYMENT_TARGET = 26.0`, so as-is you need Xcode 26 and an iOS 26 device. To run on iOS 16 (which the app's code supports via `if #available(iOS 16.0, *)`), lower the deployment target to 16.0 on both targets. -- A **physical iPhone** - ReplayKit Broadcast Extensions do not work reliably on the Simulator. -- An **Apple Developer account** (for signing the app and the extension). -- A **FastPix account** with an Access Token ID (Token ID) and a Secret Key. +1. [Check your macOS version](#1-check-your-macos-version) +2. [Check that Xcode is installed](#2-check-that-xcode-is-installed) +3. [Connect a physical iPhone](#3-connect-a-physical-iphone) +4. [Get your FastPix credentials](#4-get-your-fastpix-credentials) +5. [Clone the repository](#5-clone-the-repository) +6. [Verify the FastPix iOS Uploads SDK](#6-verify-the-fastpix-ios-uploads-sdk) +7. [Verify App Groups on both targets](#7-verify-app-groups-on-both-targets) +8. [Verify the broadcast extension identifier](#8-verify-the-broadcast-extension-identifier) +9. [Configure your FastPix credentials](#9-configure-your-fastpix-credentials) +10. [Build and run on your device](#10-build-and-run-on-your-device) +11. [Record, upload, and verify it works](#11-record-upload-and-verify-it-works) + +Do not skip the verification commands. If a step's check fails, fix that problem before you continue.
-## Get your FastPix credentials +## Before you begin + +Make sure you have the following ready. This app uses a ReplayKit Broadcast Extension and the device camera, so it needs a real iPhone. + +| Requirement | Details | +|---|---| +| **A Mac with Xcode 26 or later** | Install the full Xcode app from the App Store. It provides the build tools, the Swift compiler, and Git. The committed project was created with Xcode 26.5. | +| **A physical iPhone running iOS 26** | Both targets set an iOS 26 deployment target, and ReplayKit Broadcast Extensions do not work reliably on the Simulator, so you need a real device. | +| **An Apple Developer account** | Needed to code-sign the main app **and** the broadcast extension for your device. | +| **A FastPix account** | Free to create at the [FastPix Dashboard](https://dashboard.fastpix.com). | +| **FastPix API credentials** | An Access Token ID (Token ID) and a Secret Key. | + +The app reads your credentials from two environment variables at runtime: + +| App environment variable | FastPix credential | +|---|---| +| `ACCESS_TOKEN_ID` | Access Token ID (Token ID) | +| `SECRET_KEY` | Secret Key | + +> **Supported iOS versions:** The app's code supports **iOS 16.0+** (guarded with `if #available(iOS 16.0, *)`), but the committed project targets iOS 26. To run on an older OS, lower `IPHONEOS_DEPLOYMENT_TARGET` on **both** the `StreamGate` and `ScreenBroadcastExtension` targets in **Build Settings** (see [It will not build or install on iOS 16](#it-will-not-build-or-install-on-ios-16)). + +> **Security:** Never commit your Access Token ID or Secret Key to source control. Set them in your Xcode scheme. + +
+ +## 1. Check your macOS version + +The build tools run on macOS. Confirm your version: + +```bash +sw_vers +``` + +Output is similar to: + +```text +ProductName: macOS +ProductVersion: 26.6.2 +BuildVersion: 25G83 +``` + +Use a macOS version that supports Xcode 26. If macOS is too old, update it before you continue. + +
+ +## 2. Check that Xcode is installed + +This project builds with the full Xcode app. Confirm the command line points at Xcode: + +```bash +xcodebuild -version +``` + +Expected output is similar to: + +```text +Xcode 26.6 +Build version 17F113 +``` + +If instead you see `xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance`, point the command line at Xcode (this needs your password): + +```bash +sudo xcode-select --switch /Applications/Xcode.app +sudo xcodebuild -license accept +``` + +Then run `xcodebuild -version` again. Do not continue until it prints a version. + +
+ +## 3. Connect a physical iPhone + +Screen recording relies on a ReplayKit Broadcast Extension, which does not work reliably on the Simulator, so run on a real iPhone. Connect and unlock your iPhone (tap **Trust This Computer** if prompted), then confirm the toolchain sees it: + +```bash +xcrun xctrace list devices +``` + +Your iPhone appears under `== Devices ==` alongside any simulators. + +
+ +## 4. Get your FastPix credentials The app authenticates to FastPix to create a signed direct-upload URL, so you need your API credentials: 1. Sign up or log in and follow the [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) guide. 2. Copy your **Access Token ID** (Token ID) and **Secret Key**. -You will set these as environment variables in Step 5. Never commit real credentials to version control. +You set these as environment variables in [Configure your FastPix credentials](#9-configure-your-fastpix-credentials). Never commit real credentials to version control.
-## Step 1: Clone the repository +## 5. Clone the repository ```bash git clone https://github.com/FastPix/iOS-StreamGate.git -cd StreamGate +cd iOS-StreamGate open StreamGate.xcodeproj ``` +> The clone creates a folder named `iOS-StreamGate` (the repository name). `StreamGate.xcodeproj` and the `StreamGate/` source folder both live inside it, so run the commands from the `iOS-StreamGate` root. +
-## Step 2: Add the FastPix iOS Uploads SDK +## 6. Verify the FastPix iOS Uploads SDK + +StreamGate uses the [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads) for resumable chunked uploads. **The SDK is already integrated via Swift Package Manager**, so you don't need to add it manually - Xcode resolves it when you open the project. + +To confirm it resolves from the command line, run this from the `iOS-StreamGate` root: -StreamGate uses the [FastPix iOS Uploads SDK](https://github.com/FastPix/iOS-Uploads) for resumable chunked uploads. +```bash +xcodebuild -project StreamGate.xcodeproj -scheme StreamGate -resolvePackageDependencies +``` -**Via Swift Package Manager:** +The output confirms the package (the product is `fp-swift-upload-sdk`, module `fp_swift_upload_sdk`): -1. In Xcode go to **File → Add Package Dependencies** -2. Enter the package URL: - ``` - https://github.com/FastPix/iOS-Uploads - ``` -3. Select the latest version and add it to the **StreamGate** main target +```text +Resolved source packages: + fp-swift-upload-sdk: https://github.com/FastPix/iOS-Uploads.git @ 1.0.2 +``` -After adding, verify the SDK appears under the main target's **Frameworks, Libraries, and Embedded Content** alongside `ScreenBroadcastExtension.appex`: +In Xcode, you can also confirm the main **StreamGate** target lists both the SDK and the embedded extension under **Frameworks, Libraries, and Embedded Content**: ``` Frameworks, Libraries, and Embedded Content @@ -81,47 +179,35 @@ Frameworks, Libraries, and Embedded Content └── ScreenBroadcastExtension.appex → Embed Without Signing ``` -> `ScreenBroadcastExtension.appex` must be set to **Embed Without Signing** so iOS bundles the extension inside the main app at install time. Without this the broadcast picker will show no available extension. +> `ScreenBroadcastExtension.appex` must be set to **Embed Without Signing** so iOS bundles the extension inside the main app at install time. Without this the broadcast picker shows no available extension. -For full SDK setup instructions refer to the official guide: [Set up Resumable Uploads for iOS](https://fastpix.com/docs/upload-videos/set-up-resumable-uploads-for-ios) +For full SDK setup instructions, see [Set up Resumable Uploads for iOS](https://fastpix.com/docs/upload-videos/set-up-resumable-uploads-for-ios).
-## Step 3: Configure App Groups - -Enable the same App Group for both targets: - -**Main App Target** - -``` -Signing & Capabilities -→ App Groups -→ group.com.streamgate.broadcast -``` +## 7. Verify App Groups on both targets -**ScreenBroadcastExtension Target** +The `StreamGate` main app and the `ScreenBroadcastExtension` communicate through a shared App Group, which is already configured on both targets in the committed project. Confirm both use the **same** App Group under each target's **Signing & Capabilities → App Groups**: ``` -Signing & Capabilities -→ App Groups -→ group.com.streamgate.broadcast +group.com.streamgate.broadcast ``` -> The App Group identifier must match exactly on both targets. If they differ, the extension and main app write and read from different sandboxed directories and no recorded file will ever be detected. +> The App Group identifier must match exactly on both targets. If they differ, the extension and main app read and write different sandboxed directories, and no recorded file is ever detected. -To learn more about App Groups and Broadcast Extensions refer to: [ReplayKit - Apple Developer Documentation](https://developer.apple.com/documentation/replaykit) +To learn more, see [ReplayKit - Apple Developer Documentation](https://developer.apple.com/documentation/replaykit).
-## Step 4: Configure the broadcast extension +## 8. Verify the broadcast extension identifier -Verify the Broadcast Extension Bundle Identifier: +Confirm the broadcast extension's Bundle Identifier: ``` com.streamgate.StreamGate.ScreenBroadcastExtension ``` -And ensure the same identifier is referenced in `BroadcastPickerView.swift`: +The same identifier is referenced in `BroadCastPickerView.swift`: ```swift picker.preferredExtension = "com.streamgate.StreamGate.ScreenBroadcastExtension" @@ -129,7 +215,7 @@ picker.preferredExtension = "com.streamgate.StreamGate.ScreenBroadcastExtension"
-## Step 5: Configure your FastPix credentials +## 9. Configure your FastPix credentials The app reads your FastPix credentials from environment variables at runtime via `ProcessInfo` (`ACCESS_TOKEN_ID` and `SECRET_KEY`). Set them in your Xcode scheme: @@ -144,44 +230,27 @@ The app reads your FastPix credentials from environment variables at runtime via Never commit credentials to version control. Get your credentials from [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account). -
- -## Step 6: Camera and microphone permissions - -The app already requests camera and microphone access (declared in its generated `Info.plist`), so no action is needed. For reference, these are the usage descriptions it presents: - -```xml -NSCameraUsageDescription -Used to record videos. - -NSMicrophoneUsageDescription -Used to record audio. -``` +The app already requests camera and microphone access (declared in its generated `Info.plist`), so no extra permission setup is needed. For reference, it presents `NSCameraUsageDescription` ("Used to record videos.") and `NSMicrophoneUsageDescription` ("Used to record audio.").
-## Step 7: Build and run +## 10. Build and run on your device -**Using Xcode** +In Xcode: -1. Open `StreamGate.xcodeproj` -2. Select a physical iPhone as the run destination -3. Ensure your Apple Developer Team is selected for both: +1. Open `StreamGate.xcodeproj`. +2. Select your connected iPhone as the run destination. +3. Under **Signing & Capabilities**, select your Apple Developer **Team** for **both** targets: * `StreamGate` * `ScreenBroadcastExtension` -4. Verify App Groups are enabled on both targets: - * `group.com.streamgate.broadcast` -5. Build and run: +4. Confirm the App Group `group.com.streamgate.broadcast` is enabled on both targets. +5. Build and run: **Product → Clean Build Folder**, then **Product → Run** (`⌘R`). -``` -Product → Clean Build Folder -Product → Build -Product → Run -``` +The first build compiles the Uploads SDK, so it can take a little longer. If the app does not launch on the device, open **Settings → General → VPN & Device Management** on the iPhone and trust your developer certificate, then run again.
-## Verify it works +## 11. Record, upload, and verify it works Record a video with the camera, or start a screen broadcast, then let the app upload it. On success: @@ -207,18 +276,18 @@ If the upload does not start or no link appears, see [Troubleshooting](#troubles ## Troubleshooting ### The broadcast picker shows no extension -Set `ScreenBroadcastExtension.appex` to **Embed Without Signing** in the main app target (see [Step 2](#step-2-add-the-fastpix-ios-uploads-sdk)). Without this, iOS does not bundle the extension and the picker is empty. +Set `ScreenBroadcastExtension.appex` to **Embed Without Signing** in the main app target (see [Step 6](#6-verify-the-fastpix-ios-uploads-sdk)). Without this, iOS does not bundle the extension and the picker is empty. ### A recorded file is never detected -The App Group identifier must match exactly on both targets (`group.com.streamgate.broadcast`). If they differ, the extension and app use different sandboxed directories. See [Step 3](#step-3-configure-app-groups). +The App Group identifier must match exactly on both targets (`group.com.streamgate.broadcast`). If they differ, the extension and app use different sandboxed directories. See [Step 7](#7-verify-app-groups-on-both-targets). ### Upload fails or no shareable link appears -1. Confirm the `ACCESS_TOKEN_ID` and `SECRET_KEY` environment variables are set in your Run scheme (see [Step 5](#step-5-configure-your-fastpix-credentials)). +1. Confirm the `ACCESS_TOKEN_ID` and `SECRET_KEY` environment variables are set in your Run scheme (see [Step 9](#9-configure-your-fastpix-credentials)). 2. Confirm the credentials are active in your [FastPix Dashboard](https://dashboard.fastpix.com) and not expired. 3. Check network connectivity on the device. ### It will not build or install on iOS 16 -The committed project targets iOS 26.0. Lower `IPHONEOS_DEPLOYMENT_TARGET` to 16.0 on both the `StreamGate` and `ScreenBroadcastExtension` targets (see [Prerequisites](#prerequisites)). +The committed project targets iOS 26.0. Lower `IPHONEOS_DEPLOYMENT_TARGET` to 16.0 on both the `StreamGate` and `ScreenBroadcastExtension` targets (see [Before you begin](#before-you-begin)). ### Screen recording does not work on the Simulator Use a physical iPhone - ReplayKit Broadcast Extensions are unreliable on the Simulator. @@ -247,19 +316,19 @@ Browse everything in the [FastPix organization](https://github.com/orgs/FastPix/ It records video (camera or full-screen ReplayKit recording) and uploads it directly to FastPix in resumable chunks, then returns a shareable playback link. See [What this app demonstrates](#what-this-app-demonstrates). **Why does it need a physical iPhone?** -ReplayKit Broadcast Extensions do not work reliably on the Simulator. See [Prerequisites](#prerequisites). +ReplayKit Broadcast Extensions do not work reliably on the Simulator. See [Before you begin](#before-you-begin). **Where do I get my Token ID and Secret Key?** -From the FastPix Dashboard, via the [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) guide. See [Get your FastPix credentials](#get-your-fastpix-credentials). +From the FastPix Dashboard, via the [Activate Your Account](https://fastpix.com/docs/getting-started/activate-your-account) guide. See [Get your FastPix credentials](#4-get-your-fastpix-credentials). **Where do I put my credentials?** -Set `ACCESS_TOKEN_ID` and `SECRET_KEY` as environment variables in your Xcode Run scheme. See [Step 5](#step-5-configure-your-fastpix-credentials). +Set `ACCESS_TOKEN_ID` and `SECRET_KEY` as environment variables in your Xcode Run scheme. See [Step 9](#9-configure-your-fastpix-credentials). **The broadcast picker is empty - why?** The broadcast extension is not embedded. Set it to Embed Without Signing. See [Troubleshooting](#troubleshooting). **Which iOS versions does it support?** -The app's code supports iOS 16.0+, but the committed project currently targets iOS 26.0. See [Prerequisites](#prerequisites) for how to lower it. +The app's code supports iOS 16.0+, but the committed project currently targets iOS 26.0. See [Before you begin](#before-you-begin) for how to lower it. **How do I add resumable uploads to my own app?** Use the FastPix iOS Uploads SDK directly. See [Which FastPix repo do I need?](#which-fastpix-repo-do-i-need)