使用 Swift 进行 Amazon AWS DynamoDB 查询的最佳方式? [英] Best way to make Amazon AWS DynamoDB queries using Swift?

查看:38
本文介绍了使用 Swift 进行 Amazon AWS DynamoDB 查询的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近为我在 Swift 中开发的 iOS 应用程序实施了 AWS 开发工具包.我已连接到我的数据库实例并且能够获得查询响应,但是,我正在努力将其转换为可用数据.我对 Swift、AWS 和一般编程比较陌生,所以可能会遗漏一些明显的东西!

I have recently implemented the AWS SDK for my iOS app, which I am developing in Swift. I have connected to my DB instance and am able to get a query response, however, I am struggling to convert this into usable data. I'm relatively new to Swift, AWS and programming in general so maybe missing something obvious!

我的代码如下:

    let atVal = AWSDynamoDBAttributeValue()
    atVal.S = "123456abc"
    let condition = AWSDynamoDBCondition()
    condition.comparisonOperator = AWSDynamoDBComparisonOperator.EQ
    condition.attributeValueList = [atVal]

    let myDic: [String: AWSDynamoDBCondition] = ["userid": condition]
    let query = AWSDynamoDBQueryInput()
    query.indexName = "userid-index"
    query.tableName = "users"
    query.keyConditions = myDic
    query.limit = 1


    dynamoDB.query(query).continueWithBlock {
        (task: BFTask!) -> AnyObject! in
        let results = task.result as AWSDynamoDBQueryOutput

        let myResults = results.items
        println("object: (myResults.description)")

        return nil
    }

控制台输出是:

对象:[{area = " { S = "West Hampstead"; }";name = " { S = "Olly Mayes"; }";用户 ID = " { S = "123456abc"; }";}]

object: [{ area = " { S = "West Hampstead"; }"; name = " { S = "Olly Mayes"; }"; userid = " { S = "123456abc"; }"; }]

使用 AWS 和 Swift 的优先级似乎并不高,这是可以理解的,因此我们将不胜感激!

There doesn't seem to be much precedence for using AWS and Swift, understandably, so any help would be much appreciated!

推荐答案

问题的简单答案是:将返回的 JSON 字符串转换为 Dictionary 对象.像这样:

The easy answer to your question is : convert the JSON string returned into a Dictionary object. Something like this :

let data = jsonDataItem.dataUsingEncoding(NSUTF8StringEncoding)

    if data != nil {
        var error : NSError?
        let dict = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: &error) as? NSDictionary

        if let e = error {
            ...
        } else {
            ...
        }

但是,我强烈建议您查看更高级别的 DynamoDB 映射器类使用 DynamoDB 映射器类时,您定义数据结构,并将其提供给 DynamoDB Mapper.这是一个完整的示例,从表创建到表删除.该示例使用 DynamoDB Mapper 插入、删除、扫描和查询表.

However, I would strongly encourage you to look at the higher level DynamoDB mapper class When using DynamoDB mapper class, you define your data structure, and just give it to DynamoDB Mapper. Here is a full sample, from table creation to table deletion. The example inserts, removes, scans and query the table using DynamoDB Mapper.

首先需要初始化客户端SDK

First, you need to initialise the client SDK

    let cp = AWSStaticCredentialsProvider(accessKey: "AK...", secretKey: "xxx")
    let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: cp)
    AWSServiceManager.defaultServiceManager().setDefaultServiceConfiguration(configuration)

这只是一个示例.在代码中嵌入访问密钥和秘密密钥不是一个好习惯.最佳实践是使用 AWSCognitoCredentialsProvider 代替(阅读有关 Cognito 的更多信息).

This is a sample only. It is not a good practice to embed an Access Key and Secret Key in the code. Best practice would be to use the AWSCognitoCredentialsProvider instead (read more about Cognito).

定义一个类来映射表格中的项目

class Item : AWSDynamoDBModel, AWSDynamoDBModeling {

    var email  : String = ""
    var date   : String = ""
    var note   : String = ""
    var number : Double = 0.0

    override init!() { super.init() }

    required init!(coder: NSCoder!) {
        fatalError("init(coder:) has not been implemented")
    }

    class func dynamoDBTableName() -> String! {
        return "Demo"
    }
    class func hashKeyAttribute() -> String! {
        return "email"
    }
    class func rangeKeyAttribute() -> String! {
        return "date"
    }

    //required to let DynamoDB Mapper create instances of this class
    override init(dictionary dictionaryValue: [NSObject : AnyObject]!, error: NSErrorPointer) {
        super.init(dictionary: dictionaryValue, error: error)
    }

    //workaround to possible XCode 6.1 Bug : "Type NotificationAck" does not conform to protocol "NSObjectProtocol"
    override func isEqual(anObject: AnyObject?) -> Bool {
        return super.isEqual(anObject)
    } }

创建表格

self.createTable().continueWithSuccessBlock {(task: BFTask!) -> BFTask! in
    NSLog("Create table - success")
    return nil
}


