iOS Swift 快速开始
- AI 快速开始
- 完整开发指引
准备工作
在开始之前,请确保您已完成以下准备:
- 开通云开发环境:开通云开发环境
- 获取 API 访问凭证:在 CloudBase 控制台 获取环境 ID 和 API 密钥
Client
配置你的 AI 工具以连接 CloudBase 能力 支持本地与托管两种连接方式,详见 连接方式。
步骤 1:安装 / 配置 CloudBase
步骤 2:和 AI 对话
在 AI 对话中依次输入以下内容:
prompt
安装 CloudBase Skills:命令 npx skills add tencentcloudbase/cloudbase-skills -y使用 CloudBase Skills: 使用 CloudBase Skills:在 iOS Swift 应用中集成 CloudBase HTTP API准备工作
在开始之前,请确保您已完成以下准备:
- 开通云开发环境:开通云开发环境
- 获取 API 访问凭证:在 CloudBase 控制台 获取环境 ID 和 API 密钥
更多详情请参考:iOS Swift 完整文档
身份认证
- 短信验证码注册
- 邮箱验证码注册
- 账号密码登录
- 短信验证码登录
- 邮箱验证码登录
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 signUpWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, username: String? = nil, password: String? = nil, captchaToken: String? = nil, completion: @escaping ([String: Any]?) -> Void) {
// 步骤1: 发送邮箱验证码
var body: [String: Any] = [
"email": email,
"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] = [
"email": email,
"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)
}
}
}
}
}
// 使用示例
// signUpWithEmailCode(
// cloudbase: cloudbase,
// email: "user@example.com",
// verificationCode: "123456",
// username: "myusername",
// password: "mypassword"
// ) { result in
// if result != nil {
// print("邮箱注册成功")
// }
// }
func signIn(cloudbase: CloudBaseClient, username: String, password: String, completion: @escaping ([String: Any]?) -> Void) {
// 账号密码登录
cloudbase.request(
method: "POST",
path: "/auth/v1/signin",
body: ["username": username, "password": password]
) { (result: [String: Any]?) in
if let result = result,
let accessToken = result["access_token"] as? String,
let userId = result["sub"] as? String {
print("登录成功! 用户ID: \(userId)")
print("访问令牌: \(String(accessToken.prefix(20)))...")
// 更新访问令牌
cloudbase.updateAccessToken(accessToken)
}
completion(result)
}
}
// 使用示例(async/await)
// Task {
// let result: [String: Any]? = await cloudbase.request(
// method: "POST",
// path: "/auth/v1/signin",
// body: ["username": "your_username", "password": "your_password"]
// )
// if let result = result,
// let accessToken = result["access_token"] as? String {
// // 更新访问令牌
// cloudbase.updateAccessToken(accessToken)
// }
// print(result)
// }
func loginWithPhoneCode(cloudbase: CloudBaseClient, phoneNumber: String, verificationCode: String, captchaToken: String? = nil, completion: @escaping (Bool) -> Void) {
// 步骤1: 发送短信验证码
var body: [String: Any] = [
"phone_number": phoneNumber.hasPrefix("+86") ? phoneNumber : "+86\(phoneNumber)",
"target": "ANY" // "ANY" - 不限制,无论用户是否存在都发送; "USER" - 账号必须存在才发送
]
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(false)
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(false)
return
}
print("验证成功!")
// 步骤3: 使用验证令牌登录
cloudbase.request(
method: "POST",
path: "/auth/v1/signin",
body: [
"phone_number": phoneNumber.hasPrefix("+86") ? phoneNumber : "+86\(phoneNumber)",
"verification_token": verificationToken
]
) { (loginResult: [String: Any]?) in
if let loginResult = loginResult,
let accessToken = loginResult["access_token"] as? String {
print("登录成功!")
cloudbase.updateAccessToken(accessToken)
completion(true)
} else {
print("登录失败")
completion(false)
}
}
}
}
}
// 使用示例
// loginWithPhoneCode(
// cloudbase: cloudbase,
// phoneNumber: "13800138000",
// verificationCode: "123456"
// ) { success in
// if success {
// print("手机号登录成功")
// }
// }
func loginWithEmailCode(cloudbase: CloudBaseClient, email: String, verificationCode: String, captchaToken: String? = nil, completion: @escaping (Bool) -> Void) {
// 步骤1: 发送邮箱验证码
var body: [String: Any] = [
"email": email,
"target": "ANY" // "ANY" - 不限制,无论用户是否存在都发送; "USER" - 账号必须存在才发送
]
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(false)
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(false)
return
}
print("验证成功!")
// 步骤3: 使用验证令牌登录
cloudbase.request(
method: "POST",
path: "/auth/v1/signin",
body: [
"email": email,
"verification_token": verificationToken
]
) { (loginResult: [String: Any]?) in
if let loginResult = loginResult,
let accessToken = loginResult["access_token"] as? String {
print("登录成功!")
cloudbase.updateAccessToken(accessToken)
completion(true)
} else {
print("登录失败")
completion(false)
}
}
}
}
}
// 使用示例
// loginWithEmailCode(
// cloudbase: cloudbase,
// email: "user@example.com",
// verificationCode: "123456"
// ) { success in
// if success {
// 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 getFileUrl(cloudbase: CloudBaseClient, cloudObjectId: String, completion: @escaping (String?) -> Void) {
// 获取云存储文件的临时访问链接
cloudbase.request(
method: "POST",
path: "/v1/storages/get-objects-download-info",
body: [["cloudObjectId": cloudObjectId]]
) { (result: [[String: Any]]?) in
if let result = result, !result.isEmpty,
let downloadUrl = result[0]["downloadUrl"] as? String {
print("文件链接: \(downloadUrl)")
completion(downloadUrl)
} else {
completion(nil)
}
}
}
// 使用示例(async/await)
// Task {
// let result: [[String: Any]]? = await cloudbase.request(
// method: "POST",
// path: "/v1/storages/get-objects-download-info",
// body: [["cloudObjectId": "cloud://xxx.png"]]
// )
// if let downloadUrl = result?.first?["downloadUrl"] as? String {
// print(downloadUrl)
// }
// }
func downloadFile(cloudbase: CloudBaseClient, cloudObjectId: String, savePath: String = "./", completion: @escaping (Bool) -> Void) {
// 下载云存储文件到本地
// 1. 获取下载链接
cloudbase.request(
method: "POST",
path: "/v1/storages/get-objects-download-info",
body: [["cloudObjectId": cloudObjectId]]
) { (result: [[String: Any]]?) in
guard let result = result, !result.isEmpty,
let downloadUrl = result[0]["downloadUrl"] as? String else {
completion(false)
return
}
guard let url = URL(string: downloadUrl) else {
completion(false)
return
}
// 2. 下载文件
let task = URLSession.shared.downloadTask(with: url) { tempUrl, _, error in
if let error = error {
print("下载失败: \(error.localizedDescription)")
completion(false)
return
}
guard let tempUrl = tempUrl else {
completion(false)
return
}
// 3. 确定保存路径
let filename = url.lastPathComponent.components(separatedBy: "?").first ?? "file"
let fileManager = FileManager.default
var fullPath: URL
if savePath.hasSuffix("/") {
fullPath = URL(fileURLWithPath: savePath).appendingPathComponent(filename)
} else {
fullPath = URL(fileURLWithPath: savePath)
}
// 4. 保存文件
do {
if fileManager.fileExists(atPath: fullPath.path) {
try fileManager.removeItem(at: fullPath)
}
try fileManager.moveItem(at: tempUrl, to: fullPath)
print("下载成功! 文件已保存到: \(fullPath.path)")
completion(true)
} catch {
print("下载失败: \(error.localizedDescription)")
completion(false)
}
}
task.resume()
}
}
// 使用示例
// downloadFile(cloudbase: cloudbase, cloudObjectId: "cloud://xxx.png", savePath: "./downloads/") { success in
// print(success)
// }
func deleteFile(cloudbase: CloudBaseClient, cloudObjectIds: Any, completion: @escaping (Bool) -> Void) {
// 删除云存储文件
var ids: [String] = []
if let idString = cloudObjectIds as? String {
ids = [idString]
} else if let idArray = cloudObjectIds as? [String] {
ids = idArray
} else {
print("参数类型错误")
completion(false)
return
}
let data = ids.map { ["cloudObjectId": $0] }
cloudbase.request(
method: "POST",
path: "/v1/storages/delete-objects",
body: data
) { (result: Any?) in
if result != nil {
print("删除成功!")
completion(true)
} else {
completion(false)
}
}
}
// 使用示例(async/await)
// Task {
// let data = [["cloudObjectId": "cloud://xxx.png"]]
// let result: Any? = await cloudbase.request(
// method: "POST",
// path: "/v1/storages/delete-objects",
// body: data
// )
// print(result != nil)
// }
云函数
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 ?? "")")
// }
生图模型通过调用云函数来实现,在生图模型页面点击「一键创建云函数」,函数调用示例如下:
func generateImage(cloudbase: CloudBaseClient, prompt: String, completion: @escaping ([String: Any]?) -> Void) {
// 准备调用参数
let data: [String: Any] = ["prompt": prompt]
// 调用云函数生成图片
cloudbase.request(
method: "POST",
path: "/v1/functions/<YOUR_FUNCTION_NAME>",
body: data
) { (result: [String: Any]?) in
if let result = result {
if let success = result["success"] as? Bool, success {
let imageUrl = result["imageUrl"] as? String ?? ""
let revisedPrompt = result["revised_prompt"] as? String ?? ""
print("生成成功!")
print("图片URL: \(imageUrl)")
print("优化后的提示词: \(revisedPrompt)")
print("注意: 图片URL有效期为24小时")
completion(result)
} else {
let code = result["code"] as? String ?? ""
let message = result["message"] as? String ?? ""
print("生成失败: \(code) - \(message)")
completion(nil)
}
} else {
print("请求失败")
completion(nil)
}
}
}
// 使用示例
// generateImage(cloudbase: cloudbase, prompt: "一只可爱的猫咪在阳光下玩耍") { result in
// if let result = result {
// print("图片生成完成: \(result)")
// }
// }