跳到主要内容

iOS Swift 快速开始

准备工作

在开始之前,请确保您已完成以下准备:

  1. 开通云开发环境开通云开发环境
  2. 获取 API 访问凭证:在 CloudBase 控制台 获取环境 ID 和 API 密钥

更多详情请参考:iOS Swift 完整文档

添加 CloudBase AI 开发插件

可选:如果你使用 AI 编程助手(如 Cursor、Claude Code、CodeBuddy 等)进行开发,建议先完成本步骤,让 AI 具备 CloudBase 开发能力。

复制 AI Prompt 粘贴到 AI IDE

在 AI 对话中输入:

帮我把 CloudBase 接好,按下面做:
1. 打开 https://docs.cloudbase.net/skill.md,按说明完成接入。
2. 接入完成后告诉我,并建议最相关的下一步。

查看 skill.md →

使用 Skills 开发

对 AI 说:

使用 CloudBase Skills:在 iOS Swift 应用中集成 CloudBase HTTP API

Skills 使用文档 →

也可以手动安装 CloudBase Skills:

npx skills add tencentcloudbase/cloudbase-skills -y

身份认证

func signUpWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, username: String? = nil, password: String? = nil, captchaToken: String? = nil, completion: @escaping ([String: Any]?) -> Void) {
// 步骤1: 发送短信验证码
var body: [String: Any] = [
"phone_number": phoneNumber.hasPrefix("+86") ? phoneNumber : "+86\(phoneNumber)",
"target": "NON_USER" // "NON_USER" - 账号不存在才发送; "ANY" - 不限制
]

var headers: [String: String] = [:]
if let token = captchaToken {
headers["x-captcha-token"] = token
}

cloudbase.request(
method: "POST",
path: "/auth/v1/verification",
body: body,
customHeaders: headers
) { (sendResult: [String: Any]?) in
guard let sendResult = sendResult,
let verificationId = sendResult["verification_id"] as? String else {
print("发送验证码失败")
completion(nil)
return
}

print("验证码发送成功! ID: \(verificationId)")

// 步骤2: 验证验证码
cloudbase.request(
method: "POST",
path: "/auth/v1/verification/verify",
body: [
"verification_id": verificationId,
"verification_code": verificationCode
]
) { (verifyResult: [String: Any]?) in
guard let verifyResult = verifyResult,
let verificationToken = verifyResult["verification_token"] as? String else {
print("验证码错误")
completion(nil)
return
}

print("验证成功!")

// 步骤3: 使用验证令牌注册
var signUpBody: [String: Any] = [
"phone_number": phoneNumber.hasPrefix("+86") ? phoneNumber : "+86\(phoneNumber)",
"verification_token": verificationToken
]

// 可选:添加用户名和密码
if let username = username {
signUpBody["username"] = username
}
if let password = password {
signUpBody["password"] = password
}

cloudbase.request(
method: "POST",
path: "/auth/v1/signup",
body: signUpBody
) { (signUpResult: [String: Any]?) in
if let signUpResult = signUpResult,
let accessToken = signUpResult["access_token"] as? String,
let userId = signUpResult["sub"] as? String {
print("注册成功! 用户ID: \(userId)")
print("访问令牌: \(String(accessToken.prefix(20)))...")

// 更新访问令牌
cloudbase.updateAccessToken(accessToken)
completion(signUpResult)
} else {
print("注册失败")
completion(nil)
}
}
}
}
}

// 使用示例
// signUpWithPhoneCode(
// cloudbase: cloudbase,
// phoneNumber: "13800138000",
// verificationCode: "123456",
// username: "myusername",
// password: "mypassword"
// ) { result in
// if result != nil {
// print("手机号注册成功")
// }
// }

云存储

