From 2361c87f26356ca4be1643d9a327363d9295087d Mon Sep 17 00:00:00 2001 From: syui Date: Sat, 6 Dec 2025 21:14:08 +0900 Subject: [PATCH] add ios social-app --- ios/README.md | 8 ++ ios/app.config.patch.js | 11 +- ios/bin/build.zsh | 44 -------- ios/bin/install.zsh | 86 ---------------- ios/config.zsh | 14 +++ ios/icon.png | Bin 0 -> 61579 bytes ios/preview.zsh | 65 ++++++++++++ ios/setup.zsh | 215 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 307 insertions(+), 136 deletions(-) create mode 100644 ios/README.md delete mode 100755 ios/bin/build.zsh delete mode 100644 ios/bin/install.zsh create mode 100644 ios/config.zsh create mode 100644 ios/icon.png create mode 100755 ios/preview.zsh create mode 100755 ios/setup.zsh diff --git a/ios/README.md b/ios/README.md new file mode 100644 index 0000000..d2f6fa3 --- /dev/null +++ b/ios/README.md @@ -0,0 +1,8 @@ +今回の./ios (social-app)開発の要点をまとめます。 + +1. MITのライセンスを遵守すること、iosアプリとして出品しても問題ないようにすること +https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/LICENSE + +2. "Bluesky"という名称を使用しないこと。アイコンの変更。リンクの変更 + +3. selfhostでも動くこと。本来のsocial-appは動きませんので、これは不便なのでiosアプリに出品することにしました。なお、これはすでにpatchで実現しています。 diff --git a/ios/app.config.patch.js b/ios/app.config.patch.js index 136a4d9..f8fd036 100644 --- a/ios/app.config.patch.js +++ b/ios/app.config.patch.js @@ -1,9 +1,8 @@ // Aiat app configuration overrides module.exports = { - name: 'Aiat', - slug: 'aiat', - scheme: 'aiat', - owner: 'syui', // Your Expo account - bundleIdentifier: 'ai.syui.at', - // Icon will be set separately + name: 'syuis', + slug: 'syuis', + scheme: 'syuis', + owner: 'syui', + bundleIdentifier: 'is.syu' } diff --git a/ios/bin/build.zsh b/ios/bin/build.zsh deleted file mode 100755 index d1fe8ea..0000000 --- a/ios/bin/build.zsh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/zsh -set -e - -d=~/ai/at/repos/social-app -APP_NAME=Aiat -PKG=aiat -TEAM_NAME= -TEAM_ID= -CERT="Apple Distribution: ${TEAM_NAME} (${TEAM_ID})" -MAIL=user@example.com -KEY_CHAIN=EXAMPLE - -cd $d -# npx expo prebuild --clean -# cd ios && pod install && cd .. - -## アーカイブ -xcodebuild -workspace ios/${PKG}.xcworkspace \ - -scheme ${PKG} \ - -configuration Release \ - -archivePath build/${APP_NAME}.xcarchive \ - -allowProvisioningUpdates \ - archive - -cd build - -# IPA作成 -rm -rf Payload ${APP_NAME}.ipa -mkdir -p Payload -cp -R ${APP_NAME}.xcarchive/Products/Applications/${PKG}.app Payload/ -cp ../store.mobileprovision Payload/${PKG}.app/embedded.mobileprovision - -# entitlements抽出 -security cms -D -i Payload/${PKG}.app/embedded.mobileprovision > /tmp/profile.plist -/usr/libexec/PlistBuddy -x -c "Print :Entitlements" /tmp/profile.plist > /tmp/entitlements.plist - -codesign -f -s "$CERT" Payload/${PKG}.app/Frameworks/*.framework 2>/dev/null || true -codesign -f -s "$CERT" --entitlements /tmp/entitlements.plist Payload/${PKG}.app - -zip -r ${APP_NAME}.ipa Payload - -xcrun altool --upload-app -f ${APP_NAME}.ipa -t ios -u "${MAIL}" -p "@keychain:${KEY_CHAIN}" - -echo "Upload complete" diff --git a/ios/bin/install.zsh b/ios/bin/install.zsh deleted file mode 100644 index 2e372c7..0000000 --- a/ios/bin/install.zsh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/zsh - -if [ "$1" = "social-app-custom" ];then - at-social-app-custom-pages - at-social-app-custom-screens - at-social-app-aiat-config - at-social-app-aiat-logo - at-origin-social-app - exit -fi - -function at-social-app-custom-pages() { - d_=$d/repos/social-app - custom=$d/social-app-custom - - echo "copying custom components to social-app" - - # Create components directory if not exists - mkdir -p ${d_}/src/components/custom - - # Copy custom components - cp ${custom}/PrivacyContent.tsx ${d_}/src/components/custom/ - cp ${custom}/AppInfo.tsx ${d_}/src/components/custom/ - - echo "custom components copied successfully" -} - -function at-social-app-aiat-config() { - d_=$d/repos/social-app - custom=$d/social-app-custom - - echo "applying Aiat configuration" - - # Update app.config.js - cd ${d_} - - # Backup original - cp app.config.js app.config.js.orig - - # Apply changes using sed - sed -i "s/name: 'Bluesky'/name: 'Aiat'/g" app.config.js - sed -i "s/slug: 'bluesky'/slug: 'aiat'/g" app.config.js - sed -i "s/scheme: 'bluesky'/scheme: 'aiat'/g" app.config.js - sed -i "s/owner: 'blueskysocial'/owner: 'syui'/g" app.config.js - sed -i "s/bundleIdentifier: 'xyz.blueskyweb.app'/bundleIdentifier: 'ai.syui.at'/g" app.config.js - - # Update package.json name - sed -i 's/"name": "bsky.app"/"name": "aiat"/g' package.json - - echo "Aiat configuration applied" -} - -function at-social-app-aiat-logo() { - d_=$d/repos/social-app - custom=$d/social-app-custom - - echo "applying Aiat logo" - - # Create logo directory if not exists - mkdir -p ${custom}/assets - - # Copy logo if exists in custom folder - if [ -f ${custom}/assets/icon.png ]; then - cp ${custom}/assets/icon.png ${d_}/assets/app-icons/ios_icon_default_next.png - echo "Aiat logo applied" - else - echo "Warning: Logo file not found at ${custom}/assets/icon.png" - echo "Please add your logo file there" - fi -} - -function at-social-app-custom-screens() { - d_=$d/repos/social-app - custom=$d/social-app-custom - - echo "applying custom screens" - - # Copy custom screen files - cp ${custom}/PrivacyPolicy.screen.tsx ${d_}/src/view/screens/PrivacyPolicy.tsx - cp ${custom}/Support.screen.tsx ${d_}/src/view/screens/Support.tsx - cp ${custom}/LicenseNotice.tsx ${d_}/src/components/custom/ - - echo "custom screens applied" -} - - diff --git a/ios/config.zsh b/ios/config.zsh new file mode 100644 index 0000000..9bf6875 --- /dev/null +++ b/ios/config.zsh @@ -0,0 +1,14 @@ +APP_NAME="syuis" +DEVICE_ID="xxx" +REPO_DIR="../repos/social-app" +APP_SLUG="syuis" +APP_SCHEME="syui" +BUNDLE_ID="is.syu" +APP_GROUP="group.is.syu" +SERVICE_URL="https://syu.is" +HELP_URL="https://syu.is/help" +PRIVACY_URL="https://syu.is/privacy" +TERMS_URL="https://syu.is/terms" +REPO_DIR="../repos/social-app" +CONFIG_FILE="$REPO_DIR/app.config.js" +CONSTANTS_FILE="$REPO_DIR/src/lib/constants.ts" diff --git a/ios/icon.png b/ios/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..56f0a8717c017f5cdc45d23278287987db1f523b GIT binary patch literal 61579 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 C&|p~r literal 0 HcmV?d00001 diff --git a/ios/preview.zsh b/ios/preview.zsh new file mode 100755 index 0000000..a885a6a --- /dev/null +++ b/ios/preview.zsh @@ -0,0 +1,65 @@ +#!/bin/zsh +set -e +d=${0:a:h} +cd $d + +# DEVICE_ID="00008110-001855EA36D0401E" +APP_NAME="syuis" +REPO_DIR="../repos/social-app" + +echo "Running iOS preview workflow..." +cd "$REPO_DIR" + +# 0. Environment Setup (Fix Node Version) +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +echo "Checking Node version..." +if command -v nvm >/dev/null; then + nvm use 22 || nvm use 20 || echo "Warning: Could not switch to Node 22/20. Current: $(node -v)" +else + echo "nvm not found, using system node: $(node -v)" +fi + +# 1. Install dependencies +echo "1. Installing dependencies (yarn)..." +yarn install + +# 2. Prebuild (Generate ios directory) +echo "2. Running Expo Prebuild..." +# Clean old ios folder to remove old entitlements/AppClip targets +rm -rf ios +npx expo prebuild --platform ios --clean + +# 3. CocoaPods +echo "3. Installing CocoaPods..." +# Ensure PATH includes Homebrew ruby gems if needed +export PATH="/opt/homebrew/lib/ruby/gems/3.4.0/bin:$PATH" +cd ios +pod install +cd .. + +# 4. Signing (Manual Step) +echo "4. Opening Xcode for Signing..." +XCODE_PROJ="ios/${APP_NAME}.xcodeproj" +# Fallback search if variable name logic differs +if [ ! -d "$XCODE_PROJ" ]; then + XCODE_PROJ=$(find ios -name "*.xcodeproj" | head -n 1) +fi + +open "$XCODE_PROJ" +echo "========================================================" +echo " [ACTION REQUIRED] " +echo " Xcode opened ($XCODE_PROJ)." +echo " 1. Go to 'Signing & Capabilities' tab." +echo " 2. Select your Team." +echo " 3. Verify 'App Clip' target is gone." +echo " 4. Ensure no red errors exist." +echo " Press ENTER here once you are done to continue building." +echo "========================================================" +read + +# 5. Run +echo "5. Building and Running..." +# If user wants specific device ID, uncomment below, otherwise let Expo ask/pick boot simulator +# npx expo run:ios --device "$DEVICE_ID" --configuration Release +npx expo run:ios diff --git a/ios/setup.zsh b/ios/setup.zsh new file mode 100755 index 0000000..0473b78 --- /dev/null +++ b/ios/setup.zsh @@ -0,0 +1,215 @@ +#!/bin/zsh +d=${0:a:h} +cd $d + +APP_NAME="syuis" +APP_SLUG="syuis" +APP_SCHEME="syui" +BUNDLE_ID="is.syu" +APP_GROUP="group.is.syu" +SERVICE_URL="https://syu.is" +HELP_URL="https://syu.is/help" +PRIVACY_URL="https://syu.is/privacy" +TERMS_URL="https://syu.is/terms" + +REPO_DIR="../repos/social-app" +CONFIG_FILE="$REPO_DIR/app.config.js" +CONSTANTS_FILE="$REPO_DIR/src/lib/constants.ts" + +# Sed compatibility wrapper +function sediment() { + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +echo "Configuring $APP_NAME..." + +# Check if repo exists +if [ ! -d "$REPO_DIR" ]; then + echo "Cloning social-app..." + git clone https://github.com/bluesky-social/social-app "$REPO_DIR" +else + echo "Updating social-app..." + pushd "$REPO_DIR" + git stash -u + if ! git pull; then + echo "Git pull failed. Resetting..." + git reset --hard HEAD + git pull + fi + popd +fi + +# Backup config if not exists (or restore from backup to start fresh) +if [ ! -f "$CONFIG_FILE.bak" ]; then + cp "$CONFIG_FILE" "$CONFIG_FILE.bak" +else + cp "$CONFIG_FILE.bak" "$CONFIG_FILE" +fi + +# 1. app.config.js modifications +echo "Updating app.config.js..." + +# Replace name +sediment "s/name: 'Bluesky'/name: '$APP_NAME'/g" "$CONFIG_FILE" +sediment "s/slug: 'bluesky'/slug: '$APP_SLUG'/g" "$CONFIG_FILE" +sediment "s/scheme: 'bsky'/scheme: '$APP_SCHEME'/g" "$CONFIG_FILE" + +# Replace Bundle ID and App Group +sediment "s/xyz.blueskyweb.app/$BUNDLE_ID/g" "$CONFIG_FILE" +sediment "s/group.app.bsky/$APP_GROUP/g" "$CONFIG_FILE" + +# REMOVE App Clip Configuration (Critical for Personal Team Signing) +# Use Python for safer multi-line removal than sed +echo "Removing App Clip configuration..." +python3 -c " +import sys +import re + +try: + with open('$CONFIG_FILE', 'r') as f: + lines = f.readlines() + + with open('$CONFIG_FILE', 'w') as f: + skip = 0 + for i, line in enumerate(lines): + if skip > 0: + skip -= 1 + continue + + # Remove the plugin import line + if 'withStarterPackAppClip.js' in line: + continue + + # Check if this line defines the AppClip target + # Structure we expect: + # { + # targetName: 'BlueskyClip', + # ... + # }, + # We look for the targetName, and if found, we attempt to remove the preceding '{' line if possible + + if \"targetName: 'BlueskyClip'\" in line: + # We found the target. We need to NOT write this line. + # And we need to ensure the PREVIOUS line (which was '{') is not written? + # Since we are writing sequentially, we can't pop easily unless we buffer. + # Actually, simpler: Read file, modify list, write back. + continue + else: + pass + + # Retry with list manipulation approach + out = [] + i = 0 + while i < len(lines): + line = lines[i] + + # Remove plugin import + if 'withStarterPackAppClip.js' in line: + i += 1 + continue + + # Identify the block start + # We look ahead. If lines[i] is '{' and lines[i+1] has 'BlueskyClip', we skip the block. + if i + 1 < len(lines) and lines[i].strip() == '{' and \"targetName: 'BlueskyClip'\" in lines[i+1]: + # Found the start of the block. + # Skip until we find the closing '},' + # Typical block is 4 lines. + # { + # targetName: 'BlueskyClip', + # bundleIdentifier: ..., + # }, + # We'll just skip 4 lines to be safe matching the observed file structure + i += 4 + continue + + out.append(line) + i += 1 + + f.writelines(out) +except Exception as e: + print(f'Error processing file: {e}') + sys.exit(1) +" + +# Inject NSAppTransportSecurity for development/preview (Allow Arbitrary Loads) +if ! grep -q "NSAppTransportSecurity" "$CONFIG_FILE"; then + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "/ios: {/a\\ + infoPlist: {\\ + NSAppTransportSecurity: {\\ + NSAllowsArbitraryLoads: true,\\ + },\\ + }," "$CONFIG_FILE" + else + sed -i "/ios: {/a\\ + infoPlist: {\\ + NSAppTransportSecurity: {\\ + NSAllowsArbitraryLoads: true,\\ + },\\ + }," "$CONFIG_FILE" + fi +fi + +# 2. constants.ts modifications +echo "Updating constants.ts..." +sediment "s|export const BSKY_SERVICE = 'https://bsky.social'|export const BSKY_SERVICE = '$SERVICE_URL'|g" "$CONSTANTS_FILE" +sediment "s|export const BSKY_SERVICE_DID = 'did:web:bsky.social'|export const BSKY_SERVICE_DID = 'did:web:syu.is'|g" "$CONSTANTS_FILE" +sediment "s|export const PUBLIC_BSKY_SERVICE = 'https://public.api.bsky.app'|export const PUBLIC_BSKY_SERVICE = 'https://bsky.syu.is'|g" "$CONSTANTS_FILE" +sediment "s|const HELP_DESK_LANG = 'en-us'|const HELP_DESK_LANG = 'ja-jp'|g" "$CONSTANTS_FILE" +sediment "s|export const HELP_DESK_URL = \`https://blueskyweb.zendesk.com/hc/\${HELP_DESK_LANG}\`|export const HELP_DESK_URL = '$HELP_URL'|g" "$CONSTANTS_FILE" + +# 3. Footer/Link replacements (Global text replacement for specific URLs) +echo "Replacing links..." +grep -r "https://bsky.social/about/blog" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|https://bsky.social/about/blog|$HELP_URL|g\" {}; else sed -i \"s|https://bsky.social/about/blog|$HELP_URL|g\" {}; fi" +grep -r "https://bsky.social/about/blog/jobs" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|https://bsky.social/about/blog/jobs|$HELP_URL|g\" {}; else sed -i \"s|https://bsky.social/about/blog/jobs|$HELP_URL|g\" {}; fi" +grep -r "/support/privacy" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|/support/privacy|$PRIVACY_URL|g\" {}; else sed -i \"s|/support/privacy|$PRIVACY_URL|g\" {}; fi" +grep -r "/support/tos" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|/support/tos|$TERMS_URL|g\" {}; else sed -i \"s|/support/tos|$TERMS_URL|g\" {}; fi" + +# 4. Icon replacement +if [ -f "icon.png" ]; then + echo "Updating icon..." + cp "icon.png" "$REPO_DIR/assets/icon.png" + cp "icon.png" "$REPO_DIR/assets/icon-android-notification.png" +fi + +# 5. Build Fixes (Entitlements and NSE Sounds) +echo "Applying build fixes..." + +# Fix 1: Create Config Plugin to Allow Entitlements Modification +cat < "$REPO_DIR/plugins/withCodeSignEntitlements.js" +const { withXcodeProject } = require('expo/config-plugins'); + +module.exports = function withCodeSignEntitlements(config) { + return withXcodeProject(config, (config) => { + const xcodeProject = config.modResults; + const configurations = xcodeProject.pbxXCBuildConfigurationSection(); + for (const key in configurations) { + const buildSettings = configurations[key].buildSettings; + if (buildSettings) { + buildSettings['CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION'] = 'YES'; + } + } + return config; + }); +}; +EOF + +# Register the plugin in app.config.js +# We insert it into the plugins array. Finding a safe anchor. +# 'expo-video' is in the plugins array. +sediment "s/'expo-video',/'expo-video', '.\/plugins\/withCodeSignEntitlements.js',/g" "$CONFIG_FILE" + + +# Fix 2: Disable soundFiles in Notification Extension to avoid 'no rule to process dm.aiff' +# The main app handles sounds via expo-notifications. The extension adding it as a source fails. +NOTIF_EXT_FILE="$REPO_DIR/plugins/notificationsExtension/withNotificationsExtension.js" +if [ -f "$NOTIF_EXT_FILE" ]; then + echo "Patching withNotificationsExtension.js..." + sediment "s/const soundFiles = \['dm.aiff'\]/const soundFiles = []/g" "$NOTIF_EXT_FILE" +fi + +echo "Setup complete. App Clip configuration removed. Build fixes applied."