Plug in: power cable → HDMI to monitor → USB keyboard & mouse
- No monitor? Use an iPad/iPhone with Sidecar or find a TV with HDMI input
- No keyboard? A Bluetooth keyboard works — hold power button to enter pairing mode
- iPhone as hotspot: Settings → Personal Hotspot → Allow Others to Join
Press the power button on the back. macOS Setup Assistant will guide you through:
- Language & Region selection
- Wi-Fi setup (connect to your home network or iPhone hotspot)
- Accessibility options (skip for now)
- Data & Privacy settings
When prompted, sign in with your existing Apple ID:
System Settings → [Your Name] → iCloud → iCloud Drive → Options
- Turn on Desktop & Documents Folders — instant backup to cloud
- Enable Photos if you want cross-device photo sync
System Settings → Privacy & Security → Security
Set "Allow apps downloaded from" → App Store and identified developers
System Settings → General → Software Update
Install everything. This may take 10–30 minutes and require a restart.
Open Terminal (Applications → Utilities → Terminal) and run:
Enter your Mac password when asked. The install takes 5–10 minutes.
brew install.
Run these two commands after Homebrew installs:
Verify it works:
Verify installs:
Open App Store → search "Xcode" → Install
After install, run the first launch setup:
Accept the license when prompted. This installs iOS simulators and build tools.
On your Raspberry Pi, open terminal and run:
You'll see something like 192.168.1.45 — note this down.
Or use the Tailscale IP which works from anywhere: 100.100.237.123
Tailscale lets Mac and Pi connect securely from anywhere — even different networks.
Open Tailscale from Applications → Sign in with the same account as your Pi.
Now SSH to Pi from Mac using Tailscale IP:
On your Mac, run this to copy the Pi's OpenClaw workspace:
--delete flag to mirror exactly.
Make the Mac a full OpenClaw host:
openclaw init.
This is a game-changer: edit your Pi's files using the full Mac VS Code:
- Open VS Code → Extensions → search "Remote - SSH" → Install
- Press Cmd+Shift+P → "Remote-SSH: Connect to Host"
- Enter:
kreator@100.100.237.123 - VS Code opens the Pi's filesystem on your Mac screen 🚀
You'll see a list of checks. Green ✓ = good, Red ✗ = needs fixing.
Common fixes flutter doctor suggests:
- Xcode license:
sudo xcodebuild -license - CocoaPods:
sudo gem install cocoapods - Android licenses:
flutter doctor --android-licenses
Then in Xcode:
- Xcode → Settings → Platforms
- Download the iOS Simulator (pick latest iOS version)
- This lets you test your app without a real iPhone
Open Android Studio then:
- More Actions → SDK Manager
- Install: Android SDK, SDK Build-Tools, SDK Platform-Tools
- Accept all licenses from terminal:
Type y to accept each license.
Create and run a test project:
In lib/main.dart, replace the body with:
Your pubspec.yaml dependencies section should include:
Edit ios/Runner/Info.plist — add these keys before </dict>:
Edit android/app/src/main/AndroidManifest.xml — add inside <manifest>:
Go to developer.apple.com → Account → Enroll
- Cost: $99 USD/year
- Sign in with:
diawarrior@gmail.com - Approval takes 24–48 hours
- Gives you: App Store distribution, TestFlight, Apple Pay, iCloud, push notifications
developer.apple.com → Certificates, IDs & Profiles → Identifiers → +
- Type: App IDs
- Platform: iOS
- Bundle ID:
com.buildersmusic.clashapp(Explicit) - Enable capabilities: Push Notifications, Sign In with Apple (if needed)
In your Flutter project, open Xcode:
In Xcode → select Runner → Signing & Capabilities:
- Team: Select your developer account
- Bundle Identifier:
com.buildersmusic.clashapp - Version:
1.0.0 - Build:
1
Change the target to "Any iOS Device (arm64)"
In Xcode menu:
- Product → Archive (takes a few minutes to build)
- Organizer window opens → click Distribute App
- Method: App Store Connect
- Options: Leave defaults → click Upload
- Processing takes 5–30 minutes in App Store Connect
flutter build ipa --release then upload the .ipa with Transporter app.
Go to appstoreconnect.apple.com:
- My Apps → + New App
- Name, Bundle ID, SKU, language
- Fill in: Description, Keywords, Support URL, Privacy Policy URL
- Screenshots: required for iPhone 6.5" and 5.5" sizes (use simulator screenshots)
- Select your uploaded Build
- Pricing: Free or set your price
- Click Submit for Review
Go to play.google.com/console
- Sign in with your Google account
- Pay: $25 USD one-time fee (no annual renewal!)
- Fill in developer profile
- Account activation: instant to 48 hours
CRITICAL: Every Android app needs to be signed. Do this ONCE — save the file safely:
Create android/key.properties:
In android/app/build.gradle, add signing config in the android block.
android/key.properties to .gitignore — never commit passwords to git!
Google Play uses .aab (Android App Bundle) — it's smaller and more efficient than .apk.
In play.google.com/console:
- Create app → App name, language, type (app/game), free/paid
- Fill store listing: Short description, Full description
- Add screenshots (phone, tablet if available)
- Add Feature graphic (1024×500px banner)
- Production → Releases → Create release
- Upload your
app-release.aab - Add release notes → Review and Publish
Keep this terminal open, or run it as a background service:
Choose based on your Mac mini's RAM:
In your OpenClaw config file, add:
OpenClaw will now use your FREE local AI instead of paying for Claude/GPT API calls.
Get a beautiful ChatGPT-like interface for your local AI:
Open http://localhost:3000 in your browser → create account → start chatting!
The problem: Your web Clash App uses WebRTC/getUserMedia — this only works in browsers.
When you wrap it in a WebView for native apps:
- iOS: Safari's WebView blocks mic access without native permission grant
- Android: WebView needs special flags to allow mic
- Both: App Store / Play Store may reject WebRTC mic usage in WebViews
The solution: Use the record package for native microphone access.
For real-time clash battles (live streaming audio):
If you're using WebView to load your web Clash App, enable mic access:
onPermissionRequest callback auto-grants mic permission when your web app's JavaScript requests it. This works for modern WebView Flutter package.