Google Cloud Storage iOS - Without Authentication - ios

I'm trying to upload or download files from Google Cloud Storage without authentication. I tried to use something similar to this https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Basics but didn't work.
let storage = GTLServiceStorage()
storage.additionalHTTPHeaders = ["x-goog-project-id":"my-project-id", "Content-Type": "application/json-rpc", "Accept": "application/json-rpc"]
storage.APIKey = "my-server-api-key"
storage.retryEnabled = true
// bucket
let bucket : GTLStorageBucket = GTLStorageBucket()
bucket.name = "my-bucket-name"
// this code doesn't matter is only for test the previous code
let query : GTLQueryStorage = GTLQueryStorage.queryForBucketsInsertWithObject(bucket, project: "my-project-id") as GTLQueryStorage
self.storage.executeQuery(query, completionHandler: { (ticket : GTLServiceTicket!, object : AnyObject!, error : NSError!) -> Void in
NSLog("Bucket: \(object)");
})
When i tried the code above i get "Login Required" error, so i tried applying the following code before the code previous
auth.scope = kGTLAuthScopeStorageDevstorageFullControl
auth.clientID = "ios-client-id"
auth.clientSecret = "ios-client-secret"
auth.redirectURI = "urn:ietf:wg:oauth:2.0:oob"
storage.authorizer = auth // then set authorization to StorageService
But doesn't work. I get the error, keyName: "Request"
Please give me an example how to make it works or what i'm doing wrong.
Thanks.

Although I'm not sure this will solve your problem; all your variables are declared with the keyword let instead of var. Using the let keyword prevents any future changes to the object. It defines a constant. This prevents you from changing the object's properties the way you are doing now. You can find more info about this in the Swift documentation.

Related

Fetching list of things in things group or things from AWS IoT

