Do I need cocoa pods?
Do I need cocoa pods?
Yes, you need CocoaPods for this project, but it's handled automatically for you. Here's what you need to know:
##CocoaPods Usage
The Voltra library includes a .podspec file (ios/Voltra.podspec) which is a CocoaPods specification. This defines the iOS native dependencies needed for the library:
- iOS minimum version: 16.2
- Swift version: 5.9
- Dependencies:
ExpoModulesCore
##How It's Handled
You don't need to manually manage CocoaPods because:
-
Config Plugin Automation: The project uses an Expo config plugin (
app.plugin.js) that automatically sets up the iOS extension targets for you when you run:npx expo prebuild --clean -
Automatic Installation: When you run
npx expo prebuild, it will automatically:- Generate the iOS native code
- Handle CocoaPods installation
- Wire up the necessary extension targets
##Setup Summary
According to the README, to get started you just need to:
- Install the npm package:
npm install voltra - Add the config plugin to your
app.json:{ "expo": { "plugins": ["voltra"] } } - Run:
npx expo prebuild --clean
The prebuild command takes care of CocoaPods for you — you don't need to run pod install manually or interact with CocoaPods directly.
I got this error
Command pod install failed.
└─ Cause: CocoaPods could not find compatible versions for pod "VoltraWidget":
Based on my investigation, here's what I found:
##The Issue
The error "CocoaPods could not find compatible versions for pod 'VoltraWidget'" occurs because:
- VoltraWidget is a local pod - It's defined in
ios/VoltraWidget.podspecin your project, not published to the CocoaPods repository - The config plugin references it - The plugin tries to add it to your extension target via the Podfile with a
:pathreference
##Likely Causes
-
Path resolution problem - The path to the
VoltraWidgetpodspec might not be resolving correctly. The plugin usesexpo-modules-autolinkingto find the module path, which may not be working as expected. -
Missing build step - Make sure you've run
npm installand built the native modules before runningnpx expo prebuild --clean
##Solutions to Try
-
Clean and retry with fresh installation:
# Remove old builds rm -rf node_modules rm -rf example/node_modules npm install npm run build npx expo prebuild --clean -
Check if the Podfile was generated correctly - After running
prebuild, check yourexample/ios/Podfileand look for the widget extension target. The pod reference should look like:pod 'VoltraWidget', :path => "path/to/voltra/ios" -
If CocoaPods cache is stale:
pod repo update pod install --repo-update -
Check iOS compatibility - Make sure your iOS deployment target in your Xcode project is set to 16.2 or higher (required by Voltra)
If this doesn't resolve it, could you share the full error message and the contents of your Podfile after running prebuild? That would help pinpoint the exact issue.
Does this code look ok?
import React from "react"
import { startLiveActivity, stopLiveActivity, updateLiveActivity } from "voltra/client" import { Voltra } from "voltra"
type LivePayload = { halachicTime: string nextZman: string nextZmanTime: string locationLabel?: string }
let currentActivityId: string | null = null
function buildVariants(payload: LivePayload) {
const title = payload.locationLabel ? Zmanim • ${payload.locationLabel} : "Zmanim"
const secondary = payload.nextZman ? ${payload.nextZman} • ${payload.nextZmanTime} : ""
const minimalText = payload.halachicTime.split(" ")[0] || payload.halachicTime
return { lockScreen: ( <Voltra.VStack style={{ padding: 14, borderRadius: 18, backgroundColor: "#101828" }}> <Voltra.Text style={{ color: "#F8FAFC", fontSize: 14, fontWeight: "600" }}>{title}</Voltra.Text> <Voltra.Text style={{ color: "#F8FAFC", fontSize: 26, fontWeight: "800", marginTop: 6 }}> {payload.halachicTime} </Voltra.Text> {secondary ? ( <Voltra.Text style={{ color: "#94A3B8", fontSize: 12, marginTop: 6 }}>{secondary}</Voltra.Text> ) : null} </Voltra.VStack> ), compact: ( <Voltra.VStack style={{ paddingVertical: 4 }}> <Voltra.Text style={{ fontSize: 12, fontWeight: "700" }}>{payload.halachicTime}</Voltra.Text> {payload.nextZmanTime ? <Voltra.Text style={{ fontSize: 10 }}>{payload.nextZmanTime}</Voltra.Text> : null} </Voltra.VStack> ), minimal: <Voltra.Text>{minimalText}</Voltra.Text>, } }
export async function syncHalachicLiveActivity(payload: LivePayload, options: { enabled: boolean }) { if (!options.enabled) { if (currentActivityId) { await stopLiveActivity(currentActivityId, { dismissalPolicy: { after: 10 } }) currentActivityId = null } return }
const variants = buildVariants(payload)
if (!currentActivityId) { currentActivityId = await startLiveActivity(variants, { deepLinkUrl: "zmanim://", dismissalPolicy: { after: 30 }, staleDate: Date.now() + 2 * 60 * 60 * 1000, relevanceScore: 0.8, }) return }
await updateLiveActivity(currentActivityId, variants, { staleDate: Date.now() + 2 * 60 * 60 * 1000, relevanceScore: 0.8, }) }
export async function stopHalachicLiveActivity() { if (currentActivityId) { await stopLiveActivity(currentActivityId, { dismissalPolicy: { after: 10 } }) currentActivityId = null } }
Perfect! Your code looks very good overall. Here's my analysis:
##✅ What's Correct
- Function usage is correct - You're using
startLiveActivity,updateLiveActivity, andstopLiveActivitycorrectly with proper signatures - Variants structure is good - Your
buildVariants()returns properLiveActivityVariantswithlockScreen,compact, andminimalviews - State management is solid - Tracking
currentActivityIdto manage activity lifecycle is the right approach - Options are appropriate - Your options like
deepLinkUrl,dismissalPolicy,staleDate, andrelevanceScoreare all valid
##⚠️ Minor Observations
-
activityNamerecommendation - Consider adding anactivityNameto yourstartLiveActivity()call. This allows you to rebind to the same activity if your app is force-closed and reopened:currentActivityId = await startLiveActivity(variants, { activityName: "halachic-time", // Add this deepLinkUrl: "zmanim://", // ... rest of options }) -
Global state concern - Using a module-level
currentActivityIdvariable works, but be aware that:- If your app is killed and restarted,
currentActivityIdwill benulleven if an activity is still running - The
activityNameoption solves this by letting you query existing activities
- If your app is killed and restarted,
-
Error handling - You might want to add try-catch blocks:
export async function syncHalachicLiveActivity(payload: LivePayload, options: { enabled: boolean }) { try { // ... your code } catch (error) { console.error('Failed to sync halachic live activity:', error) // Handle error appropriately } }
##📋 Suggested Improvement
Here's an enhanced version with activityName:
const ACTIVITY_NAME = 'halachic-time'
export async function syncHalachicLiveActivity(payload: LivePayload, options: { enabled: boolean }) {
if (!options.enabled) {
if (currentActivityId) {
await stopLiveActivity(currentActivityId, { dismissalPolicy: { after: 10 } })
currentActivityId = null
}
return
}
const variants = buildVariants(payload)
if (!currentActivityId) {
currentActivityId = await startLiveActivity(variants, {
activityName: ACTIVITY_NAME, // ← Add this
deepLinkUrl: "zmanim://",
dismissalPolicy: { after: 30 },
staleDate: Date.now() + 2 * 60 * 60 * 1000,
relevanceScore: 0.8,
})
return
}
await updateLiveActivity(currentActivityId, variants, {
staleDate: Date.now() + 2 * 60 * 60 * 1000,
relevanceScore: 0.8,
})
}
Overall, your implementation matches the Voltra API well and should work correctly! 🎉
I got this error
✔ Created native directory
✔ Updated package.json | no changes
[Voltra] Generated Info.plist
[Voltra] Generated Assets.xcassets
[Voltra] ⚠️ Skipping user images: directory does not exist at ./assets/voltra
[Voltra] Generated VoltraWidgetInitialStates.swift with 0 pre-rendered widget states
[Voltra] Generated VoltraWidgetBundle.swift with 0 home screen widgets
[Voltra] Generated nativeLiveActivity.entitlements
» ios: scheme: "ios.infoPlist.CFBundleURLTypes" is set in the config. Ignoring abstract property "scheme": zmanim
✔ Finished prebuild
⚠️ Something went wrong running pod install in the ios directory.
Command pod install failed.
└─ Cause: CocoaPods could not find compatible versions for pod "VoltraWidget":
In Podfile:
VoltraWidget (from ../../../node_modules/.pnpm/voltra@1.0.0_expo@54.0.31_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/voltra/ios)
Specs satisfying the VoltraWidget (from ../../../node_modules/.pnpm/voltra@1.0.0_expo@54.0.31_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/voltra/ios) dependency were found, but they required a higher minimum deployment target.
pod install --repo-update --ansi exited with non-zero code: 1
##Solution
Voltra requires iOS 16.2 or higher. You need to update your project's iOS deployment target to at least 16.2.
###Steps to Fix:
-
Open your
app.jsonand update the iOS platform version:{ "expo": { "ios": { "deploymentTarget": "16.2" }, "plugins": ["voltra"] } } -
Clean and rebuild:
rm -rf ios npx expo prebuild --clean
If you're using a bare React Native project (not Expo), update the deployment target in Xcode:
- Open your
.xcodeprojfile in Xcode - Select your main project
- Go to Build Settings
- Search for Minimum Deployment Target
- Set it to 16.2 for both the main target and the widget extension target
- Try running pod install again:
cd ios pod install --repo-update
That should resolve the CocoaPods error! 🎯
I am using Expo
✔ Created native directory
✔ Updated package.json | no changes
[Voltra] Generated Info.plist
[Voltra] Generated Assets.xcassets
[Voltra] ⚠️ Skipping user images: directory does not exist at ./assets/voltra
[Voltra] Generated VoltraWidgetInitialStates.swift with 0 pre-rendered widget states
[Voltra] Generated VoltraWidgetBundle.swift with 0 home screen widgets
[Voltra] Generated nativeLiveActivity.entitlements
✔ Finished prebuild
⚠️ Something went wrong running pod install in the ios directory.
Command pod install failed.
└─ Cause: CocoaPods could not find compatible versions for pod "VoltraWidget":
In Podfile:
VoltraWidget (from ../../../node_modules/.pnpm/voltra@1.0.0_expo@54.0.31_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/voltra/ios)
Specs satisfying the VoltraWidget (from ../../../node_modules/.pnpm/voltra@1.0.0_expo@54.0.31_react-native@0.81.5_@babel+core@7.28.6_@types+react@19.1.17_react@19.1.0__react@19.1.0/node_modules/voltra/ios) dependency were found, but they required a higher minimum deployment target.
pod install --repo-update --ansi exited with non-zero code: 1
Ah! I see the issue. The example app has deploymentTarget: 17.0 which is fine, but your app likely has a lower deployment target.
Can you share your app.json file? But based on the error, here's what you need to do:
##Fix: Update your app.json
Make sure you have the expo-build-properties plugin configured with at least iOS 16.2:
{
"expo": {
"name": "Your App",
"slug": "your-app-slug",
"plugins": [
"voltra",
[
"expo-build-properties",
{
"ios": {
"deploymentTarget": "16.2"
}
}
]
]
}
}
Key points:
- The
expo-build-propertiesplugin sets the iOS deployment target - Set it to at least 16.2 (or higher like 17.0 is fine too)
- Make sure
voltraplugin comes beforeexpo-build-propertiesin the plugins array
Then try again:
rm -rf ios
npx expo prebuild --clean
If you're still getting the error after this, please share:
- Your
app.jsonfile - The output of:
grep -r "deploymentTarget\|IPHONEOS_DEPLOYMENT_TARGET" ios/(after prebuild)
NO! This is my app.json
{ "expo": { "name": "native", "slug": "native", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", "newArchEnabled": true, "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "updates": { "fallbackToCacheTimeout": 0 }, "assetBundlePatterns": [ "**/*" ], "plugins": [ "expo-router", [ "voltra", { "groupIdentifier": "group.com.zmanim.widget", "deploymentTarget": "26.2", "enablePushNotifications": true } ] ], "ios": { "deploymentTarget": "26.2", "infoPlist": { "CFBundleURLTypes": [ { "CFBundleURLSchemes": [ "zmanim" ] } ], "NSSupportsLiveActivities": true, "NSSupportsLiveActivitiesFrequentUpdates": false, "Voltra_AppGroupIdentifier": "group.com.zmanim.widget" }, "entitlements": { "com.apple.security.application-groups": [ "group.com.zmanim.widget" ] }, "bundleIdentifier": "com.zmanim.native" } } }
END OF POST