Does anyone have a working XCode 8 Swift 3 Project with OAuth Simple Auth they mind sharing?

Does anyone have a working compiling XCode 8 Swift 3 project using OAuth Simple Auth, that they would mind sharing for example purposes??? Been asking the Particle Dev Team, but they dragging getting back to me. Also, I am happy to send someone one of my projects for troubleshooting, if you want to lend a hand with the issue. Thanks a lot in advance.

Hi @sdevo619,

I’m not 100% sure if we have an xcode 8 / swift project in here, but for reference here are some of our iOS example projects:

I hope that helps!

Thanks,
David

David,
Thank you very much. Unfortunately, I have been there, and am still stuck. I just sent the my Xcode 8 project to Ido, your lead mobile engineer, to take look at, because I have not been able to get through the OAuth Simple Auth setup process, without getting stuck where I am right now. I am still seeing this error a lot. On a positive note, he also mentioned to me that we is planning to update the project files on the website to the newest versions of Xcode next week.

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[myAccessories.ViewController sparkSetupViewController:didFinishWithResult:device:]: unrecognized selector sent to instance 0x7f803a50ae30’
*** First throw call stack:
(
0 CoreFoundation 0x00000001136eb34b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010fca721e objc_exception_throw + 48
2 CoreFoundation 0x000000011375af34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x0000000113670c15 forwarding + 1013
4 CoreFoundation 0x0000000113670798 _CF_forwarding_prep_0 + 120
5 SparkSetup 0x000000010f6b49f3 __51-[SparkSetupMainController setupDidFinishObserver:]_block_invoke + 131
6 UIKit 0x0000000110710684 -[UIPresentationController transitionDidFinish:] + 1289
7 UIKit 0x0000000110927f43 -[_UICurrentContextPresentationController transitionDidFinish:] + 42
8 UIKit 0x0000000110714120 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 183
9 UIKit 0x00000001110d8fbd -[_UIViewControllerTransitionContext completeTransition:] + 102
10 UIKit 0x000000011070d00c -[UITransitionView notifyDidCompleteTransition:] + 251
11 UIKit 0x000000011070cd1f -[UITransitionView _didCompleteTransition:] + 1539
12 UIKit 0x000000012305b993 -[UITransitionViewAccessibility _didCompleteTransition:] + 42
13 UIKit 0x000000011070f74c -[UITransitionView _transitionDidStop:finished:] + 104
14 UIKit 0x0000000110620475 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 222
15 UIKit 0x00000001106209ca -[UIViewAnimationState animationDidStop:finished:] + 136
16 UIKit 0x000000012309270d -[UIViewAnimationStateAccessibility animationDidStop:finished:] + 121
17 QuartzCore 0x0000000116b18990 _ZN2CA5Layer23run_animation_callbacksEPv + 316
18 libdispatch.dylib 0x00000001133950cd _dispatch_client_callout + 8
19 libdispatch.dylib 0x00000001133758d6 _dispatch_main_queue_callback_4CF + 406
20 CoreFoundation 0x00000001136af4f9 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9
21 CoreFoundation 0x0000000113674f8d __CFRunLoopRun + 2205
22 CoreFoundation 0x0000000113674494 CFRunLoopRunSpecific + 420
23 GraphicsServices 0x000000011632da6f GSEventRunModal + 161
24 UIKit 0x0000000110593964 UIApplicationMain + 159
25 touchTHCAccessories 0x000000010f528ebf main + 111
26 libdyld.dylib 0x00000001133e168d start + 1
27 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

Here is my implementation of that function:

func sparkSetupViewController(_ controller: SparkSetupMainController!, didFinishWith result: SparkSetupMainControllerResult, device: SparkDevice!) {

    if result == .loggedIn
    {
        print("Logged In")
    }
    if result == .skippedAuth
    {
        print("...Skipped Auth...")
    }
    if result == .userCancel{
        print("...User Canceled...")
    }
    if result == .success{
        print("...Finished Successfully...")
    }
    if result == .successDeviceOffline{
        print("...Success Device Offline...")
    }
    if result == .successNotClaimed{
        print("...Success Device Not Claimed...")
    }
    if result == .failureClaiming{
        print("...FAILURE CLAIMING...")
    }
    if result == .failureConfigure{
        print("...FAILED TO CONFIGURE...")
    }
    if result == .failureLostConnectionToDevice{
        print("...FAILED LOST CONNECTION...")
    }
    
}

Do I need to pass anything to the particle cloud in the didFinishWithResult function???

At the top of my view controller I am importing:
import Spark_SDK
import SparkSetup

In the App Delegate:
In didFinishLaunchingWithOptions:
let keys = MyaccessoriesKeys()
SparkCloud.sharedInstance().oAuthClientId = keys.oAuthClientId()
SparkCloud.sharedInstance().oAuthClientSecret = keys.oAuthSecret()

Podfile:

pod 'Spark-SDK’
pod ‘SparkSetup’

plugin ‘cocoapods-keys’, {
:project => “MyAccessories”,
:keys => [
“OAuthClientId”,
“OAuthSecret”
]}


My Bridging Header File:
#include “SparkSetup.h”
#include “MyaccessoriesKeys.h”
#include “Spark-SDK.h”

Login portal customization function(which i have tried running in the view did load as well as prior to the func that launches the Particle Portal Login Controller):

func customSetup(){

    let custom = SparkSetupCustomization.sharedInstance()
    
    custom?.allowPasswordManager = true
    
    custom?.linkTextColor = UIColor.white
    //custom?.normalTextFontName = "Gotham-Medium"
    //custom?.boldTextFontName = "Gotham-Medium"
    //custom?.headerTextFontName = "Verdana"
    custom?.lightStatusAndNavBar = true
    custom?.tintSetupImages = true
    custom?.normalTextColor = UIColor.white
    custom?.brandImageBackgroundColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 0.25)
    custom?.elementTextColor = UIColor(red: 0, green: 186.0/255.0, blue: 236.0/255.0, alpha: 1.0)
    custom?.elementBackgroundColor = UIColor.white
    custom?.organization = true
    custom?.organizationName = "My Organization"
    custom?.organizationSlug = "my product slug"
    custom?.productName = "My Product"
    custom?.productSlug = "my product slug"
    
    let keys = MyaccessoriesKeys()
    
    SparkCloud.sharedInstance().oAuthClientId = keys.oAuthClientId()
    SparkCloud.sharedInstance().oAuthClientSecret = keys.oAuthSecret()
    
    
}

