用内置有线传输帮助页替换飞书外链。
帮助文档改为应用内 WebView 加载本地 HTML,避免依赖外部平台内容。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// WiredCameraTransferHelpDocument.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// 有线相机传输帮助文档(App 内置 HTML),供传输页与历史导入页打开。
|
||||||
|
enum WiredCameraTransferHelpDocument {
|
||||||
|
/// 导航栏标题。
|
||||||
|
static let pageTitle = "帮助文档"
|
||||||
|
|
||||||
|
/// Bundle 内资源名(不含扩展名)。
|
||||||
|
static let resourceName = "WiredCameraTransferHelp"
|
||||||
|
|
||||||
|
/// 返回内置帮助页文件 URL;资源缺失时返回 `nil`。
|
||||||
|
static func bundledURL(in bundle: Bundle = .main) -> URL? {
|
||||||
|
bundle.url(forResource: resourceName, withExtension: "html")
|
||||||
|
}
|
||||||
|
}
|
||||||
208
suixinkan/Resources/WiredCameraTransferHelp.html
Normal file
208
suixinkan/Resources/WiredCameraTransferHelp.html
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-Hans">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||||
|
<title>有线相机传输帮助</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary: #0073FF;
|
||||||
|
--text: #1F2329;
|
||||||
|
--secondary: #646A73;
|
||||||
|
--border: #E5E6EB;
|
||||||
|
--bg: #FFFFFF;
|
||||||
|
--card: #F7F8FA;
|
||||||
|
--tip: #EFF6FF;
|
||||||
|
--warn: #FFF7E8;
|
||||||
|
--warn-text: #AD6800;
|
||||||
|
}
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px 16px 40px;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.65;
|
||||||
|
color: var(--text);
|
||||||
|
background: var(--bg);
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
|
.lead {
|
||||||
|
margin: 0 0 24px;
|
||||||
|
color: var(--secondary);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
margin: 28px 0 12px;
|
||||||
|
padding-left: 10px;
|
||||||
|
border-left: 3px solid var(--primary);
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin: 18px 0 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
p { margin: 0 0 12px; }
|
||||||
|
ol, ul {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
padding-left: 1.35em;
|
||||||
|
}
|
||||||
|
li { margin: 0 0 8px; }
|
||||||
|
li:last-child { margin-bottom: 0; }
|
||||||
|
.card {
|
||||||
|
margin: 12px 0;
|
||||||
|
padding: 14px 14px 12px;
|
||||||
|
background: var(--card);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.card p:last-child,
|
||||||
|
.card ul:last-child,
|
||||||
|
.card ol:last-child { margin-bottom: 0; }
|
||||||
|
.tip {
|
||||||
|
background: var(--tip);
|
||||||
|
border: 1px solid #D6E7FF;
|
||||||
|
}
|
||||||
|
.warn {
|
||||||
|
background: var(--warn);
|
||||||
|
border: 1px solid #FFE4BA;
|
||||||
|
color: var(--warn-text);
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
color: var(--primary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.divider {
|
||||||
|
margin: 28px 0 0;
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: var(--secondary);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
strong { font-weight: 600; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>有线相机传输帮助</h1>
|
||||||
|
<p class="lead">本说明适用于「随心瞰商家版」iPhone 端旅拍相册的有线相机传输功能,帮助你快速连接相机、导入照片并上传到相册。</p>
|
||||||
|
|
||||||
|
<h2>功能简介</h2>
|
||||||
|
<p>通过 USB 线将相机连接到 iPhone 后,可在当前旅拍相册中:</p>
|
||||||
|
<ul>
|
||||||
|
<li>边拍边传:拍摄后自动传入 App,并可按设置自动上传</li>
|
||||||
|
<li>拍后传输:先把照片传入 App,再手动选择上传</li>
|
||||||
|
<li>历史导入:从相机内已有照片中挑选导入</li>
|
||||||
|
<li>相册导入:从手机系统相册导入照片</li>
|
||||||
|
</ul>
|
||||||
|
<div class="card tip">
|
||||||
|
<span class="label">支持品牌</span>
|
||||||
|
<p>当前支持佳能、索尼、尼康等主流相机(具体机型以实际识别结果为准)。连接成功后,状态区会显示相机名称。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>使用前准备</h2>
|
||||||
|
<ol>
|
||||||
|
<li>使用 <strong>iPhone</strong>(仅竖屏使用),并确保手机有足够剩余存储空间。</li>
|
||||||
|
<li>准备原装或质量可靠的 USB 数据线,以及必要的转接头(Lightning / USB-C 按手机接口选择)。</li>
|
||||||
|
<li>相机开机,并确认电量充足;建议使用相机原厂供电或满电电池。</li>
|
||||||
|
<li>如需上传,请保持网络畅通(Wi‑Fi 或蜂窝数据)。</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>连接相机</h2>
|
||||||
|
<ol>
|
||||||
|
<li>打开旅拍相册,进入<strong>有线传输</strong>页面。</li>
|
||||||
|
<li>用数据线将相机连接到 iPhone。</li>
|
||||||
|
<li>若系统弹出「是否允许访问相机 / USB 配件」等授权提示,请选择<strong>允许</strong>。</li>
|
||||||
|
<li>页面状态变为「xxx 已连接」即表示连接成功;若长时间停留在搜索或未连接,可点击<strong>重新连接</strong>,或拔插数据线后重试。</li>
|
||||||
|
</ol>
|
||||||
|
<div class="card warn">
|
||||||
|
<span class="label">注意</span>
|
||||||
|
<p>连接过程中请勿频繁拔插数据线,也不要同时打开电脑读卡软件或其他占用相机 USB 的应用。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>传输模式</h2>
|
||||||
|
<div class="card">
|
||||||
|
<h3>边拍边传</h3>
|
||||||
|
<p>相机处于可实时传输状态时,新拍照片会自动写入当前相册;若开启对应上传逻辑,则会继续上传到云端。</p>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3>拍后传输</h3>
|
||||||
|
<p>照片会先进入 App 本地列表,不会自动上传。你可使用「批量上传」或「指定上传」按需上传。</p>
|
||||||
|
</div>
|
||||||
|
<p>可在页面设置区切换传输模式;切换后对后续新传入的照片生效。</p>
|
||||||
|
|
||||||
|
<h2>页面常用操作</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>重新连接 / 刷新</strong>:未连接时用于重新搜索;已连接时用于刷新当前已传入列表。</li>
|
||||||
|
<li><strong>历史导入</strong>:相机连接成功后可用,从相机存储中挑选历史照片导入当前相册。</li>
|
||||||
|
<li><strong>批量上传</strong>:进入多选模式,勾选照片后上传选中项。</li>
|
||||||
|
<li><strong>指定上传</strong>:可一键上传「所有未上传照片」或「今日拍摄照片」。</li>
|
||||||
|
<li><strong>相册导入</strong>:从手机系统相册选择图片导入当前旅拍相册。</li>
|
||||||
|
<li><strong>时间轴</strong>:左侧时间导航可快速定位到某一时间段的照片。</li>
|
||||||
|
</ul>
|
||||||
|
<p>列表支持「全部 / 已上传 / 失败」筛选,失败项可按提示重试。</p>
|
||||||
|
|
||||||
|
<h2>索尼相机说明</h2>
|
||||||
|
<p>索尼相机在不同 USB 模式下,行为和列表内容会有差异:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>边拍边传</strong>:通常需要进入相机支持的远程/PC Remote 类连接模式,以便拍摄后及时传到手机。</li>
|
||||||
|
<li><strong>历史导入</strong>:若提示无照片或列表为空,请将相机 USB 连接模式切换为 <strong>MTP</strong>(或「仅传照片 / Mass Storage / MTP」等类似选项,以机身为准),然后重新插拔连接并再次进入历史导入。</li>
|
||||||
|
</ul>
|
||||||
|
<div class="card tip">
|
||||||
|
<span class="label">切换提示</span>
|
||||||
|
<p>多数索尼机身路径类似:菜单 → 网络/连接 → USB 连接 → 选择 MTP。具体名称因机型而异,请以相机说明书为准。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>常见问题</h2>
|
||||||
|
<h3>1. 一直显示「未连接 USB」或「正在搜索」?</h3>
|
||||||
|
<ul>
|
||||||
|
<li>检查数据线与转接头是否支持数据传输(仅充电线无法识别相机)。</li>
|
||||||
|
<li>确认相机已开机,并处于可被电脑/手机识别的 USB 模式。</li>
|
||||||
|
<li>尝试拔掉重插,或点击「重新连接」。</li>
|
||||||
|
<li>重启相机与 App 后再试。</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>2. 已连接但看不到新拍照片?</h3>
|
||||||
|
<ul>
|
||||||
|
<li>确认当前传输出入的是正确的旅拍相册。</li>
|
||||||
|
<li>边拍边传模式下,请保持本页在前台,并避免同时进行历史导入。</li>
|
||||||
|
<li>索尼机型请核对 USB/远程模式是否匹配当前用途。</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>3. 上传失败怎么办?</h3>
|
||||||
|
<ul>
|
||||||
|
<li>检查网络是否稳定,必要时切换 Wi‑Fi。</li>
|
||||||
|
<li>确认手机存储空间充足。</li>
|
||||||
|
<li>在「失败」Tab 中查看失败照片,并重试上传。</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>4. 历史导入打开后没有照片?</h3>
|
||||||
|
<ul>
|
||||||
|
<li>相机存储卡中确实要有可识别的照片文件。</li>
|
||||||
|
<li>索尼请切换到 MTP 模式后重试。</li>
|
||||||
|
<li>关闭历史导入页,回到传输页重新连接后再进入。</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>5. 连接中提示没有权限?</h3>
|
||||||
|
<ul>
|
||||||
|
<li>请在系统弹窗中允许访问相机或相关配件。</li>
|
||||||
|
<li>若曾点过拒绝,可到 iPhone「设置」中为「随心瞰商家版」重新开启相关权限,或重新插拔设备触发授权。</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr class="divider" />
|
||||||
|
<p class="footer">随心瞰商家版 · 有线相机传输帮助。若上述步骤仍无法解决,请保留机型、连接线类型与报错截图,联系客服处理。</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -7,7 +7,7 @@ import SnapKit
|
|||||||
import UIKit
|
import UIKit
|
||||||
import WebKit
|
import WebKit
|
||||||
|
|
||||||
/// 协议 H5 页面,使用应用内 WebView 展示关于我们、用户协议和隐私政策。
|
/// 应用内 WebView 页面,用于展示协议 H5、内置帮助 HTML 等文档内容。
|
||||||
final class AgreementWebViewController: BaseViewController {
|
final class AgreementWebViewController: BaseViewController {
|
||||||
private let pageTitle: String
|
private let pageTitle: String
|
||||||
private let url: URL
|
private let url: URL
|
||||||
@ -37,8 +37,16 @@ final class AgreementWebViewController: BaseViewController {
|
|||||||
view.addSubview(loadingIndicator)
|
view.addSubview(loadingIndicator)
|
||||||
loadingIndicator.hidesWhenStopped = true
|
loadingIndicator.hidesWhenStopped = true
|
||||||
loadingIndicator.startAnimating()
|
loadingIndicator.startAnimating()
|
||||||
|
loadContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadContent() {
|
||||||
|
if url.isFileURL {
|
||||||
|
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
|
||||||
|
} else {
|
||||||
webView.load(URLRequest(url: url))
|
webView.load(URLRequest(url: url))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func setupConstraints() {
|
override func setupConstraints() {
|
||||||
webView.snp.makeConstraints { make in
|
webView.snp.makeConstraints { make in
|
||||||
|
|||||||
@ -293,8 +293,11 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func helpTapped() {
|
@objc private func helpTapped() {
|
||||||
guard let url = URL(string: "https://sharesky.feishu.cn/wiki/CaAhwl3Gnin4Kqk0BVocK3SGnab?from=from_copylink") else { return }
|
guard let url = WiredCameraTransferHelpDocument.bundledURL() else { return }
|
||||||
UIApplication.shared.open(url)
|
navigationController?.pushViewController(
|
||||||
|
AgreementWebViewController(title: WiredCameraTransferHelpDocument.pageTitle, url: url),
|
||||||
|
animated: true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -777,8 +777,14 @@ final class WiredCameraTransferViewController: BaseViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func helpTapped() {
|
@objc private func helpTapped() {
|
||||||
guard let url = URL(string: "https://sharesky.feishu.cn/wiki/CaAhwl3Gnin4Kqk0BVocK3SGnab?from=from_copylink") else { return }
|
guard let url = WiredCameraTransferHelpDocument.bundledURL() else {
|
||||||
UIApplication.shared.open(url)
|
showToast("帮助文档暂不可用")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigationController?.pushViewController(
|
||||||
|
AgreementWebViewController(title: WiredCameraTransferHelpDocument.pageTitle, url: url),
|
||||||
|
animated: true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func presentPhotoPreview(_ item: TravelAlbumOTGPhotoItem) {
|
private func presentPhotoPreview(_ item: TravelAlbumOTGPhotoItem) {
|
||||||
|
|||||||
33
suixinkanTests/WiredCameraTransferHelpDocumentTests.swift
Normal file
33
suixinkanTests/WiredCameraTransferHelpDocumentTests.swift
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// WiredCameraTransferHelpDocumentTests.swift
|
||||||
|
// suixinkanTests
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import suixinkan
|
||||||
|
|
||||||
|
/// 有线相机传输内置帮助文档资源测试。
|
||||||
|
final class WiredCameraTransferHelpDocumentTests: XCTestCase {
|
||||||
|
func testBundledHelpHTMLExists() {
|
||||||
|
let url = WiredCameraTransferHelpDocument.bundledURL()
|
||||||
|
XCTAssertNotNil(url)
|
||||||
|
XCTAssertEqual(url?.pathExtension, "html")
|
||||||
|
XCTAssertTrue(url?.lastPathComponent.hasPrefix(WiredCameraTransferHelpDocument.resourceName) == true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBundledHelpHTMLContainsCoreSections() throws {
|
||||||
|
let url = try XCTUnwrap(WiredCameraTransferHelpDocument.bundledURL())
|
||||||
|
let html = try String(contentsOf: url, encoding: .utf8)
|
||||||
|
XCTAssertTrue(html.contains("有线相机传输帮助"))
|
||||||
|
XCTAssertTrue(html.contains("连接相机"))
|
||||||
|
XCTAssertTrue(html.contains("边拍边传"))
|
||||||
|
XCTAssertTrue(html.contains("拍后传输"))
|
||||||
|
XCTAssertTrue(html.contains("历史导入"))
|
||||||
|
XCTAssertTrue(html.contains("索尼相机说明"))
|
||||||
|
XCTAssertTrue(html.contains("常见问题"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPageTitle() {
|
||||||
|
XCTAssertEqual(WiredCameraTransferHelpDocument.pageTitle, "帮助文档")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user