func createTable() -> BFTask! {
    let pt = AWSDynamoDBProvisionedThroughput()
    pt.readCapacityUnits  = 10
    pt.writeCapacityUnits = 10

    let emailAttr = AWSDynamoDBAttributeDefinition()
    emailAttr.attributeName = "email"
    emailAttr.attributeType = AWSDynamoDBScalarAttributeType.S

    let dateAttr = AWSDynamoDBAttributeDefinition()
    dateAttr.attributeName = "date"
    dateAttr.attributeType = AWSDynamoDBScalarAttributeType.S

    let emailKey = AWSDynamoDBKeySchemaElement()
    emailKey.attributeName = "email"
    emailKey.keyType = AWSDynamoDBKeyType.Hash

    let dateKey = AWSDynamoDBKeySchemaElement()
    dateKey.attributeName = "date"
    dateKey.keyType = AWSDynamoDBKeyType.Range

    let ct = AWSDynamoDBCreateTableInput()
    ct.tableName = "Demo"
    ct.provisionedThroughput = pt
    ct.attributeDefinitions = [emailAttr, dateAttr]
    ct.keySchema = [ emailKey, dateKey ]

    NSLog("Creating table")

    let client = AWSDynamoDB.defaultDynamoDB()
    return client.createTable(ct)
}

删除表格

self.deleteTable().continueWithSuccessBlock({ (task: BFTask!) -> BFTask! in
    NSLog("Delete table - success")
    return nil
})

func deleteTable() -> BFTask! {

    let dt = AWSDynamoDBDeleteTableInput()
    dt.tableName = "Demo"

    NSLog("Deleting table")
    let client = AWSDynamoDB.defaultDynamoDB()
    return client.deleteTable(dt)
}

插入项目

self.insertSomeItems().continueWithBlock({
    (task: BFTask!) -> BFTask! in

    if (task.error != nil) {
        NSLog(task.error.description)
    } else {
        NSLog("DynamoDB save succeeded")
    }

    return nil;
})

func insertSomeItems() -> BFTask! {
    let mapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()

    var item = Item()
    item.email  = "stormacq@amazon.com"
    item.date   = "20141101"
    item.note   = "This is item #1"
    item.number = 1.0
    let task1 = mapper.save(item)

    item = Item()
    item.email  = "stormacq@amazon.com"
    item.date   = "20141102"
    item.note   = "This is item #2"
    item.number = 2.0
    let task2 = mapper.save(item)

    item = Item()
    item.email  = "stormacq@amazon.lu"
    item.date   = "20141103"
    item.note   = "This is item #3"
    item.number = 3.0
    let task3 = mapper.save(item)

    return BFTask(forCompletionOfAllTasks: [task1, task2, task3])
}

加载单个项目

self.load("stormacq@amazon.com", range:"20141101").continueWithSuccessBlock({ (task: BFTask!) -> BFTask! in
    NSLog("Load one value - success")
    let item = task.result as Item
    print(item)
    return nil
})


func load(hash: String, range: String) -> BFTask! {
    let mapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
    return mapper.load(Item.self, hashKey: hash, rangeKey: range)

}

查询哈希和范围键

/* 
   keyConditions
   http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSDynamoDBQueryInput.html#//api/name/keyConditions
*/
let cond = AWSDynamoDBCondition()
let v1    = AWSDynamoDBAttributeValue(); v1.S = "20141101"
cond.comparisonOperator = AWSDynamoDBComparisonOperator.EQ
cond.attributeValueList = [ v1 ]
let c = [ "date" : cond ]
self.query("stormacq@amazon.com", keyConditions:c).continueWithSuccessBlock({ (task: BFTask!) -> BFTask! in
    NSLog("Query multiple values - success")
    let results = task.result as AWSDynamoDBPaginatedOutput
    for r in results.items {
        print(r)
    }
    return nil
})

func query(hash: String, keyConditions:[NSObject:AnyObject]) -> BFTask! {
    let mapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()

    let exp = AWSDynamoDBQueryExpression()
    exp.hashKeyValues      = hash
    exp.rangeKeyConditions = keyConditions

    return mapper.query(Item.self, expression: exp)
}

扫描项目(全表扫描)

let cond = AWSDynamoDBCondition()
let v1    = AWSDynamoDBAttributeValue(); v1.S = "20141101"
cond.comparisonOperator = AWSDynamoDBComparisonOperator.GT
cond.attributeValueList = [ v1 ]

let exp = AWSDynamoDBScanExpression()
exp.scanFilter = [ "date" : cond ]

self.scan(exp).continueWithSuccessBlock({ (task: BFTask!) -> BFTask! in
    NSLog("Scan multiple values - success")
    let results = task.result as AWSDynamoDBPaginatedOutput
    for r in results.items {
        print(r)
    }
    return nil
})

func scan(expression : AWSDynamoDBScanExpression) -> BFTask! {

    let mapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
    return mapper.scan(Item.self, expression: expression)
}

如果您在 US EAST 1 中没有其他使用 DynamoDB 的情况,则运行此示例不会产生任何相关费用,因为它属于 DynamoDB 的免费套餐.

If you have no other usage of DynamoDB in US EAST 1, there is no cost associated with running this sample, as it is falling into DynamoDB's free tier.

这篇关于使用 Swift 进行 Amazon AWS DynamoDB 查询的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