Any ideas??
What’s missing???

Hi @sdevo619,

Hmm, some googling gave this result:

Thanks!
David

I appreciate the help Dave, but none of those ideas worked, and just caused everything to crash out. I have tried wiring up the button in my project both through Interface Builder and through code, only to get the same result both ways. I have made sure I don’t have multiple actions attached to it as well. I have sent your iOS Engineer, Ido, my entire Xcode Project, but have yet to receive a response since I sent it to him. I am happy to send it to you too, if it will speed up the manner in which this gets resolved. Still stuck though, and waiting…

1 Like

Hi @sdevo619,

Sorry about the delays! We try to help when we can, but I know he’s busy. I haven’t played with Swift / Xcode 8 yet, so I probably wouldn’t be much help. Hopefully he’ll get a chance to look it over soon.

Thanks,
David

Thanks very much for trying. I will keep waiting for as long as I can to get an answer. Hope it won’t be too much longer though. The Xcode Project I sent him, literally has one button in it, so the code is very simple, as I did not want to complicate things. I know he mentioned he would be updating the example docs on the website for Swift 3 this week, so one way or another I am hoping to have this fixed sometime this week. Once I do, I will update my posts. Please update the Authentication sections of the website so people know how productSlugs are used inside the Xcode project better. Also, what the relevancy of orgSlugs is in relation to the Xcode project, as that section still needs more work and to be update to reflect changes you’ve made regarding the organizationSlug and organizationName. I am still not sure I understand, because Harrison told me orgSlugs don’t exist anymore, but when I remove the orgSlugs or you don’t specify an organization in the Xcode project, even though there is nowhere to set one in the Particle Console, it errors out on account signup and login, with Xcode reporting “Organization not found” in the logging console. What needs to be passed to the Particle Cloud from the Xcode Project/iOS App, and in what order, in order for a the signup to work properly and get attached to my product specifically?? Can I pass it to the Cloud in the SparkSetupCustomization function call or does it need to be done when you call the setup to SparkSetupMainContoller(to present the Particle Login Page), or in the function where I inject the access token. In the example app it shows it being done in the SparkSetupCustomization. None of this process is made clear in your current docs though.

David,
Great news. I figured out all of my issues on my own. I appreciate you guys helping as much as you did, and please let @ido know that figured out the problems. The issue where setup was crashing on cancel and all the issues with me not being able to claim a photon under my product are now resolved. It ended up being just one line of code that needed to be removed.

Crashing:

  func mySparkCloudLogin(){
        if let setupController = SparkSetupMainController()
        {
            setupController.delegate = self //<--crash culprit
            
            self.present(setupController, animated: true, completion: nil)
        }
    }

Working with NO Crashing issues and able to claim devices using simple auth, with users showing up in the console properly of my product:

  func mySparkCloudLogin(){
        if let setupController = SparkSetupMainController()
        {
            self.present(setupController, animated: true, completion: nil)
        }
    }

Sorry for bugging you guys so much. Thank’s for doing as much as you did. One followup question. Is it possible to wire up a button or switch to one of the input pins, so that when pushed, would put the photon into listening mode. I would like to create a small reset button for my product, similar to what you would find on a router, and as it may not be easy to get to the photons actual buttons, I want to know if this can be done with code. If so, can you point me to necessary docs to do that? Thanks again.

Look at WiFi.listen() in the docs

1 Like

Thanks for pointing this out - I don’t think it says anywhere in the docs to include this in the bridging header (at least I didnt see it). In the reference docs where it shows what to put in your AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    var keys = YourappnameKeys()
    SparkCloud.sharedInstance().OAuthClientId = keys.oAuthClientId()
    SparkCloud.sharedInstance().OAuthClientSecret = keys.oAuthSecret()

    return true
}

you will obviously get a “Use of unresolved identifier” error, since you havent declared what a YourappnameKeys object is.

Putting #include "YourappnameKeys.h" in your bridging header and updating your pods will prevent this

Hi @sdevo619
I have not seen the same error but in your pod file I don’t see AFNetworking 3.0 included. Here is my full pod file. Hope that help. I have my own problem trying to Create a Customer step in OAuth process for my Xcode project.

source 'https://github.com/CocoaPods/Specs.git
platform :ios, ‘8.0’

target ‘ProjectName’ do

Comment the next line if you’re not using Swift and don’t want to use dynamic frameworks

use_frameworks!

Pods for ProjectName

pod 'SparkSetup'
pod 'Spark-SDK'
pod 'AFNetworking', '~> 3.0'
plugin 'cocoapods-keys', {
    :project => 'ProjectName',
    :keys => [
    'OAuthClientId',
    'OAuthSecret'
    ]}

end