I need list of things in group or list of things from AWS with that I tried to find solution from AWSIoT Reference So i have used below code to get it. Previously i used to get it using normal API call from our backend service but i need fully use with AWS.
func initializeAWS() {
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:AWS_REGION,
identityPoolId:IDENTITY_POOL_ID)
initializeControlPlane(credentialsProvider: credentialsProvider)
}
func initializeControlPlane(credentialsProvider: AWSCredentialsProvider) {
let controlPlaneServiceConfiguration = AWSServiceConfiguration(region:AWS_REGION, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = controlPlaneServiceConfiguration
iot = AWSIoT.default()
let request = AWSIoTListThingsInThingGroupRequest()
request?.thingGroupName = "XXXGroupName"
let output = iot.listThings(inThingGroup: request!)
print("output is \(output.result)")
print("error is \(output.error)")
}
I have used here AWSIoT & AWSIoTListThingsInThingGroupRequest object to get list of things may i know is this right way to fetch ? if it is I'm output and error both objects getting nil.
I tried to find solution for the AWS IOT example from Github, I didnt get anything relevant answer to this. Or is there anything in iotDataManager that will give list of things ? Please can you help me on this ? For more info I have raised question on AWS Github Fetching list of things in things group
I've checked log level output was getting, All configurations as well was right only thing i wasn't aware about is how to get response of things, the way to get things is as below.
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:AWS_REGION,
identityPoolId:IDENTITY_POOL_ID)
let controlPlaneServiceConfiguration = AWSServiceConfiguration(region:AWS_REGION, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = controlPlaneServiceConfiguration
iot = AWSIoT.default()
let request = AWSIoTListThingsInThingGroupRequest()
request?.thingGroupName = "XXXGroupName"
let output = iot.listThings(inThingGroup: request!)
output.continueOnSuccessWith { (response) -> Any? in
if let result = response.result, let things = result.things {
self.awsDevices = things
completionHandler(true)
}
return self.awsDevices
}

Firebase DynamicLink Url returning jSON serialize error. iOS

Xcode version: 10.1
Firebase SDK version: 6.0.0
Firebase Component: Firebase/DynamicLinks
Component version: 4.0.0
Hi, I am stuck at a point when dealing with Dynamic linking, all is good when making a link, but i am getting error on the link which is like this
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.
</ExceptionMessage>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Object reference not set to an instance of an object.
</ExceptionMessage>
<ExceptionType>System.NullReferenceException</ExceptionType>
and link which is generated https://marcoapp.page.link/T4Ye is here which is having issue.
i know that is error where someone would say it's from backend , but no same things worked before and even Android level of application is still working fine with same parameters. And i didn't get what is wrong thing i am sending or not sending which is causing this issue. Below mentioned is the code.
guard let components: DynamicLinkComponents = DynamicLinkComponents(link: urlLink, domainURIPrefix: "https://marcoapp.page.link") else {
return ""
}
in here urlLink = https://marcotest.azurewebsites.net/api/Groups/(Int)
func createDynamicLink() {
let domain = "yourProject.page.link"
let link = URL(string: "https://facebook.com")
let referralLink = DynamicLinkComponents(link: link!, domain: domain)
referralLink.iOSParameters = DynamicLinkIOSParameters(bundleID: “set_app_bundleID")
referralLink.iOSParameters?.appStoreID = "app_store_id"
referralLink.androidParameters = DynamicLinkAndroidParameters(packageName: "set_app_bundleID")
guard let longUrl = referralLink.url?.absoluteString else {
return
}
print(longUrl)
}
Make sure you have already created domain in firebase account in Dynamic links section then only you can use let domain = "yourProject.page.link"
https://imgur.com/a/Fg5qHyV

How to access JSON response in Swift using AWS API Gateway-generated iOS SDK

I have a working REST API based on this API Gateway tutorial. I'm able to successfully invoke it via the test functionality of the AWS Console; and I'm able to successfully invoke it via my simple iOS Swift 4.2 Xcode application using the iPhone XR simulator.
I know it's working via a real, live external call because I can see the Cloudwatch logs which always register a 200 response and is sending the results back to the Client.
My problem is really in understanding the Swift code, and I'm hoping that a Swift expert can help me understand how to unpack result in the code below.
Here's my code in ViewController.swift for invoking the REST API and attempting to print result to the console:
#IBAction func userInvokeApi(_ sender: UIButton) {
print("You clicked invoke api...")
let client = SVTLambdaGateClient.default()
client.calcGet(operand2: "3", _operator: "+", operand1: "5").continueWith{ (task: AWSTask?) -> AnyObject? in
if let error = task?.error {
print("Error occurred: \(error)")
return nil
}
if let result = task?.result {
// Do something with result
print("The result is... \(result)")
}
return nil
}
}
As pointed out in the comments below, I'm getting the following result because it's printing out the address of the object:
You clicked invoke api...
The result is... <AmplifyRestApiTest.Empty: 0x600002020770> {
}
(where AmplifyRestApiTest is the name of my Xcode project.)
UPDATE When I set a breakpoint on the print statement, this is what I see in the Debug pane:
UPDATE 2
When I type task?.result there are two viable properties as per this answer from the Amplify team: error and result. So, since my API responds successfully I am assuming I just don't know how to view result.
Can someone help me understand what steps I must take to access members of this class object?
Here is the corresponding method in the API Gateway-generated iOS Swift SDK code:
/*
#param operand2
#param _operator
#param operand1
return type: Empty
*/
public func calcGet(operand2: String, _operator: String, operand1: String) -> AWSTask<Empty> {
let headerParameters = [
"Content-Type": "application/json",
"Accept": "application/json",
]
var queryParameters:[String:Any] = [:]
queryParameters["operand2"] = operand2
queryParameters["operator"] = _operator
queryParameters["operand1"] = operand1
let pathParameters:[String:Any] = [:]
return self.invokeHTTPRequest("GET", urlString: "/calc", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: nil, responseClass: Empty.self) as! AWSTask<Empty>
}
I'm fairly certain this return type of Empty refers to the Empty model defined for the REST API as shown in the screenshot below. I think it's "empty" because the API doesn't alter the response from the Lambda function back to the Client. So, it's all pass-through. Indeed, the tutorial explains that the other models -- Output and Result -- are not used because it "relies on the passthrough behavior and does not use this model."
Any thoughts?

Checking metadata of Amazon S3 file using iOS AWS SDK in Swift

I am using the AWS iOS SDK v2, and Swift 1.2.
I am storing my app's app.json file on S3 and want to check it at launch to see if it's been updated since the last run. According to research, simply doing a HEAD request on the object should return the "Last-Modified" attribute which can then be compared to the previous.
The problem is that doing a HEAD request on an Object doesn't really seem to be well documented. I've got the following:
var metaDataRequest = AWSS3HeadObjectRequest()
metaDataRequest.bucket = S3BucketName
metaDataRequest.key = S3AppJSONKey
This seems like a decent start, however I cannot find a way to execute the request. The AWSS3TransferManager has a download() method, but the method requires an AWSS3TransferManagerDownloadRequest type, which an AWSS3HeadObjectRequest cannot be cast as.
Not sure where to go from here, short of just doing the request outside of the SDK. I did, however, want to leverage as much of the SDK as possible, so if this is possible I would love to know how.
You need to use AWSS3 (instead of AWSS3TransferManager) to call - headObject:.
You need to call headobject method of AWSS3
var request = AWSS3HeadObjectRequest()
request.bucket = "flkasdhflhad"
request.key = "hfsdahfjkhadjkshf"
request.ifModifiedSince = NSDate()
var s3 = AWSS3.defaultS3()
s3.headObject(request) { ( output1 : AWSS3HeadObjectOutput?, error : NSError?) -> Void in
print( output1?.description())
}
if your object is modified from specified date then it will return u the object otherwise it will return u the status code 304.
You can use following Swift 2.2 method to check if file exist or not
func checkIfFileExist() {
let s3 = AWSS3.defaultS3()
let headObjectsRequest = AWSS3HeadObjectRequest()
headObjectsRequest.bucket = "YourBucketName" //Don't add "/" at end of your bucket Name
headObjectsRequest.key = "YourFileNameYouWantToCheckFor" //Don't add "/" in start of file name
s3.headObject(headObjectsRequest).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
print("Error to find file: \(error)")
} else {
print("fileExist")
}
}
}
Note: Example to set bucket and key
suppose you have bucket named "ABC" and than folder named "XYZ" and than inside "XYZ" you have file "abc123"
than write
headObjectsRequest.bucket = "ABC/XYZ"
and
headObjectsRequest.key = "abc123"
and if you want to check for the entire folder
than use
headObjectsRequest.bucket = "ABC/XYZ"
and
headObjectsRequest.key = ""
Thanks Mohsin

