Pure Swift SDK BmobSwiftSDK For iOS 15+ / macOS 12+, install using Swift Package Manager or CocoaPods, with the API centered on async/await、Bmob.initialize(appKey:)、BmobObject、BmobQuery .
If the project uses the older Objective-C BmobSDK、BmobSDK.xcframework, a Bridging Header, or saveInBackgroundWithResultBlock, read instead bmob-database-ios。
Core Principles
- First confirm the SDK form: the package name of the pure Swift SDK is
BmobSwiftSDK, and the import module is usuallyimport BmobSDK; the old iOS SDK is an Objective-C framework + Bridging Header. - Minimum environment:Xcode 15.0+、Swift 5.9+、iOS 15.0+、macOS 12.0+。
- Initialization is asynchronous: start early
try await Bmob.initialize(appKey:); check if necessary before business requestsawait Bmob.isReady。 - Data tables use by default
BmobObject(className:): fields are read and written via subscripts, and updates / deletions must includeobjectId。 - Queries use chained
BmobQuery:whereKey、order、limit、skip、includeKeyall return query, and finallytry await find()/get(objectId:)。 - Production domains must be set before initialization: for private cloud or registered domains use
Bmob.resetDomain(...), in the order beforeinitialize.
Security Checklist
- Examples only include
"YOUR_APP_KEY"/"your-application-id", do not commit real AppKeys. - The client must not carry the Master Key; when management capabilities are needed, switch to the server side, REST management scripts, or MCP.
- Set an ACL when writing to business tables (such as
BmobACL), to avoid default permissions causing arbitrary users to read and write. - User passwords are only handled through the
BmobUserregister, login, and change-password APIs; do not update them as ordinary fields. - Before file upload, confirm the source, size, and MIME type; do not write local absolute paths into business tables.
- Before release, confirm
resetDomainuses a registered/private cloud domain, and that the call order is earlier than initialization.
Quick Start
Installation
Swift Package Manager:
dependencies: [
.package(url: "https://github.com/bmob/BmobSwiftSDK", from: "1.0.6")
],
targets: [
.target(name: "YourApp", dependencies: [
.product(name: "BmobSDK", package: "BmobSwiftSDK")
])
]
CocoaPods:
platform :ios, '15.0'
use_frameworks!
target 'YourApp' do
pod 'BmobSwiftSDK', '~> 1.0.6'
end
Initialization
import SwiftUI
import BmobSDK
@main
struct MyApp: App {
init() {
Task {
do {
// 私有云或备案域名必须在 initialize 前设置:
// Bmob.resetDomain("https://your-private-cloud.com")
try await Bmob.initialize(appKey: "YOUR_APP_KEY")
} catch {
print("Bmob 初始化失败: \(error)")
}
}
}
var body: some Scene {
WindowGroup { ContentView() }
}
}
Single-record CRUD
// 新增
let note = BmobObject(className: "Note")
note["title"] = "我的第一条笔记"
note["content"] = "Hello Bmob!"
note["score"] = 100
try await note.save()
print(note.objectId ?? "")
// 查询单条
let query = BmobQuery(className: "Note")
let fetched = try await query.get(objectId: "abc123")
print(fetched["title"] ?? "")
// 更新
let updating = BmobObject(className: "Note", data: ["objectId": "abc123"])
updating["content"] = "更新后的内容"
try await updating.update()
// 删除
let deleting = BmobObject(className: "Note", data: ["objectId": "abc123"])
try await deleting.delete()
Conditional Queries and Relations
let query = BmobQuery(className: "Note")
.whereKey("score", greaterThan: 80)
.whereKey("author", equalTo: BmobPointer(className: "_User", objectId: "user123"))
.includeKey("author")
.order(byDescending: "createdAt")
.limit(10)
let notes = try await query.find()
User / File / Cloud Function Quick Reference
// 用户
let user = BmobUser()
user.username = "testuser"
user.password = "password123"
try await user.signUp()
let loggedIn = try await BmobUser.login(username: "testuser", password: "password123")
// 文件(上传走加密客户端协议 POST /8/files;成功后可读 file.url / file.cdn)
let file = BmobFile(data: imageData, filename: "avatar.jpg", mimeType: "image/jpeg")
try await file.upload { progress in
print("上传进度: \(Int(progress * 100))%")
}
// 删除:上传后的实例可直接 delete();仅凭 URL 重建时请传入上传响应里的 cdn(如 "aliyun")
// let again = BmobFile(url: file.url!, cdn: file.cdn)
// try await again?.delete()
// 云函数
let result = try await BmobCloud.run(function: "hello", params: ["name": "Swift"])
Cloud Function Parameters (Known Behavior)
Known behavior: the Bmob server converts all values of cloud function parameters to strings before passing them into
request.body, so in the cloud functiontypeof(param)is always"string". Types such as Int/Bool/Array/Dict are all serialized into string form (such as42→"42"、true→"true"、[1,2,3]→"[1,2,3]"). This is a design behavior of the Bmob backend, not an SDK bug. If you need to use a specific type in a cloud function, parse it manually inside the cloud function (such asparseInt(request.body.name)、JSON.parse(request.body.items))。
Client params can pass native Swift types, but the cloud function side always handles them as strings; when writing cloud functions or doing integration testing, do not assume that request.body is still a number / boolean / object.
This behavior applies to scenarios where cloud functions are called via POST through encrypted client SDKs such as Android, iOS, and Swift.
FAQ
For cross-platform issues see shared/faq.md. Swift-specific judgment:
- Seeing
Bridging-Header.h、#import <BmobSDK/Bmob.h>、saveInBackground: this is the old iOS SDK, readbmob-database-ios。 - Seeing
BmobSwiftSDK、import BmobSDK、try await note.save(): this is the pure Swift SDK, use this skill.
Anti-patterns
See shared/anti-patterns.md. Skill-specific:
- Mixing the old iOS SDK's
setObject(_:forKey:)、saveInBackground、Bmob.register(withAppKey:)into pure Swift SDK examples. - Writing the order before and after
Bmob.initializebackwards:resetDomainmust be earlier. - Forgetting
objectIdand callingupdate()/delete()。
Advanced capabilities (read references/ as needed)
| Topic | Path |
|---|---|
| BmobDocs Sync Code Snippets | references/snippets/ |
| Complete API Documentation | metadata.docs_raw |
| Complete Todo Example | metadata.docs_example |
Use Case Recipes
| Scenario | Recipe |
|---|---|
| User-Owned Todo (Row-Level ACL) | shared/recipes/user-owned-todos.md |
| Blog / CMS | shared/recipes/blog-cms.md |
| Avatar Upload | shared/recipes/avatar-upload.md |
Integration with MCP
If already configured Bmob MCP, before writing Swift code first get_project_tables to get the real schema, avoiding:
- Misspelled table names / field names (Swift subscripts do not validate the schema in advance).
- Wrong Pointer target table or objectId.
- ACL design does not match business ownership.
Troubleshooting Quick Reference
For cross-platform symptoms see shared/faq.md。
| Symptom | Troubleshooting |
|---|---|
No such module 'BmobSDK' |
Whether SPM added .product(name: "BmobSDK", package: "BmobSwiftSDK"); whether CocoaPods opened .xcworkspace |
| Requests fail after initialization | Whether the AppKey is correct;resetDomain whether it is before initialize ; whether the release domain has been filed |
| Update / delete has no effect | BmobObject(className:data:) the data of must contain objectId |
| Related query not expanded | Whether the query .includeKey("author"); whether the Pointer field name and target objectId exist |
BmobError.serverError(code, message) |
After retrieving the number code query bmob-error-codes |
| Numeric / boolean judgments in cloud functions are incorrect | request.body values are all strings; use parseInt、=== "true"、JSON.parse to parse, see "Cloud Function Parameters (Known Behavior)" above |
| Swift concurrency warnings or UI update issues | Use async/awaitfor SDK calls; return UI state updates to @MainActor / main thread context |
Reference
- Quickstart:index.md
- Complete API:develop_doc.md
- Complete Example:example.md
- Agent fetch:
metadata.docs_raw - SDK Source:https://github.com/bmob/BmobSwiftSDK
- Operation Routing:
shared/operation-routing.md - Legacy iOS SDK:
bmob-database-ios - MCP:
bmob-mcp - Writing Standards:
shared/skill-authoring.md