使用SWIFT使亚马逊AWS DynamoDB查询的最好方法?亚马逊、方法、SWIFT、DynamoDB

2023-09-11 23:50:57 作者:曲未终人却散

我最近实施了AWS SDK为我的iOS应用程序,这是我正在开发的斯威夫特。我已经连接到我的数据库实例的广告时能够得到一个查询响应,但是我奋力将其转换成有用的数据。我是比较新的雨燕,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 ad 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 may be missing something obvious!

我的code是如下:

    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
    }

和此控制台输出是:

对象:[{     面积={\ñS = \西浦\; \ n}的;     NAME ={\ñS = \奥利·梅斯\; \ n}的;     用户id ={\ñS = \123456abc \; \ n}的; }]

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

目前似乎没有太大precedence使用AWS和雨燕,可以理解,所以任何帮助将非常AP preciated!

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映射。下面是一个完整的示例,从表创建表删除。该示例插入,删除,扫描和使用DynamoDB映射查询表。

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)

这只是一个样本。这是不是一个好的做法,以嵌入一个访问键和code密钥。最好的做法是使用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)
}

如果您有DynamoDB在美国东1没有其他用途,不存在与运行此示例相关的成本,因为它是落入的 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.