Skip to content

Repository files navigation

TapBB

一个极简的双端互动问答应用。iPhone 端发送带选项的问题,对方 Apple Watch 震动后抬腕即可直接点击作答,或在 iPhone 上通过灵动岛 / 长按通知直接回答,全程不需要打开 App


体验流程

A 在 iPhone 发送问题 + 选项(可选择哪些选项高亮蓝色)
        ↓
B 的 Apple Watch 震动 / iPhone 灵动岛弹出或弹通知
        ↓
B 直接点选作答(Watch 抬腕 / iPhone 灵动岛点选 / 长按通知)
        ↓
A 收到"对方已回答"通知(显示问题和选项)

技术栈

层级 技术
后端 Go · Gin · MySQL · APNs
推送 APNs HTTP/2(sideshow/apns2),支持 Push-to-Start Live Activity
iPhone SwiftUI · async/await · StoreKit 2 · ActivityKit
Apple Watch SwiftUI · WKNotificationScene · 独立登录
iPhone 通知 Notification Content Extension(长按直接回答)
灵动岛 Live Activity Widget Extension · Push-to-Start · LiveActivityIntent
登录同步 WatchConnectivity(iPhone → Watch 传 JWT+userId)+ Watch 独立登录
认证 JWT(7 天有效期)
邮件 标准 SMTP(默认 Gmail,可换任意服务商)
项目管理 XcodeGen(project.yml 生成 .xcodeproj
部署 Rocky Linux 9 · Nginx · Cloudflare

目录结构

TapBB/
├── TapBB.xcodeproj                  # 由 XcodeGen 生成,不要手动编辑
├── project.yml                      # XcodeGen 项目配置(所有 target 定义)
├── TapBB/                           # iPhone App
├── TapBBWatch Watch App/            # Watch App
├── TapBBNotification/               # iPhone 通知扩展(交互式回答)
├── TapBBLiveActivity/               # 灵动岛 Widget Extension
├── Shared/                          # 主 App 与灵动岛共享代码(ActivityAttributes + LiveActivityIntents)
├── backend/                         # Go 后端
│   ├── main.go
│   ├── config/
│   ├── handlers/
│   ├── models/
│   ├── middleware/
│   ├── push/
│   ├── email/
│   └── apitest/                     # 集成测试
├── deploy/
│   ├── nginx.conf                   # Nginx 反向代理配置
│   └── .env.production              # 生产环境变量模板
├── tests/
│   ├── docker-compose.yml           # 测试用 MySQL(端口 13306)
│   ├── .env.test
│   ├── run.sh
│   ├── watch_notification_test.apns
│   └── iphone_notification_test.apns
├── docker-compose.dev.yml           # 本地开发 MySQL
├── Makefile
└── .env                             # 本地环境变量(不提交 git)

本地开发

# 启动 MySQL
docker compose -f docker-compose.dev.yml up -d

# 建表
make migrate

# 启动后端
make dev   # 监听 :8080

编译

make build-all
# 输出:
#   bin/tapbb-server-linux-amd64
#   bin/tapbb-server-linux-arm64
#   bin/tapbb-server-darwin-arm64
#   bin/tapbb-server-windows-amd64.exe

生产部署

服务器运行目录只需两个文件:

/你的目录/
├── tapbb-server   # 二进制(linux/amd64 或 arm64)
└── .env           # 环境变量

步骤:

# 1. 编译
make build-all

# 2. 上传二进制
scp bin/tapbb-server-linux-amd64 服务器:/你的目录/tapbb-server

# 3. 建表(首次)或迁移(新字段)— 二进制直接执行 migrate 子命令
/你的目录/tapbb-server migrate

# 4. 启动
/你的目录/tapbb-server

Nginx 配置(/etc/nginx/conf.d/tapbb.conf):

server {
    listen 80;
    server_name tapbb.zgentime.com;

    location / {
        proxy_pass         http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo nginx -t && sudo systemctl reload nginx

Cloudflare 负责 HTTPS,Nginx 只做反向代理转发到 :8080


环境变量

PORT=8080
JWT_SECRET=至少32位随机字符串

# 数据库
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=tapbb_user
DB_PASSWORD=密码
DB_NAME=tapbb

# SMTP(留空 SMTP_PASSWORD 则跳过邮件发送,默认 Gmail)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_PASSWORD=xxxx xxxx xxxx xxxx
EMAIL_FROM=your@gmail.com

# APNs(留空则跳过推送)
APNS_KEY_PATH=./AuthKey_XXXXXXXXXX.p8
APNS_KEY_ID=XXXXXXXXXX
APNS_TEAM_ID=XXXXXXXXXX
APNS_TOPIC=com.zgentime.TapBB
APNS_SANDBOX=true              # Xcode 开发签名用,上线后删掉

APP_BASE_URL=https://tapbb.zgentime.com

生产环境模板见 deploy/.env.production


模拟器测试通知

# Watch 通知(Watch 模拟器必须在表盘界面)
xcrun simctl push <watch-uuid> com.zgentime.TapBBWatch.watchkitapp tests/watch_notification_test.apns

# iPhone 通知(长按展开可直接回答)
xcrun simctl push <iphone-uuid> com.zgentime.TapBB tests/iphone_notification_test.apns

集成测试

bash tests/run.sh

独立 Docker MySQL(端口 13306),测试后自动销毁。


API 概览

除注册、登录、邮箱验证、忘记/重置密码外,所有接口均需 Authorization: Bearer <token>

方法 路径 说明
POST /auth/register 邮箱注册(含 username 字段)
POST/GET /auth/verify-email 验证邮箱(GET 供邮件链接直接跳转)
POST /auth/login 登录,返回 token + user
POST /auth/resend-verification 重新发送验证邮件
POST /auth/forgot-password 发送重置密码邮件
POST /auth/reset-password 重置密码
POST /auth/change-password 修改密码(需当前密码)
POST /auth/change-email 修改邮箱(需密码验证)
POST /auth/change-nickname 修改昵称
POST /auth/change-username 修改用户名(唯一,正则 ^[a-z0-9_]{3,20}$
POST /device/register 注册 APNs device token(platform: iphone/watch/liveactivity)
GET /friend/search?q= 搜索用户
POST /friend/request 发送好友请求
GET /friend/sent 已发出的好友请求
DELETE /friend/request/:id 撤销好友请求
POST /friend/respond 接受 / 拒绝好友请求
GET /friend/list 好友列表(含 alias)
GET /friend/pending 待处理好友请求(含昵称)
PUT /friend/:id/alias 设置好友备注
DELETE /friend/:id 删除好友
POST /message/send 发送问题(2~4 选项)
POST /message/reply 回传答案
GET /message/history 历史记录(分页)
GET /message/:id 消息详情

开发进度

  • Go 后端:用户系统 · 好友 · 消息 · APNs · 标准 SMTP 邮件
  • 消息过期定时任务(每小时,24 小时后标记 expired)
  • 集成测试框架
  • Watch App:通知直接回答 · 历史记录 · 消息详情回答 · 独立登录
  • iPhone App:登录 · 好友 · 发送 · 历史 · 消息详情回答 · 设置 · Tip Jar
  • iPhone 通知扩展:长按通知直接回答(Notification Content Extension)
  • 账号管理:修改昵称 · 用户名 · 邮箱 · 密码
  • 好友增强:备注 · 已发请求 · 撤销请求
  • WatchConnectivity JWT+userId 同步(含自动重推)
  • 选项高亮(highlight_indices 多选,星标图标)
  • 四平台编译
  • 生产部署(Rocky Linux 9 · Nginx · Cloudflare · tapbb.zgentime.com)
  • 全面代码审查 + 安全修复(后端 15 项 + iOS 11 项)
  • APNs 真机联调(iPhone 推送 + 交互式通知回答 + 回答通知)
  • Xcode Capabilities(Push Notifications · Time Sensitive)
  • 历史记录搜索(本地过滤问题/选项)
  • 好友搜索/添加分离(搜索过滤好友列表 + 独立添加好友入口)
  • iOS 26 Liquid Glass 搜索栏(.searchToolbarBehavior(.minimize)
  • 发送页 UI 优化(星标高亮 · 键盘发送键 · 滚动收键盘)
  • 灵动岛 / Live Activity(Push-to-Start 远程启动 · 灵动岛内直接回答/关闭)
  • XcodeGen 项目管理(project.yml 定义所有 target)
  • 上线

About

原App Store项目,现已开源

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages