Getting started with building an iOS - where do I start?

Hi there Particle Peeps,
I’m trying to make an app to control my arduino-brained clothes dryer. I’ve downloaded the iOS SDK for spark/photon/particle, but I don’t really understand what the heck is going on with it.
Where do I start? How can I take the SDK and turn that into a “blink LED” command?
Any help is appreciated, as I’m a complete Swift/Objective C noob. Incidentally, which is better for noobs, Swift or Obj C?

Thanks,
JR

Is that an actual Arduino, or are you using one of the Particle devices? The SDK is made for the Particle ecosystem, and will have little/no use for ‘regular’ Arduinos.

The documentation never hurts, I guess…

Well, you don’t. The SDK won’t do any blinking. It’s a wrapper around the cloud interactions. You can create a “blink a led” program on one of the devices, and have the SDK call a function to trigger that. It makes the interactions with the cloud easier, and allows you to use the setup process without too much of a hassle. You won’t be able to code your Particle device with xCode though, if that’s what you were expecting.

Slightly unrelated: do you have any experience creating iOS apps? If not, are you aware you need an Apple computer for xCode, a developers license ($99/year), and an iOS app will (obviously) only work on iOS? Depending on what your planning on doing with it, a web app is perhaps easier, using the ParticleJS SDK for example.

1 Like

Is that an actual Arduino, or are you using one of the Particle devices? The SDK is made for the Particle ecosystem, and will have little/no use for ‘regular’ Arduinos.

Currently a regular old Uno, but I have a Photon, so the idea is to replace the arduino with the Photon and have a web enabled clothes dryer.

The documentation1 never hurts, I guess…

The Docs are not very n00b friendly, I’m afraid. I mean, I can make my LED switch on/off with requests in Python, no problemo, but I don’t quite see how that’s done from iOS.

Well, you don’t. The SDK won’t do any blinking. It’s a wrapper around the cloud interactions. You can create a “blink a led” program on one of the devices, and have the SDK call a function to trigger that. It makes the interactions with the cloud easier, and allows you to use the setup process without too much of a hassle. You won’t be able
to code your Particle device with xCode though, if that’s what you were expecting.

Yes, I get that. Xcode handles the talkie bits and build.particle.io handles the blinky bits.

Slightly unrelated: do you have any experience creating iOS apps?

Nope

If not, are you aware you need an Apple computer for xCode

yep

, a developers license ($99/year),

I hadn’t considered that …
Back to Django (the D is silent) again.

Thanks!
JR

1 Like

I have had good luck using Flask which is a bit simpler than Django. I would be happy to share what I have done. I have chosen to use a Web page for this and it works great.

On another note, I built a remote system using both a Spark Core and then duplicated the functionality using an Arduino Leonardo and a Raspberry Pi communicating over USB serial.

@JL_678 I’d love to see what you did. I’m not married to django, we use it at work, so that was my first thought.

I was thinking or 'duino and PI, but photon is cheaper than pi. I may get another pi2 to act as a web server, but that’s another thing :slight_smile:

Okay, see below. The first thing I found is that it is much faster to encapsulate multiple variables inside a delimited spark variable. (; is the delimiter in my case) This allows the algorithm to call one spark variable and get all the data it needs versus having to make multiple separate REST queries. (The last version made 4 separate REST calls.) In testing, this increased performance by about 50%. Naturally, your mileage will vary and it will depend on your code.

Finally, I am no Python/Flask expert and so there is probably lots of room for further code improvement. I am open to any suggestions.

Others here have suggested that a better way to do this is using Javascript for dynamic page updates which I agree with, but I have not gotten around to re-working the code. As it stands, a page refresh is required to update the data.

Without further ado, here you go.

The base code:

from flask import Flask, render_template, request, url_for, redirect, session
import sparkfunction

app = Flask(__name__)

@app.route('/')
def DataNow():
	dataDict = sparkfunction.VarUpdate("delimOT")
	dataVals = dataDict.split(";")
	tempdata = dataVals[0]
	ledstatus = ledsparkvar(int(dataVals[1]))
	utimedata = dataVals[2] + " Days, " + dataVals[3]+":" + dataVals[4] + ":" + dataVals[5]
	
	authcookie = False
	if 'authuser' in session:
		authcookie = True
	if (request.args.get('auth') == 'xxx') or (authcookie):
		authbool = True
	else:
		authbool = False	
	return render_template('sparktemplate.html', tempdata=tempdata, utimedata=utimedata, ledstatus=ledstatus, authbool=authbool)

