测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可 | Apache 2 |
发布最后发布 | 2017年2月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✓ |
由 Robert Walsh,Robert Walsh 维护。
用Swift编写的用户网格SDK
虽然用户网格SDK是用Swift编写的,但其功能与Objective-C保持兼容。
在您的Objective-C文件中使用
#import <UsergridSDK/UsergridSDK-Swift.h>
来启用SDK的功能。
嵌入式框架至少需要iOS 8或OS X Mavericks(10.9)的部署目标。
cd
进入您的顶级项目目录,然后运行以下命令,如果您的项目未初始化为git仓库:$ git init
$ git submodule add https://github.com/apache/usergrid
UsergridSDK.xcodeproj
拖入您的应用程序Xcode项目的“项目导航器”。它应该出现在您的应用程序蓝色项目图标之下。
UsergridSDK.xcodeproj
,并验证部署目标与您的应用程序目标相匹配。+
按钮。UsergridSDK.framework
。
UsergridSDK.framework
将自动添加为目标依赖项、链接框架和复制文件构建阶段的嵌入式框架,这些正是您在模拟器和设备上构建所需要的东西。
此库的文档在此处可用:这里。
有两种不同的方式可以初始化用户网格Swift SDK
Usergrid.initSharedInstance(orgId: "orgId", appId: "appId")
let client = UsergridClient(orgId: "orgId", appId: "appId")
注意:本readme中的示例假设您正在使用共享实例的Usergrid
。如果您实现了实例模式,只需将Usergrid
替换为您的客户端实例变量即可。
注意:您必须有苹果开发者账号以及已设置的有效的配置文件,才能接收推送通知。
为了使用Usergrid推送通知,您必须使用Usergrid推送通知标识符注册设备。
有关接收推送通知和发送推送通知(从设备)的更详细示例,请参阅位于
/Samples
文件夹中的推送示例应用程序。
以下代码片段显示了如何在应用程序代理中注册推送通知并将推送令牌应用在其中。
import UsergridSDK
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Initialize the shared instance of Usergrid.
Usergrid.initSharedInstance(orgId:"orgId", appId: "appId")
// Register for APN
application.registerUserNotificationSettings(UIUserNotificationSettings( forTypes: [.Alert, .Badge, .Sound], categories: nil))
application.registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
Usergrid.applyPushToken(deviceToken, notifierID: "notifierId") { response in
// The push notification is now added to Usergrid for this device and this device will now be able to recieve notifications.
}
}
}
在发起任何RESTful调用时,始终需要一个type
参数(或path
)。您是将其指定为参数还是作为对象的参数,由您决定。
Usergrid.GET("collection") { response in
var entities: [UsergridEntity]? = response.entities
}
Usergrid.GET("collection", uuidOrName:"<uuid-or-name>") { response in
var entity: UsergridEntity? = response.entity?
}
UsergridQuery
对象在集合中获取特定实体var query = UsergridQuery("cats").gt("weight", value: 2.4)
.contains("color", value:"bl*")
.not()
.eq("color", value:"blue")
.or()
.eq("color", value:"orange")
// this will build out the following query:
// select * where weight > 2.4 and color contains 'bl*' and not color = 'blue' or color = 'orange'
Usergrid.GET(query) { response in
var entities: [UsergridEntity]? = response.entities
}
POST和PUT请求都需要JSON体负载。您可以传递Swift对象或UsergridEntity
实例。虽然前一种在原则上可行,但最佳实践是在适用的情况下使用UsergridEntity
。当实体具有uuid或名称属性并且已在服务器上存在时,使用PUT请求更新它。如果它不存在,则使用POST来创建它。
var entity = UsergridEntity(type: "restaurant", propertyDict: ["restaurant": "Dino's Deep Dish","cuisine": "pizza"])
Usergrid.POST(entity) { response in
// entity should now have a uuid property and be created
}
// you can also POST an array of entities:
var entities = [UsergridEntity(type: "restaurant", propertyDict:["restaurant": "Dino's Deep Dish","cuisine": "pizza"]),
UsergridEntity(type: "restaurant", propertyDict:["restaurant": "Pizza da Napoli","cuisine": "pizza"])]
Usergrid.POST(entities) { response in
// response.entities should now contain now valid posted entities.
}
var entity = UsergridEntity(type: "restaurant", propertyDict:["restaurant": "Dino's Deep Dish", "cuisine": "pizza"])
Usergrid.POST(entity) { response in
if let responseEntity = response.entity {
responseEntity["owner"] = "Mia Carrara"
Usergrid.PUT(responseEntity) { (response) -> Void in
// entity now has the property 'owner'
}
}
}
// or update a set of entities by passing a UsergridQuery object
var query = UsergridQuery("restaurants").eq("cuisine", value:"italian")
Usergrid.PUT(query, jsonBody: ["keywords":["pasta"]]) { response in
/* the first 10 entities matching this query criteria will be updated:
e.g.:
[
{
"type": "restaurant",
"restaurant": "Il Tarazzo",
"cuisine": "italian",
"keywords": ["pasta"]
},
{
"type": "restaurant",
"restaurant": "Cono Sur Pizza & Pasta",
"cuisine": "italian",
"keywords": ["pasta"]
}
]
*/
}
DELETE请求需要传递特定实体或作为参数传递的UsergridQuery
对象。
Usergrid.DELETE("collection", uuidOrName: "<uuid-or-name>") { response in
// if successful, entity will now be deleted
})
UsergridQuery
对象来删除集合中的特定实体let query = UsergridQuery("cats").eq("color", value:"black")
.or()
.eq("color", value:"white")
// this will build out the following query:
// select * where color = 'black' or color = 'white'
Usergrid.DELETE(query) { response in
// the first 10 entities matching this query criteria will be deleted
}
UsergridEntity
提供了一些帮助/便捷方法,使与实体的交互更加方便。
从服务器重新加载实体
entity.reload() { response in
// entity is now reloaded from the server
}
在服务器上保存(或创建)实体
entity["aNewProperty"] = "A new value"
entity.save() { response in
// entity is now updated on the server
}
从服务器删除实体
entity.remove() { response in
// entity is now deleted on the server and the local instance should be destroyed
}
Usergrid
可以使用初始化时传递的app客户端ID和密钥,自动检索用于这些凭据的应用程序级别令牌。
Usergrid.setAppAuth("<client-id>", "<client-secret>")
Usergrid.authenticateApp() { response in
// Usergrid.appAuth is authenticated automatically when this call is successful
}
Usergrid
具有一个特殊的currentUser
属性。
当前用户信息存储在钥匙串中,以便于在应用重新启动后保持用户的登录和令牌信息。要调整此功能,请在初始化时编辑
Usergrid.persistCurrentUserInKeychain
属性。
默认情况下,在调用authenticateUser()
时,如果身份验证流程成功,将.currentUser
设置为该用户。
let userAuth = UsergridUserAuth(username: "<username>", password: "<password>")
Usergrid.authenticateUser(userAuth) { auth, user, error in
// Usergrid.currentUser is set to the authenticated user and the token is stored within that context
}
如果您想在未将其设置为当前用户的情况下使用authenticateUser,只需将布尔值作为第二个参数传递为false
。
let userAuth = UsergridUserAuth(username: "<username>", password: "<password>")
Usergrid.authenticateUser(userAuth,setAsCurrentUser: false) { auth, user, error in
// user is authenticated but Usergrid.currentUser is not set.
}
认证模式用于确定UsergridClient
将用于授权的内容。
默认情况下,Usergrid.authMode
被设置为.User
,在这种情况下,如果UsergridClient.currentUser
中存在非过期的UsergridUserAuth
,将使用这个令牌对所有API调用进行认证。
如果将Usergrid.authMode
设置为.None
,则所有API调用都将未认证执行。
如果将Usergrid.authMode
设置为.App
,则所有API调用都将使用客户端凭证令牌执行,如果有可用的令牌(即在某处执行了authenticateApp()
)。
有时候,可能希望对API调用的认证上下文有完整的、粒度化的控制。
为此,passthrough函数.usingAuth()
允许您预先定义下一个API调用的认证上下文。
// assume Usergrid.authMode = .None
Usergrid.usingAuth(Usergrid.appAuth!).POST("roles/guest/permissions", jsonBody: ["permission" : "get,post,put,delete:/**"] ) { response in
// here we've temporarily used the client credentials to modify permissions
// subsequent calls will not use this auth context
}
UsergridUser
具有一些助手/便捷方法,以便更方便地处理用户实体。如果您没有使用Usergrid
共享实例,您必须将这些助手方法作为第一个参数传递一个UsergridClient
实例。
创建新用户
let user = UsergridUser(username: "username", password: "password")
user.create() { response in
// user has now been created and should have a valid uuid
}
以更简单的方式获取用户级别的令牌
user.login("username", password: "password") { auth, user, error in
// user is now logged in
}
注销所选用户。您也可以在Usergrid.currentUser
上使用此便捷方法。
user.logout() { response in
// user is now logged out
}
重置所选用户的密码。
user.resetPassword("oldPassword", new: "newPassword") { error, didSucceed in
// if it was done correctly, the new password will be changed
// 'didSucceed' is a boolean value that indicates whether it was changed successfully
}
这是一个类(静态)方法,允许您检查用户名或电子邮箱地址是否可用。
UsergridUser.checkAvailable("email", username: nil) { error, available in
// 'available' == whether an email already exists for a user
}
UsergridUser.checkAvailable(nil, username: "username") { error, available in
// 'available' == whether an username already exists for a user
}
UsergridUser.checkAvailable("email", username: "username") { error, available in
// 'available' == whether an email or username already exist for a user
}
UsergridQuery
类允许您使用Usergrid查询语法构建复杂的查询过滤器。
UsergridQuery
构建模式的第一个参数应该是您打算查询的集合(或类型)。您可以将其传递作为一个参数,或者作为第一个构建对象。
var query = UsergridQuery("cats")
// or
var query = UsergridQuery().collection("cats")
然后可以添加额外的查询。
var query = UsergridQuery("cats").gt("weight", value: 2.4)
.contains("color", value: "bl*")
.not()
.eq("color", value:"white")
.or()
.eq("color", value:"orange")
您还可以调整返回结果的数量
var query = UsergridQuery("cats").eq("color", value: "black")
.limit(100)
// returns a maximum of 100 entiteis
并且可以排序结果
var query = UsergridQuery("cats").eq("color", value: "black")
.limit(100)
.asc("name")
// sorts by 'name', ascending
并且可以进行地理定位查询
var query = UsergridQuery("devices").locationWithin(<distance>, latitude: <lat>, longitude: <long>)
可以将查询作为参数传递给GET、PUT和DELETE请求
Usergrid.GET("type", query: query) { response in
// Gets entities of a given type matching the query.
}
Usergrid.PUT(query, jsonBody: ["aNewProperty":"A new value"]) { response in
// Updates the entities matching the query with the new property.
}
Usergrid.DELETE(query) { response in
// Deletes entities of a given type matching the query.
}
type("string")
查询的集合名称
collection("string")
type
的别名
eq("key", value: "value")
或 equals("key", value: "value")
或 filter("key", value: "value")
等于(例如:
where color = 'black'
)
contains("key", value: "value")
或 containsString("key", value: "value")
或 containsWord("key", value: "value")
包含字符串(例如:
where color contains 'bl*'
)
gt("key", value: "value")
或 greaterThan("key", value: "value")
大于(例如:
where weight > 2.4
)
gte("key", value: "value")
或 greaterThanOrEqual("key", value: "value")
大于等于(例如:
where weight >= 2.4
)
lt("key", value: "value")
或 lessThan("key", value: "value")
小于(例如:
where weight < 2.4
)
lte("key", value: "value")
或 lessThanOrEqual("key", value: "value")
小于等于(例如:
where weight <= 2.4
)
not()
否定构建器模式中的下一条语句,例如:
var query = UsergridQuery("cats").not().eq("color", value: "black")
// select * from cats where not color = 'black'
and()
通过要求两个查询都满足来连接两个查询。
and
在连接两个查询时不带操作符时也是隐含的。例如:
var query = UsergridQuery("cats").eq("color", value:"black").eq("fur", value:"longHair")
// is identical to:
var query = UsergridQuery("cats").eq("color", value:"black").and().eq("fur", value:"longHair")
or()
通过只要求满足其中一个查询来连接两个查询。
or
永远不会隐含。例如:
var query = UsergridQuery("cats").eq("color",value: "black").or().eq("color", value: "white")
当使用
or()
和and()
运算符时,and()
连接的优先级高于or()
连接。您可以在此处阅读有关查询运算符和优先级的更多信息:。
locationWithin(distanceInMeters, latitude: latitude, longitude: longitude)
返回在指定半径内的实体。参数可以是
float
或int
。
asc("key")
或 ascending("key")
按指定属性升序排序结果
desc("key")
或 descending("key")
按指定属性降序排序结果
sort("key", value: .Asc)
按指定属性,在指定的
UsergridQuerySortOrder
(.Asc
或.Desc
)中排序结果
limit(int)
要返回的最大实体数
cursor("string")
分页游标字符串
fromString("query string")
一个特殊的构建器属性,允许您输入预定义的查询字符串。当定义此属性时,将忽略所有构建器属性。例如
var query = UsergridQuery().fromString("select * where color = 'black' order by name asc")
UsergridResponse
是处理Usergrid成功和失败HTTP响应的核心类。
如果请求成功,响应中返回的任何实体都将自动解析为UsergridEntity
对象,并推送到entities
属性。
如果请求失败,error
属性将包含关于遇到的问题的信息。
您可以通过检查UsergridResponse.ok
,一个Bool
值,来查看响应是否成功。任何状态码< 400
返回true。
Usergrid.GET("collection") { response in
if response.ok {
// woo!
}
}
根据您进行的调用,响应中返回的任何实体都将自动解析为UsergridEntity
对象,并推送到entities
属性。如果您正在查询users
集合,这些也将是UsergridUser
对象,它是UsergridEntity
的子类。
.first
返回实体数组中的第一个实体;.entity
是.first
的别名。如果没有实体,这两个都将是未定义的。
.last
返回实体数组中的最后一个实体;如果数组中只有一个实体,这将与.first
和.entity
相同,如果没有实体,将为未定义。
.entities
将是响应中的实体数组,或者是一个空数组。
.user
是一种特殊别名,用于查询users
集合时的.entity
。它不是UsergridEntity
对象,而是它的子类UsergridUser
。
.users
与.user
相同,不过其行为类似于.entities
,返回一个包含UsergridUser
对象数组的数组,或者一个空数组。
示例
Usergrid.GET("collection") { response in
// you can access:
// response.entities (the returned entities)
// response.first (the first entity)
// response.entity (same as response.first)
// response.last (the last entity returned)
}
Usergrid.GET("collection", uuidOrName:"<uuid-or-name>") { response in
// you can access:
// response.entity (the returned entity)
// response.entities (containing only the returned entity)
// response.first (same as response.entity)
// response.last (same as response.entity)
}
Usergrid.GET("users") { response in
// you can access:
// response.users (the returned users)
// response.entities (same as response.users)
// response.user (the first user)
// response.entity (same as response.user)
// response.first (same as response.user)
// response.last (the last user)
}
Usergrid.GET("users", uuidOrName:"<uuid-or-name>") { response in
// you can access;
// response.users (containing only the one user)
// response.entities (same as response.users)
// response.user (the returned user)
// response.entity (same as response.user)
// response.first (same as response.user)
// response.last (same as response.user)
}
可以使用Usergrid.connect()
、Usergrid.disconnect()
和Usergrid.getConnections()
或同名的实体便捷方法来管理连接。
当通过Usergrid.getConnections()
检索连接时,您可以通过传入一个可选的UsergridQuery
对象来过滤返回的已连接实体。
在两个实体之间创建连接
Usergrid.connect(entity1, relationship: "relationship", to: entity2) { response in
// entity1 now has an outbound connection to entity2
}
检索出站连接
Usergrid.getConnections(.Out, entity: entity1, relationship: "relationship", query: nil) { response in
// entities is an array of entities that entity1 is connected to via 'relationship'
// in this case, we'll see entity2 in the array
}
检索入站连接
Usergrid.getConnections(.In, entity: entity2, relationship: "relationship", query: nil) { response in
// entities is an array of entities that connect to entity2 via 'relationship'
// in this case, we'll see entity1 in the array
}
删除两个实体之间的连接
Usergrid.disconnect(entity1, relationship: "relationship", from: entity2) { response in
// entity1's outbound connection to entity2 has been destroyed
}
可以使用Usergrid.uploadAsset()
或Usergrid.downloadAsset()
直接上传和下载资源,或者使用具有相同名称的同名UsergridEntity
便捷方法。在上传资源之前,您需要初始化一个UsergridAsset
实例。
注意:初始化UsergridAsset
对象时指定文件名是可选的。
let image = UIImage(contentsOfFile: "path/to/image")
let data = UIImagePNGRepresentation(image)
let asset = UsergridAsset(fileName:"<file-name-or-nil>", data: data!, contentType:"image/png")
let image = UIImage(contentsOfFile: "path/to/image")
let asset = UsergridAsset(fileName:"<file-name-or-nil>", image: image!, imageContentType: .Png)
let fileUrl = NSURL(string: "local/path/to/file")
if fileUrl.isFileReferenceURL() { // This must be a file reference url.
let asset = UsergridAsset(fileName:"<file-name-or-nil>", fileUrl: fileUrl!, contentType:"<content-type>")
}
上传一个图片并连接到实体
let image = UIImage(contentsOfFile: "path/to/image")
let asset = UsergridAsset(fileName:"<file-name-or-nil>", image: image!, imageContentType: .Png)!
Usergrid.uploadAsset(entity,
asset: asset,
progress: { bytesFinished, bytesExpected in
// Monitor the upload progress
},
completion: { asset, response in
// The asset is now uploaded to Usergrid and entity.asset == asset
})
下载与实体连接的图片
Usergrid.downloadAsset(entity,
contentType: "<expected-content-type>",
progress: { bytesFinished, bytesExpected in
// Monitor the download progress
},
completion:{ asset, error in
// The asset is now downloaded from Usergrid and entity.asset == asset
})
创建基础UsergridEntity
类(类似于UsergridUser
和UsergridDevice
)的自定义子类是可能的。
有关创建自定义子类的示例,请参阅位于
/Samples
文件夹中的ActivityFeed示例应用。那里的自定义子类名为ActivityEntity
。
UsergridEntity
的子类并实现所需的方法import UsergridSDK
public class ActivityEntity: UsergridEntity {
required public init(type: String, name: String?, propertyDict: [String : AnyObject]?) {
super.init(type: type, name: name, propertyDict: propertyDict)
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Usergrid.initSharedInstance(orgId: "orgId", appId: "appId")
UsergridEntity.mapCustomType("activity", toSubclass: ActivityEntity.self)
通过注册自定义子类,UsergridEntity
和 UsergridResponse
类能够根据实体的 type
生成这些类的实例。
在上面的示例中,具有 type
值为 activity
的实体现在可以被转换为 ActivityEntity
对象。例如:
Usergrid.GET("activity") { response in
var activityEntities: [ActivityEntity]? = response.entities as? [ActivityEntity]
}