func uploadFile(cloudbase: CloudBaseClient, filePath: String, objectId: String? = nil, completion: @escaping ([String: String]?) -> Void) {
// 上传文件到云存储
guard let fileUrl = URL(string: filePath),
let fileData = try? Data(contentsOf: fileUrl) else {
print("文件不存在: \(filePath)")
completion(nil)
return
}

let filename = fileUrl.lastPathComponent
let timestamp = Int(Date().timeIntervalSince1970 * 1000)
let finalObjectId = objectId ?? "uploads/\(timestamp)-\(filename)"

// 1. 获取上传信息
cloudbase.request(
method: "POST",
path: "/v1/storages/get-objects-upload-info",
body: [["objectId": finalObjectId]]
) { (uploadInfo: [[String: Any]]?) in
guard let uploadInfo = uploadInfo, !uploadInfo.isEmpty else {
completion(nil)
return
}

let info = uploadInfo[0]
guard let uploadUrl = info["uploadUrl"] as? String,
let authorization = info["authorization"] as? String,
let token = info["token"] as? String,
let cloudObjectMeta = info["cloudObjectMeta"] as? String else {
completion(nil)
return
}

// 2. 上传文件
guard let url = URL(string: uploadUrl) else {
completion(nil)
return
}

var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.setValue(authorization, forHTTPHeaderField: "Authorization")
request.setValue(token, forHTTPHeaderField: "X-Cos-Security-Token")
request.setValue(cloudObjectMeta, forHTTPHeaderField: "X-Cos-Meta-Fileid")
request.httpBody = fileData

let task = URLSession.shared.dataTask(with: request) { _, response, error in
if let error = error {
print("文件上传失败: \(error.localizedDescription)")
completion(nil)
return
}

guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("文件上传失败")
completion(nil)
return
}

let result = [
"cloudObjectId": info["cloudObjectId"] as? String ?? "",
"downloadUrl": info["downloadUrl"] as? String ?? "",
"objectId": finalObjectId
]

print("文件上传成功:")
print("- 对象ID: \(result["objectId"] ?? "")")
print("- 下载URL: \(result["downloadUrl"] ?? "")")

completion(result)
}

task.resume()
}
}

// 使用示例
// uploadFile(cloudbase: cloudbase, filePath: "./example.jpg") { result in
// print(result)
// }

云函数

func callFunction(cloudbase: CloudBaseClient, functionName: String, data: [String: Any]? = nil, completion: @escaping ([String: Any]?) -> Void) {
// 调用云函数
cloudbase.request(
method: "POST",
path: "/v1/functions/\(functionName)",
body: data ?? [:]
) { (result: [String: Any]?) in
if let result = result {
print("云函数调用结果: \(result)")
}
completion(result)
}
}

// 使用示例(async/await)
// Task {
// let result: [String: Any]? = await cloudbase.request(
// method: "POST",
// path: "/v1/functions/{%FUNCTION_NAME%}",
// body: [:]
// )
// print(result)
// }

大模型

func streamText(cloudbase: CloudBaseClient, model: String, subModel: String, messages: [[String: String]], completion: @escaping (String?) -> Void) {
// 流式文本生成
let payload: [String: Any] = [
"model": subModel,
"messages": messages,
"stream": true
]

guard let url = URL(string: "\(cloudbase.baseUrl)/v1/ai/\(model)/chat/completions") else {
completion(nil)
return
}

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("text/event-stream", forHTTPHeaderField: "Accept")
request.setValue("Bearer \(cloudbase.accessToken)", forHTTPHeaderField: "Authorization")

do {
request.httpBody = try JSONSerialization.data(withJSONObject: payload)
} catch {
print("JSON序列化失败: \(error)")
completion(nil)
return
}

let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("AI 调用失败: \(error.localizedDescription)")
completion(nil)
return
}

guard let data = data,
let responseString = String(data: data, encoding: .utf8) else {
completion(nil)
return
}

print("AI 流式响应:")
var fullContent = ""

let lines = responseString.components(separatedBy: "\n")
for line in lines {
if line.hasPrefix("data: ") {
let dataStr = String(line.dropFirst(6))
if dataStr.trimmingCharacters(in: .whitespaces) != "[DONE]" {
if let data = dataStr.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let choices = json["choices"] as? [[String: Any]],
let delta = choices.first?["delta"] as? [String: Any],
let content = delta["content"] as? String {
print(content, terminator: "")
fullContent += content
}
}
}
}

print()
completion(fullContent)
}

task.resume()
}

// 使用示例
// streamText(
// cloudbase: cloudbase,
// model: "{%AI_MODEL_NAME%}",
// subModel: "{%AI_SUB_MODEL_NAME%}",
// messages: [
// ["role": "system", "content": "请严格按照七言绝句或七言律诗的格律要求创作"],
// ["role": "user", "content": "春天"]
// ]
// ) { response in
// print("\n完整回复: \(response ?? "")")
// }