execute put item request - AWS DynamoDB ios SDK

Looked all over SO and through Amazon's docs as well, but couldn't find any solid documentation on how to make a put request using iOS SDK, specifically using Swift.
I gather that I need to instantiate an AWSDynamoDBClient first (https://aws.amazon.com/articles/7439603059327617) but don't see that appear as a type when I'm working in xcode.
I've honestly only got two lines of code after all this struggle:
var myDynamoDBPutRequest:AWSDynamoDBPutRequest = AWSDynamoDBPutRequest()
myDynamoDBPutRequest.item = ["fbid": "test"]
I can't figure out how to run it, and doubt that request is set up properly anyway. I've also looked at PutItemInputs, but not sure how that differs from putRequest.item. If anyone can just point me in the right direction I'll be happy to investigate on my own - I'm just running out of places to look for good documentation :/
EDIT:
I've made a bit of progress, but still can't figure out how to properly create a put item input . Here is the code I have now:
var myPutItemInput:AWSDynamoDBPutItemInput = AWSDynamoDBPutItemInput()
myPutItemInput.tableName = "mytable"
var myDynamoDB = AWSDynamoDB.defaultDynamoDB()
myDynamoDB.putItem(myPutItemInput).continueWithBlock { (task:BFTask!) -> AnyObject! in
if(task.result != nil){
let myPutOutput = task.result as AWSDynamoDBPutItemOutput
println(task.result)
}else{
println("task.result was nil for put item request")
}
return nil
}//end put item task
right now I at least figured out how to execute the request, but the result is nil each time.
Here is an example of - putItem:
let dynamoDB = AWSDynamoDB.defaultDynamoDB()
let putItemInput = AWSDynamoDBPutItemInput()
putItemInput.tableName = "testTableName"
let hashValue = AWSDynamoDBAttributeValue()
hashValue.S = "testPutItem"
let stringValue = AWSDynamoDBAttributeValue()
stringValue.S = "stringValue";
putItemInput.item = [
"hashKey" : hashValue,
"stringKey" : stringValue
]
dynamoDB.putItem(putItemInput).continueWithBlock { (task:AWSTask?) -> AnyObject? in
if(task.error != nil) {
println(task.error)
}
if (task.result != nil) {
let putItemOutput = task.result as AWSDynamoDBPutItemOutput
println(putItemOutput)
}
return nil
}
Even though it's in Objective-C, looking at the integration tests may help understand how to use Amazon DynamoDB with the AWS Mobile SDK for iOS v2.

Resources