@app.route('/led', methods=['POST'])
def LEDChange():
	sparkfunction.sparkLED(request.form['LED'])
	session['authuser'] = 'xxx'
	session.permanent = True
	return redirect('./')

def ledsparkvar(ledstatusInt):
	if ledstatusInt == 1:
		ledstatus = "On"
	elif ledstatusInt == 0:
		ledstatus = "Off"
	else:
		ledstatus = "LED Error"
	return ledstatus

Spark access is encapsulated in a function:

import json, requests, ssl, sys

devID = "xxxx"
AToken = "yyyy"    

def VarUpdate ( varName):
        spark_url = "https://api.spark.io/v1/devices/%s/%s?access_token=%s" % (devID,varName,AToken)
        r = requests.get(spark_url)
        data = r.json()
        jsonData = "result"
        OutputData = data[jsonData]
        return OutputData

def sparkLED(appName):
  spark_url = "https://api.spark.io/v1/devices/%s/%s" % (devID,appName)
  payload = {'access_token':AToken}
  r = requests.post(spark_url, params=payload)
  data = r.json()
  jsonData = "return_value"
  return

@JL_678 this is great! Certainly seems easier than Django…
I wonder if you can share your Spark code and html template code, too?
All I want is to make some buttons and get some variables; should be easy, right? :slight_smile:

Thanks,
JR

Hi,

Sure, my template is very basic. The Spark code is a bit more involved.

Template:

<!doctype html>
<head>
<title>Current Data</title>
</head>

    <h1>Temperature is: {{ tempdata }}<br>
        Uptime is: {{ utimedata }}</h1>
<form>
<input type="button"  onClick="history.go(0)" value="Refresh">
</form>
<hr>
<h1>LED Control</h1>
<h2>Current Status: {{ ledstatus }}</h2>
{% if authbool %}
<form name="LEDaction" method="post" action="led">
<input type="radio" name="LED" value="ledon">On
<br>
<br>
<input type="radio" name="LED" value="ledoff">Off
<br>
<br>
<input type="submit" name="Submit"value="Submit">
</form>
{% endif %}

Spark code:

#include "Adafruit_GFX.h"

#include "Adafruit_LEDBackpack.h"
#include "Adafruit_MPL3115A2/Adafruit_MPL3115A2.h"

Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();
Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();

float tempF;
int tempFi;
int LEDint;
boolean ledonoff = true;
boolean tempupdate = true;
int PreviousTime;
const int interval = 10; //update every 5 seconds
char delimString[40];


void setup() {
  alpha4.begin(0x70);

  Spark.variable("delimOT",delimString, STRING); //delimited sensor/uptime data
  Spark.function("ledon", ledon);
  Spark.function("ledoff", ledoff);
  while(! baro.begin()) {
    delay(1000);
  }
  PreviousTime = Time.now() - interval - 1;
}

void loop() {
    if (Time.now() - PreviousTime > interval){   //non-blocking time loop
      PreviousTime = Time.now();
      tempF = baro.getTemperature()*9/5+32;
      tempFi = (int) tempF;
      tempupdate = true;
    }
    LEDint = (int) ledonoff;   //convert ledonoff boolean to integer
    sparkPub(millis());   //calculates uptime and updates spark variable
    
    if (ledonoff){ // LED On and show temp
        if (tempupdate){
            displayascii(32,tempFi%100/10+48,tempFi%10+48,32);
            tempupdate = false;
        }
    }
    else{ // LED Off
      displayascii(32,32,32,32);  
    }
}

void displayascii(int first, int second, int third, int fourth){
    alpha4.writeDigitAscii(0, first);
    alpha4.writeDigitAscii(1, second);
    alpha4.writeDigitAscii(2, third);
    alpha4.writeDigitAscii(3, fourth);
    alpha4.writeDisplay();
}

void sparkPub(unsigned long now) {
    unsigned nowSec = now/1000UL;
    unsigned sec = nowSec%60;
    unsigned min = (nowSec%3600)/60;
    unsigned hours = (nowSec%86400)/3600;
    unsigned days = (nowSec/86400);
    sprintf(delimString,"%i;%i;%u;%u;%u;%u",tempFi,LEDint,days,hours,min,sec);
}

int ledon(String args2){
    ledonoff = true;
    tempupdate = true;
    return 10;
}

int ledoff(String args2){
    ledonoff = false;
    return 20;
}