DynamoDB"序列化对象不是有效的json对象"

时间:2015-02-21 19:22:30

标签: ios swift amazon-web-services amazon-dynamodb

我正在尝试扫描DynamoDB表,获取位置附近的所有项目:

func getPosts(location: CLLocation, radius: Int, limit: Int){
    let rad = Double(Double(radius) * 0.01)
    let latMin = location.coordinate.latitude - rad
    let latMax = location.coordinate.latitude + rad
    let lonMin = location.coordinate.longitude - rad
    let lonMax = location.coordinate.longitude + rad

    var latMinA: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
    latMinA.N = "\(latMin)"
    var latMaxA: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
    latMaxA.N = "\(latMax)"
    var lonMinA: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
    lonMinA.N = "\(lonMin)"
    var lonMaxA: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
    lonMaxA.N = "\(lonMax)"

    var vals: [NSObject : AnyObject] = [":latMin" : latMinA, ":latMax" : latMaxA, ":lonMin" : lonMinA, ":lonMax" : lonMaxA]

    var filter = "(Latitude BETWEEN :latMin AND :latMax) and (Longitude BETWEEN :lonMin AND :lonMax)"

    self.scan("Posts", select: AWSDynamoDBSelect.AllAttributes, attributes: nil, filterAttributes: vals, startKeyName: nil, startKey: nil, limit: nil, filter: filter)
}

func scan(table: String, select: AWSDynamoDBSelect, attributes: [String]?, filterAttributes: [NSObject : AnyObject]?, startKeyName: String?, startKey: String?, limit: Int?, filter: String?){
     let dynamo: AWSDynamoDB = AWSDynamoDB.defaultDynamoDB()

     var fa: String = ""
     if(attributes != nil){
         for attribute in attributes!{
             fa+=(fa == "" ? "" : ", ")
             fa+=attribute
         }
     }

     var val: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
     val.S = startKey

     let input: AWSDynamoDBScanInput = AWSDynamoDBScanInput()
     input.tableName = table
     input.exclusiveStartKey = startKeyName != nil && startKey != nil ? [startKeyName! : val] : nil
     input.limit = limit == nil ? nil : NSNumber(unsignedInteger: limit!)
     input.filterExpression = filter
     input.expressionAttributeNames = filterAttributes
     input.select = select
     input.projectionExpression = fa == "" ? nil : fa


     dynamo.scan(input).continueWithBlock({(task: BFTask!) -> AnyObject! in
         if(task.error != nil){println("An error occurred while scanning in DynamoDB table \(table). Message: '\(task.error)'")}

         return nil
     })
 }
正确计算了{p> latMinlatMaxlonMinlonMax,除了我尝试扫描表格时,一切正常。扫描表时,我收到此错误:

Error Domain=com.amazonaws.AWSJSONBuilderErrorDomain Code=4 "serialized object is not a valid json Object: {
  ExpressionAttributeNames =     {
    ":latMax" = "<AWSDynamoDBAttributeValue: 0x7fe1c3e6f6d0> {\n    N = \"33.820303\";\n}";
    ":latMin" = "<AWSDynamoDBAttributeValue: 0x7fe1c3ea33d0> {\n    N = \"33.740303\";\n}";
    ":lonMax" = "<AWSDynamoDBAttributeValue: 0x7fe1c3ea0cf0> {\n    N = \"-118.378292\";\n}";
    ":lonMin" = "<AWSDynamoDBAttributeValue: 0x7fe1c3e7cf90> {\n    N = \"-118.458292\";\n}";
  };
  FilterExpression = "(Latitude BETWEEN :latMin AND :latMax) and (Longitude BETWEEN :lonMin AND :lonMax)";
  Select = "ALL_ATTRIBUTES";
  TableName = Posts;
}

LatitudeLongitudeNumber数据类型,也是Local Secondary Indexes。我不会解析任何JSON,它都是由AWS完成的。

我已尝试将过滤器设置为:

var filter = "(Latitude BETWEEN \(latMin) AND \(latMax)) and (Longitude BETWEEN \(lonMin) AND \(lonMax))"

并且只是将其设置为:

var filter = "(Latitude BETWEEN 100 AND 200) and (Longitude BETWEEN 100 AND 200)"

但我仍然得到同样的错误。当我尝试将过滤器和attributeValues设置为:

时,会发生同样的情况
var lat: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
lat.S = "Latitude"
var lon: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
lon.S = "Longitude"

var vals: [NSObject : AnyObject] = [":lat" : lat, ":lon" : lon]

var filter = "(:lat BETWEEN \(latMin) AND \(latMax)) and (:lon BETWEEN \(lonMin) AND \(lonMax))"

但我仍然明白这一点:

Error Domain=com.amazonaws.AWSJSONBuilderErrorDomain Code=4 "serialized object is not a valid json Object: {
  ExpressionAttributeNames =     {
    ":lat" = "<AWSDynamoDBAttributeValue: 0x7fd69afa77b0> {\n    S = Latitude;\n}";
    ":lon" = "<AWSDynamoDBAttributeValue: 0x7fd69afe2fc0> {\n    S = Longitude;\n}";
  };
  FilterExpression = "(:lat BETWEEN 33.740303 AND 33.820303) and (:lon BETWEEN -118.458292 AND -118.378292)";
  Select = "ALL_ATTRIBUTES";
  TableName = Posts;
}

我是否应该自己过滤结果,而不使用included in the AWS API过滤器?

1 个答案:

答案 0 :(得分:-1)

expressionAttributeNames的{​​{1}} <{1}}必须是AWSDynamoDBScanInputString字典。有关详细信息,请参阅AWSDynamoDBScanInput Class Reference

此外,如果您使用的是框架而不是CocoaPods,请务必将String更新为最新版本。