iOS SDK woes - cannot create client

I am attempting to get an iOS client connected to the Particle cloud, create a user and associate a photon - following the simple AUTH procedure outlined here: https://docs.particle.io/guide/how-to-build-a-product/authentication/#simple-authentication and the specific iOS Spark-SDK instructions here: https://cocoapods.org/pods/Spark-SDK The initial part of having a new client create a login using the oAUTH client id and secret does not work. The relevant code snippets (swift3, iOS10) are:

in my AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
	SparkCloud.sharedInstance().oAuthClientId = “MyClientId”
	SparkCloud.sharedInstance().oAuthClientSecret = “MyClientSecret”
 }

with “MyClientId” and “MyClientSecret” being the values obtained from the particle console. Starting the customer sign up process with:

@IBAction func setupDeviceBtn(_ sender: Any) {		
	if let setupController = SparkSetupMainController(authenticationOnly: true)   {						
		setupController.delegate = self
		self.present(setupController, animated: true, completion: nil)
	}
}

This call fails with status code 400; user credentials are invalid. However, I can use the user/pwd I just supplied to the app to login particle.io/console and get logged in. Also, when I run this code again, providing the same credentials, I get an error stating that the user already exists.

I also tried the tinker iOS app found here:https://github.com/spark/spark-setup-ios-example which give the same errors and problems (after fixing all the code issues this repo has - has Particle abandoned this?)

I see NO way that the current SDK can work (has anyone?). I’d love some help from particle. @Ido, anyone?

Hello,

Let me ping someone for you that might be able to help, @rickkas7 are you able to help him?

Kyle

Sounds like you’re mistakenly trying to sign up rather than log in (hence the “user exists” error)…

Indeed i am trying to sign up, not login - how is this wrong? Notice that I simple checked to see if the user had been created by running the method again i.e., the “user exists” error is a confirmation that the sign up process worked at least partially.

Are you saying you getting a 400 error on every signup (even new non-existing user)?
Can you also report which error string you’re getting?

yes, thats what i am saying.

This is what I get in the debugger:
2017-05-08 08:15:55.139298-0700 particleAUTHtest[5372:320163] [Common] _BSMachError: port 1553; (os/kern) invalid capability (0x14) “Unable to insert COPY_SEND”

2017-05-08 08:15:55.139756-0700 particleAUTHtest[5372:320163] [Common] _BSMachError: port 1553; (os/kern) invalid name (0xf) “Unable to deallocate send right”

2017-05-08 08:15:55.170412-0700 particleAUTHtest[5372:322428] PAC Fetch failed with error [NSURLErrorDomain:-1003]

2017-05-08 08:15:55.170890-0700 particleAUTHtest[5372:322452] [] nw_proxy_resolver_create_parsed_array PAC evaluation error: NSURLErrorDomain: -1003

2017-05-08 08:15:56.131 particleAUTHtest[5372:320163] ! loginWithUser https://api.particle.io/oauth/token Failed (status code 400): {

error = “invalid_grant”;

“error_description” = “User credentials are invalid”;

}

BTW, your colleague “Rick” is looking into this also.

Well, my friend, your debugger output:

proves you are trying to login and not signup... and invalid credentials means that either the username or password is wrong. Please double check what you're doing.

ah since we’re friends now :wink: – the code I posted above is what produced “! loginWithUser https://api.particle.io/oauth/token” At no point in the iOS code do I call:

SparkCloud.sharedInstance().login()

It is a very small iOS test app that only tries to get the user to sign up so I think I know all my code :smiley:

So when I drill into the SparkSetup lib with the debugger after calling
self.present(setupController, animated: true, completion: nil)

it calls:

(NSURLSessionDataTask *)createUser:(NSString *)username
                           password:(NSString *)password
                        accountInfo:(nullable NSDictionary *)accountInfo
                         completion:(nullable SparkCompletionBlock)completion

That certainly doesn’t look like a login() to me. It fails on calling:

NSURLSessionDataTask *task = [self.manager POST:@"/v1/users/" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)

which comes back with the error code described above.

OK, let me know - are you using latest version of the SDKs?
Cocoapods / carthage method?
I’ll look into that

Yep latest SDKs, using cocoapods (Spark-SDK v0.6.0, SparkSetup v0.7.0).

Alright, I hang my head in shame but with a smile, issue solved. With @rickkas7 help the important bit that was left out in my code was the customization of the product ID, mode and name. So the proper setup prior to calling the setupController should be:

@IBAction func setupDeviceBtn(_ sender: Any) {		
  if let setupController = SparkSetupMainController(authenticationOnly: true)   {
    if let c = SparkSetupCustomization.sharedInstance() {
      c.productMode = true
      c.productName = "YourProductName"
      c.productId = YourProductId // in particle/console, right next to your product name
    }
    setupController.delegate = self
    self.present(setupController, animated: true, completion: nil)
  }
}

And of course your oAuth Id and Secret need to be set in AppDelegate or at least prior to calling the method above.

Hopefully this helps some others struggling with this also. Now, on to the next problem (hey its software, you know there is always a next problem to solve :slight_smile: )

1 Like

Uh, way to go @rickkas7 ! you never mentioned you were trying to create an app for a product, thought it a user app. Glad its solved! Did you create your oauth client id and secret in the console?

Yes oAuth client & secret were created in the console. Not sure what you meant by ‘user app’ vs ‘product app’. The app is intended for users of a product so does that make it a ‘user app’ or ‘product app’ (grin).

Yes the connotational use of everyday words is a bit confusing :sunglasses:
I guess Ido meant a developer application running on an individual Particle device not on a device that was part of the Particle based Product.

If your firmware does contain the PRODUCT_ID() macro and the device running that firmware has been added to a Product in console.particle.io/products then it is here refered to as a product app.
But if the same code with out the macro runs on a “generic” device it’s refered as user app or better as a developer app.

And both of these options do need to address the authentication issue a bit differently.

@ScruffR thanks that helps. I did have the PRODUCT_ID() macro but discovered that the ID I provided was different from the product ID in the console. That didn’t seem to bother the setup procedure though - so where/when does the firmware PRODUCT_ID() come into play?

The product ID and version macros inform the cloud what version of the firmware is installed on the device. If it doesn’t match the current default product firmware version, or the lock and flash version if that’s specified for the device, the cloud will force a firmware flash of your device (unless it’s marked as a product development device).

If you had the wrong product ID macro in the on-device firmware, it would just flash the correct product firmware after the first connection to the cloud after successfully configuring.

1 Like