Saving HealthKit Data & Closures

iOS 8 HealthKit Santiapps Marcio Valenzuela
iOS 8 HealthKit

This code bit saves:

  healthKitStore.saveObject(bmiSample, withCompletion: { (success, error) -> Void in
    if( error != nil ) {
      println("Error saving BMI sample: \(error.localizedDescription)")
    } else {
      println("BMI sample saved successfully!")
    }
  })

The method signature is:

saveObject(object: HKObject!, withCompletion completion: ((Bool, NSError!) -> Void)!)

This method takes an HKObject which is bmiSample

and it takes a completion closure which itself takes a bool & error and returns void.

So in our method call, we pass in the bmiSample as the HKObject and for the success and error completion block we say:

if error is NOT nil then log that error’s description,

else log that the bmiSample was saved successfully.

 

 

This code bit reads:

// 2. Call the method to read the most recent weight sample
self.healthManager?.readMostRecentSample(sampleType, completion: { (mostRecentWeight, error) -> Void in
 
  if( error != nil )
  {
    println("Error reading weight from HealthKit Store: \(error.localizedDescription)")
    return;
  }
 
  var weightLocalizedString = self.kUnknownString;
  // 3. Format the weight to display it on the screen
  self.weight = mostRecentWeight as? HKQuantitySample;
  if let kilograms = self.weight?.quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) {
    let weightFormatter = NSMassFormatter()
    weightFormatter.forPersonMassUse = true;
    weightLocalizedString = weightFormatter.stringFromKilograms(kilograms)
  }
 
  // 4. Update UI in the main thread
  dispatch_async(dispatch_get_main_queue(), { () -> Void in
    self.weightLabel.text = weightLocalizedString
    self.updateBMI()
 
  });
});

Here we are calling the .readMostRecentSample method which has this signature:

func readMostRecentSample(sampleType:HKSampleType , completion: ((HKSample!, NSError!) -> Void)!)

This method takes an HKSampleType which is sampleType

and it takes a completion closure which itself takes an HKSample & error and returns void.

So in our method call, we pass in the sampleType as the HKSample and for the success and error completion block we say:

if error is NOT nil then log that error’s description,

else get that mostRecentWeight as self.weight, format it and set it as the label’s text.

How does this method get the actual value from the HKHealthStore?  Inside itself, it executes an HKQuery which itself says this:

let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: mostRecentPredicate, limit: limit, sortDescriptors: [sortDescriptor])
    { (sampleQuery, results, error ) -> Void in
 
      if let queryError = error {
        completion(nil,error)
        return;
      }
 
      // Get the first sample
      let mostRecentSample = results.first as? HKQuantitySample
 
      // Execute the completion closure
      if completion != nil {
        completion(mostRecentSample,nil)
      }
  }
  // 5. Execute the Query
  self.healthKitStore.executeQuery(sampleQuery)

Give me:

a.  sampleType

b.  a predicate, limit, sortDescriptors

c. and a completion closure which takes a sampleQuery, results & error

such that;

if error it NOT nil, set the readMostRecentSample method’s completion closure to nil,error

otherwise set the completion closure with the results and no error.

HealthKit for iOS8: Part 7

iOS 8 HealthKit Santiapps Marcio Valenzuela
iOS 8 HealthKit

4. CoreData for other non-health stats

You made it to the end!  Ok, so we are basically going to be adding another store to our app and reading and writing data to THAT store as well.

First let’s add a new tab and make it a UITableViewController as well.  It will have dynamically populated cells.

HealthKit for iOS8
HealthKit for iOS8

Now embed it!

HealthKit for iOS8
HealthKit for iOS8

 

Your final storyboard should look like this:

HealthKit for iOS8
HealthKit for iOS8

 

Add a new Swift class called Swimming Data and set that new UITableViewController scene to its class.  Make that class file look like this:

import Foundation

import UIKit

class SwimmingData: UITableViewController {

}

Now we must add CoreData.  To do this we need to create a CoreData stack and a xcdatamodeld file.  First thing is first, let’s add the xcdatamodeld file by New->File->CoreData->DataModel.  Name it SwimModel.  Create an entity called Swim and add the following attributes:

  • pace : Int16
  • date : Date
  • laps : Int16
  • meters : Double
  • totalTime : Double

Now with the xcdatamodeld file selected, go to Editor and select Create NSManagedObject subclass:

HealthKit for iOS8
HealthKit for iOS8

 

Make sure SwimModel is selected, click Next, make sure to select the Swim entity, click Next and you should get a Swim.swift class like this:

import Foundation
import CoreData
class Swim: NSManagedObject {

@NSManaged var date: NSDate
@NSManaged var laps: NSNumber
@NSManaged var totalTime: NSNumber
@NSManaged var meters: NSNumber
@NSManaged var pace: NSNumber
}

Perfect!  All you need now is your stack!  To do this, again create a New->File->Source->Swift File-> and name it CoreDataStack.  Now replace everything in there with this:

import CoreData

class CoreDataStack {

let context:NSManagedObjectContext
let psc:NSPersistentStoreCoordinator
let model:NSManagedObjectModel
let store:NSPersistentStore?

 

init() {

//1

let bundle = NSBundle.mainBundle()

let modelURL = bundle.URLForResource("SwimModel", withExtension:"momd")

model = NSManagedObjectModel(contentsOfURL: modelURL!)!

 

//2

psc = NSPersistentStoreCoordinator(managedObjectModel:model)

 

//3

context = NSManagedObjectContext()

context.persistentStoreCoordinator = psc

 

//4

let documentsURL = applicationDocumentsDirectory()

let storeURL = documentsURL.URLByAppendingPathComponent("SwimFit4")

 

let options = [NSMigratePersistentStoresAutomaticallyOption: true]

 

var error: NSError? = nil

store = psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: options, error:&error)

 

if store == nil {

println("Error adding persistent store: \(error)")

abort()

}

}

 

func saveContext() {

var error: NSError? = nil

if context.hasChanges && !context.save(&error) {

println("Could not save: \(error), \(error?.userInfo)")

}

}

 

func applicationDocumentsDirectory() -> NSURL {

let fileManager = NSFileManager.defaultManager()

 

let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) as [NSURL]

return urls[0]

}

}

Now since this is not a CoreData tutorial, I will not go into the details, but every CoreData project needs a MOM, MOC and PSC.  That is what we initialize here.

Now we can begin writing to our MOC and PSC.  To test run it, let’s hardcode a value.  Go to the SwimmingData Class and first give it an import CoreData at the top.  Now declare a property for your stack inside your class of course:

lazy var coreDataStack = CoreDataStack()

var workouts = NSMutableArray()

We are creating a CoreDataStack instance and we are creating a mutable array.

Then give it a viewDidLoad method like this:

 

override func viewDidLoad() {

super.viewDidLoad()

//Create Sample Swim object

var description = NSEntityDescription.entityForName("Swim", inManagedObjectContext:coreDataStack.context)

var sampleSwim = Swim(entity:description!, insertIntoManagedObjectContext:coreDataStack.context)

sampleSwim.laps = 24

sampleSwim.meters = 50

sampleSwim.totalTime = 40

sampleSwim.pace = 6

sampleSwim.date = NSDate()

coreDataStack.saveContext()

 

//Add object to array

self.workouts.addObject(sampleSwim)

 

//Refresh UI

self.tableView.reloadData()

}

Now add an identifier for the cell like so:

let JournalViewControllerTableViewCellReuseIdentifier: NSString = "Cell"

as a property at the top of the class.

So of course don’t forget to set the identifier in your storyboard scene.  Finally, implement both datasource methods:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return self.workouts.count

}

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell {

 

let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath!) as UITableViewCell

 

var myWorkout: Swim = self.workouts[indexPath!.row] as Swim

let dateFormatter = NSDateFormatter()

dateFormatter.dateFormat = "yyyy'-'MM'-'dd HH':'mm':'ss"

let date = dateFormatter.stringFromDate(myWorkout.date as NSDate)

println(date)

cell.textLabel.text = date

 

cell.detailTextLabel!.text = myWorkout.totalTime.stringValue

 

return cell;

}

And don’t forget to set your cell type to Right Detail in your storyboard.  If you Build & Run and switch to the newly created tab, you might get a crash saying:

Unable to load class Swim …

This is because you need to fully qualify the class name in CoreData, so select your xcdatamodeld file and with your Swim entity selected, make sure to append the Class name in the inspector on the right like so:

HealthKit for iOS8
HealthKit for iOS8

Basically you need to ensure that you append your project name to the Class name field.

Now run your app and go over to the Workouts tab and see your hardcoded workout in the tableview.

Before we move on, let’s take a few minutes to work on some details.  While this provides the info required by the user, it would be nice to polish it up a bit.  First, we should add the letters “mins” to the totalTime displayed in the cell.  Second, it would be nice to format the date a little more such that its more human readable.  So go back to your cellForRowAtIndexPath and make the following changes:

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell {

let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath!) as UITableViewCell

var myWorkout: Swim = self.workouts[indexPath!.row] as Swim

var formatString = NSDateFormatter.dateFormatFromTemplate("EdMMM", options: 0, locale: NSLocale.currentLocale())

let dateFormatter = NSDateFormatter()

dateFormatter.dateFormat = formatString

let date = dateFormatter.stringFromDate(myWorkout.date as NSDate)

println(date)

cell.textLabel.text = date

cell.detailTextLabel!.text = myWorkout.totalTime.stringValue + " mins"

return cell;

}

There, now the user has a little mode detailed info of the data displayed.  We could go on and modify the cell to hold more data or even be selectable such that it would segue into a detail view controller to display all the info.

WRITING TO CORE DATA

Now all that is left to do is actually, remove that viewDidLoad code that writes to CoreData and instead, write to CoreData from our Workout view controller.  So back in WorkoutViewController, first import CoreData at the top, then add this property:

lazy var coreDataStack = CoreDataStack()

and finally, in the saveMyWorkout method, after we calculate our joules burned, or before, it doesn’t matter, add this code:

//E - Perhaps just store laps and meters per lap = total metes in some extra field within the SwimFit app to display it.

var description = NSEntityDescription.entityForName("Swim", inManagedObjectContext:coreDataStack.context)

var sampleSwim = Swim(entity:description!, insertIntoManagedObjectContext:coreDataStack.context)

var numberFormatter = NSNumberFormatter()

var nolaps:NSNumber? = numberFormatter.numberFromString(numberOfLapsValue!)

if let nolaps = nolaps {

sampleSwim.laps = Int(nolaps)

}

var nometers:NSNumber? = numberFormatter.numberFromString(metersPerLapValue!)

if let nometers = nometers {

sampleSwim.meters = Double(nometers)

}

var totime:NSNumber? = numberFormatter.numberFromString(workoutDurationValue!)

if let totime = totime {

sampleSwim.meters = Double(totime)

}

sampleSwim.pace = pace

sampleSwim.date = NSDate()

coreDataStack.saveContext()

This will save that other data, which is not HealthKit or health store data, into CoreData for later use.  Now let’s just go modify our SwimmingData view controller to make it fetch.

You already added a CoreDataStack variable to your SwimmingData view controller, so just add a fetchRequest var like this, right below the CoreDataStack var:

var coreDataStack: CoreDataStack!

var fetchRequest: NSFetchRequest!

Now in viewDidLoad add this neat code:

fetchRequest = coreDataStack.model.fetchRequestTemplateForName("FetchRequest")

This is a stored fetch request and to use it you must head over to the xcdatamodeld.file and create a new FetchRequest, leave its name as FetchRequest and now from the editor leave Swim as the selected entity to fetch from.  Now go back to SwimmingData and add this method:

//MARK - Helper methods

func fetchAndReload(){

var error: NSError?

let results = coreDataStack.context.executeFetchRequest(fetchRequest, error: &error) as [Swim]?

if let fetchedResults = results {

workouts = fetchedResults.copy() as NSMutableArray

} else {

println("Could not fetch \(error), \(error!.userInfo)")

}

tableView.reloadData()

}

And now call this method from viewDidLoad.  This will load your fetched data from CoreData into your tableview.

This will fetch the items in the order they were inserted, but you can also add a sort descriptor.

Add this lazy property at the top of your SwimmingData class:

lazy var dateSortDescriptor: NSSortDescriptor = {

var sd = NSSortDescriptor(key: "Swim.laps",

ascending: true) return sd
}()

Then in the viewDidLoad add this as a property of your fetchRequest:

fetchRequest.sortDescriptors =[dateSortDescriptors]

 NSFETCHEDRESULTSCONTROLLER OPTION

Alternatively you can also use NSFetchedResultsController.  NSFRC is a neat object that is created specifically for fetching and manipulating data from a CoreData query.  Its special in many respects but mainly because it works nicely with table views.  It can store information about table structure and can allow for interaction between its data and the tableview at the same time.  So add this property to the top of your class:

var fetchedResultsController : NSFetchedResultsController!

In your viewDidLoad:

//1
let fetchRequest = NSFetchRequest(entityName: "Swim")
let sortDescriptor = NSSortDescriptor(key: "totalTime", ascending: false) fetchRequest.sortDescriptors = [sortDescriptor] 
//2 fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.context, sectionNameKeyPath: nil, cacheName: nil) 
//3 var error: NSError? = nil 
if (!fetchedResultsController.performFetch(&error)) { 
println("Error: \(error?.localizedDescription)") } 

Now replace your datasource methods with:

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return fetchedResultsController.sections!.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
}

Finally, the way you access data to populate your cell in cellForRowAtIndexPath is:

let mySwim = fetchedResultsController.objectAtIndexPath(indexPath) as Swim

cell.textLabel.text = date
cell.detailLabel.text = mySwim.totalTime.stringValue + " mins"

}

where date would be the formatted value of course.

Well it has been a long journey.  I hope you learned enough about Healthkit to feel comfortable enough to start working on your own app.

Have a good one!

HealthKit for iOS8: Part 6

iOS 8 HealthKit Santiapps Marcio Valenzuela
iOS 8 HealthKit

Here is the start of our WorkOut view controller:

import Foundation
import UIKit
import HealthKit

class WorkoutViewController: UITableViewController, UITextFieldDelegate {

@IBOutlet var numberOfLapsTextField: UITextField!
@IBOutlet var metersPerLapTextField: UITextField!
@IBOutlet var workoutDurationTextField: UITextField!
@IBOutlet var paceTextField: UITextField!
var numberOfLapsValue: NSString?
var metersPerLapValue: NSString?
var workoutDurationValue: NSString?
var userWeight: Double?
var  healthStore:HKHealthStore?
}

We import what we need, we subclass UITableViewController and add the Text Field delegate protocol.  Here I have created 4 labels for:

  • numberOfLaps
  • metersPerLap
  • workoutDuration
  • pace

These labels have an underlying variable for each.  The reason the first 3 are strings is because these are not health kit data per se.  These will be stored in CoreData.  However they really should be NSNumbers because it would be quite nice to store them and take advantage of CoreData’s ability to retrieve ordered data and statistical data in its fetches as well.

Finally we declare our health store property.

First let’s look at our lifecycle methods:

override func viewDidLoad() {

super.viewDidLoad()

self.fetchUsersWeight()

}

func textFieldShouldReturn (textField: UITextField) -> (ObjCBool) {

textField.resignFirstResponder()

if self.numberOfLapsTextField != nil && self.metersPerLapTextField != nil && self.workoutDurationTextField != nil {

}

return true;

}

In viewDidLoad we call a fetchUsersWeight method because we will need that to calculate calories burned.  Then we implement textFieldShouldReturn for each label.  Let’s take a look at that first method called:

func fetchUsersWeight() -> () {

var todayPredicate: NSPredicate = self.predicateForSamplesToday()

var weightType: HKQuantityType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)

self.healthStore?.aapl_mostRecentQuantitySampleOfType(weightType, predicate: todayPredicate, completion: { (weight, error) -> () in

if weight == nil {

NSLog("Sorry, weight is empty...")

return

}

if let someWeight = weight {

var weightUnit: HKUnit = HKUnit.poundUnit()

self.userWeight = weight!.doubleValueForUnit(weightUnit)

}

})

}

Once again we make a fetch using the same extension method and helper predicate method as before.  This exemplifies the use of extensions because we need to include the predicate method in this Workout class, not so the extension.  So go ahead and add the predicate method now:

func predicateForSamplesToday () -> (NSPredicate) {

let calendar: NSCalendar = NSCalendar.currentCalendar()

let now: NSDate = NSDate()

let startDate: NSDate = calendar.startOfDayForDate(now)

let endDate: NSDate = calendar.dateByAddingUnit(.CalendarUnitDay, value:1, toDate:startDate, options:nil)!

return HKQuery.predicateForSamplesWithStartDate(startDate, endDate:endDate, options:HKQueryOptions.StrictStartDate)

}

Ok so the user has 2 options here: Done or Cancel.  Cancel is easy:

@IBAction func cancel(sender: AnyObject) -> () {

self.navigationController?.popViewControllerAnimated(true)

}

Now let’s take a look at Done:

@IBAction func saveMyWorkout(sender: AnyObject) -> () {

//1.  Enter the values for your workout & capture

numberOfLapsValue = numberOfLapsTextField.text

metersPerLapValue = metersPerLapTextField.text

workoutDurationValue = workoutDurationTextField.text

//A - Need to fetch the user's weight in kgs from healthstore

var myWeight: Double = self.userWeight! * 0.453

//B - Need to convert time worked out into hours

//C - Need to select pace from some sort of switch

var pace: Double = (paceTextField!.text as NSString).doubleValue

//D - Throw away numberOfLaps = (numberOfLapsValue! as NSString).doubleValue & (metersPerLapValue! as NSString).doubleValue

var totalCaloriesBurnedByWorkout: Double =  ( (myWeight * pace) ) * ((workoutDurationValue! as NSString).doubleValue)/60

var totalJoulesBurnedByWorkout: Double = totalCaloriesBurnedByWorkout*4.184

//1.5 Set to EnergyVC before saving

let energyVCInstance: EnergyViewController = self.navigationController!.viewControllers[0] as EnergyViewController

energyVCInstance.activeEnergyBurnedValueLabel?.text = NSString(format:"%.2f",totalJoulesBurnedByWorkout)

energyVCInstance.activeEnergyBurned = totalJoulesBurnedByWorkout

energyVCInstance.refreshControl?.endRefreshing()

//2.  Dismiss and set values on EnergyVC such that they can be saved to the healthStore

//Save object to healthstore

// MUST DEFINE HKQUANTITY_TYPE

var quantityType: HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned)

//MUST DEFINE HKQUANTITY

var quantity: HKQuantity = HKQuantity(unit: HKUnit.jouleUnit(), doubleValue:totalJoulesBurnedByWorkout)

//DATE & METADATA

var now: NSDate = NSDate()

var metadata: NSDictionary = ["HKMetadataKey":"Swim Session"]

//WORKOUT TYPE?

var workoutType = HKWorkoutActivityType.Swimming

//This creates the object to SAVE

var energyBurnt: HKQuantitySample = HKQuantitySample(type: quantityType, quantity:quantity, startDate:now, endDate:now, metadata:metadata)

NSLog("Before saving to the healthstore...")

self.healthStore?.saveObject(energyBurnt, withCompletion: { (success, error) in

NSLog("Saving to the healthstore...")

if (error != nil) {

NSLog("The error is: \(error)")

}

dispatch_async(dispatch_get_main_queue(), {

if success {

// This was for updating a uitableview

// Alert User

let alertController = UIAlertController(title: "Success!", message: "Data Saved", preferredStyle: UIAlertControllerStyle.Alert)

alertController.addAction(UIAlertAction(title: "Confirm", style: UIAlertActionStyle.Default, handler: {action in

println("confirm was tapped")

//dismiss this vc

self.navigationController?.popViewControllerAnimated(true)

}))

self.presentViewController(alertController, animated: true, completion: nil)

} else {

NSLog("An error occured saving your workout burn. In your app, try to handle this gracefully. The error was: %@.", error)

abort()

}

})

})

}

This time I take you step by step, once again, inside the same method so as to drive the point home.  First we take all necessary data from labels to make our calculations.  We make our calculation and populate totalJoulesBurnedByWorkout.

Then we set the properties in our EnergyViewController from here before we return.

And before returning, we save our data to the health store, creating an identifier, then a quantity, then a date, then some metadata and finally calling saveObject.  In the saveObject method we return an alertController for success and pop our Workout view controller, because remember this is a navigation stack, not a modally presented view controller.  Else we log an error.

In the final part, we will add CoreData to our project and save laps and meters data into CoreData as well.

C ya!

HealthKit for iOS8: Part 3

HealthKit iOS8 by Santiapps.com
HealthKit iOS8

Great!  Now let’s move on to the Journal View Controller.  It’ll be a good relax! 🙂 Ok we start out importing the frameworks we need:

import UIKit
import HealthKit

Ok now let’s declare our class properties:

class JournalViewController: UITableViewController {     
let JournalViewControllerTableViewCellReuseIdentifier: NSString = "Cell"     
var foodItems: NSMutableArray?     
var energyFormatter: NSEnergyFormatter {         
var energyFormatter: NSEnergyFormatter?         
var onceToken: dispatch_once_t = 0         
dispatch_once(&onceToken, {             
energyFormatter = NSEnergyFormatter()             
energyFormatter?.unitStyle = NSFormattingUnitStyle.Long             energyFormatter?.forFoodEnergyUse = true             
energyFormatter?.numberFormatter.maximumFractionDigits = 2         })         
return energyFormatter!     
}      
var  healthStore:HKHealthStore? 
}

The first thing to note, is that once again this is UITableViewController.  However, unlike Profile, this tableview will contain dynamic, prototype cells.  Thus we need to dequeue our cells to save memory.  The first constant we need is one for our table view cell identifier.  Then we create a mutable array to hold our selected food items, which will come from the user selecting them in the FoodPicker. The next property is a bit strange.  NSEnergyFormatter is something new and health kit uses it to format energy data.  This is a computed property, which means it is computed each time you call for it.  This is basically creating an energyFormatter much in the same way you would create an dateFormatter from NSDateFormatter. Then finally there is the healthstore property which we need and set from the AppDelegate as you recall. Next up we have our view controller lifecycle methods which kick things off:

override func viewDidLoad() {         
super.viewDidLoad()         
self.foodItems = NSMutableArray()         
self.updateJournal()         
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateJournal", name: UIApplicationDidBecomeActiveNotification, object: nil)     }     
override func viewDidDisappear(animated: Bool) {         
NSNotificationCenter.defaultCenter().removeObserver(self, name:UIApplicationDidBecomeActiveNotification, object:nil)     
}

Our viewDidLoad does 2 things; instantiates a mutable array for foodItems so the user can start putting things in there and it calls updateJournal which we will write next.  This view controller also sets itself up as an observer for notifications fired whenever the app becomes active and finally in the viewDidDisappear method we remove ourselves as an observer. Now let’s write updateJournal.  The purpose of this method will be to basically update this tableview with data gotten from the FoodPicker after the user selects items he or she consumed:

func updateJournal () -> () {
var now: NSDate = NSDate()
let calendar : NSCalendar = NSCalendar.currentCalendar()       
var components: NSDateComponents = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: now)
var startDate: NSDate = calendar.dateFromComponents(components)!
var endDate: NSDate = calendar.dateByAddingUnit(.CalendarUnitDay, value:1, toDate:startDate, options:nil)!

var sampleType: HKSampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDietaryEnergyConsumed)
var predicate: NSPredicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate:endDate, options:.None)

var query: HKSampleQuery = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 0, sortDescriptors: nil) {

(query:HKSampleQuery?, results:[AnyObject]!, error:NSError!) -> Void in

if (error != nil) {
NSLog("An error occured fetching the user's tracked food. In your app, try to handle this gracefully. The error was: %@.", error)                 
abort()
}
if results != nil {
NSLog("Got something!")
}
dispatch_async(dispatch_get_main_queue(), {

// PARSE RESULTS INTO ARRAY, RELOAD DATA ALL ON MAIN QUEUE
self.foodItems?.removeAllObjects()
for sample in results as [HKQuantitySample] {                 
NSLog("sample is= \(sample.metadata)")
let foodMetadataDict = (sample.metadata as NSDictionary)
let foodThing: AnyObject? = foodMetadataDict.objectForKey("HKMetadataKeyFoodType")                 NSLog("\(foodThing)")

let foodName = foodThing as NSString
let joules: Double = sample.quantity.doubleValueForUnit(HKUnit.jouleUnit())             
let foodItem: FoodItem = FoodItem(name: foodName, joules:joules) as FoodItem                 self.foodItems?.addObject(foodItem)
}             
self.tableView.reloadData()
})
}
self.healthStore?.executeQuery(query)     // EXECUTE QUERY  }

Ok, its a bit long but simple.  The first few lines create a date for our query.  Then we create a sampleType for DietaryEnergyConsumed which is a data type health store can read and write.  We then create a predicate for it which basically limits the query to today.  Finally we create the query object and execute it (in the last line).

Remember, whats inside the query body is actually a completion block.  We pass the query the sampleType, dates and completion handler.  That completion handler takes a result and an error once again.  If there is an error, we log, if we get results from the query then we log that we got something!  Thats just being silly, but then the query code goes on to a dispatch queue.

This is where we will now update the UI by removing all objects in our foodItems array, and then for every HKQuantitySample in results array, we get the metadata key that we  will store in the object array as part of the FoodItem object and get it as a NSString.

Finally we get the value for that quantity and create a fully qualified FoodItem with that data.  In the end we add that FoodItem to the array and reload the table data. Well now that we mentioned FoodItem, let’s take a look at that class and it’ll help you better understand the next method which is the actual method for adding a FoodItem’s data to the health store.  So here is the FoodItem class:

import Foundation
import HealthKit

class FoodItem {
var name: NSString
var joules:  Double
init (name:NSString, joules:Double) {
self.name = name
self.joules = joules
}

func isEqual(object:AnyObject) -> (Bool) {
if object.isKindOfClass(FoodItem) {
return ((object as FoodItem).joules == self.joules) && (self.name == (object as FoodItem).name)
}
return false;
}

func description(NSString) -> (NSString){
var descriptionDict: NSDictionary = [ "name" : self.name, "joules" : self.joules ]
return descriptionDict.description as NSString
}
}

That was short and sweet!  First we declare the properties of our FoodItem class, name and joules.  Then we create the initializer for it, important to note!  We also added an isEqual function in there to test if an object is a FoodItem type object.  Remember that FoodItem is not subclassing NSObject so it doesn’t have access to NSObject’s isEqual function.  Finally we give FoodItem a description function which basically returns its name and joules values as an NSString. Sweet!  Ok so now let’s look at the Journal view controller method that actually adds a FoodItem:

func addFoodItem (foodItem:FoodItem) {         
// MUST DEFINE HKQUANTITY_TYPE         
var quantityType: HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDietaryEnergyConsumed)         //MUST DEFINE HKQUANTITY         
var quantity: HKQuantity = HKQuantity(unit: HKUnit.jouleUnit(), doubleValue:foodItem.joules)         //DATE & METADATA         
var now: NSDate = NSDate()         
var metadata: NSDictionary = ["HKMetadataKeyFoodType":foodItem.name]         
//This creates the object to SAVE         
var calorieSample: HKQuantitySample = HKQuantitySample(type: quantityType, quantity:quantity, startDate:now, endDate:now, metadata:metadata)          
NSLog("Before saving to health store in Journal...")         self.healthStore?.saveObject(calorieSample, withCompletion: { (success, error) in             NSLog("After saving to healthstore in Journal...")             dispatch_async(dispatch_get_main_queue(), {                 
NSLog("After dispatch to health store in Journal...")                 
if success {                     //MUST UPDATE TABLE in MAIN QUEUE                     NSLog("Energy Consumed Saved")                     
self.foodItems?.insertObject(foodItem, atIndex:0)                     
var indexPathForInsertedFoodItem: NSIndexPath = NSIndexPath(forRow: 0, inSection: 0)                     self.tableView.insertRowsAtIndexPaths([indexPathForInsertedFoodItem], withRowAnimation: UITableViewRowAnimation.Automatic)                 
} else {                     
NSLog("An error occured saving the food %@. In your app, try to handle this gracefully. The error was: %@.", foodItem.name, error)                     
abort()                 
}             
})         
})     
}

It seems long, but the pattern is pretty simple.  We create the right identifier for DietaryEnergyConsumed, we create a quantity from the FoodItem we passed into this method, specifically from its joules value.  We create a date and give it some metadata in order to complete the creation of our HKQuantitySample.  Finally we saveObject to the health store and in its completion block, if success we log Energy Consumed Saved, insert the newly selected item into the foodItems array and update the tableview.  Otherwise we log the error. Finally let’s look at our tableview methods and our segue method because remember that from this Journal view controller we will allow the user to tap the “Add” button to take us to the FoodPicker which we will analyze next.  So here are our tableview and segue methods:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {         return self.foodItems!.count     }

We set our numberOfRowsInSection to the items in our mutable foodItems array.

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell {         
let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath!) as UITableViewCell          
var foodItem: FoodItem = self.foodItems?[indexPath!.row] as FoodItem         cell.textLabel.text = foodItem.name          
cell.detailTextLabel!.text = energyFormatter.stringFromJoules(foodItem.joules)         
return cell;     
}

Here we dequeue a cell as always and create a FoodItem according to the indexPath!.row and get its name and joules into the cell.

func performUnwindSegue(segue:UIStoryboardSegue) { //was typed as ibaction...         
var foodPickerViewController: FoodPickerViewController = segue.sourceViewController as FoodPickerViewController         
var selectedFoodItem: FoodItem = foodPickerViewController.selectedFoodItem! as FoodItem       self.addFoodItem(selectedFoodItem)     
}

As for the segue, this is the initiating view controller, so we need an unwind because when the user finishes selecting an item in the FoodPicker, we must do some stuff.  What stuff?  Well first we get our sourceViewController for the “unwind” segue.  Don’t get confused because normally you get the destination segue of a forward segue in order to set that destination view controller’s properties.  In this case, we are in the calling view controller and we are unwinding from a segue.  Our source view controller is FoodPicker and our destination is Journal.  We then take the source’s selectedFoodItem property and set it as a local variable called selectedFoodItem here, locally, in Journal.  Then we call our addFoodItem() method passing it in that local variable selectedFoodItem.  That saves that food item’s name in metadata and its joules into the health store as DietaryConsumedEnergy. Well, that was quite simple.  The FoodPicker is actually quite simple.  See you there!

Swift is Confusing: Classes, Structures, Designated Initializers, Instance Methods, Type Methods, Functions, Methods, Convenience Initializers & External Parameter Names

Swift is Confusing: Classes, Structures, Designated Initializers, Instance Methods, Type Methods, Functions, Methods, Convenience Initializers & External Parameter Names
Swift is Confusing

Class vs Structs

Both: Store values, initialize, subscripts, extensible & protocol

Class can inherit, de-initialize, reference counting & typecast

Functions vs Methods

Methods are FUNCTIONS INSIDE A CLASS

Functions can be inside or OUTSIDE A CLASS!

Cannot use functionName(param1,param2) to call a function declared inside a class {}

Methods:

  1. It is implicitly passed the object for which it was called
  2. It is able to operate on data that is contained within the class

Instance Methods vs Type Methods (Instance Method vs Class Methods I think)

Methods are functions that are associated with a particular type. Classes, structures, and enumerations can all define instance methods, which encapsulate specific tasks and functionality for working with an instance of a given type. Classes, structures, and enumerations can also define type methods, which are associated with the type itself. Type methods are similar to class methods in Objective-C.

  • class Counter {
  • var count = 0
  • func increment() {
  • count++
  • }
  • }
  • let counter = Counter()
  • counter.increment()

vs

  • class SomeClass {
  • class func someTypeMethod() {
  • // type method implementation goes here
  • }
  • }
  • SomeClass.someTypeMethod()

Class Factory vs Initializer

This is not particular to Swift but may come up in searches.  A Class Factory method is what was know in ObjC as factory methods and I even saw them references as convenience methods or constructors.  These are instead of:

NSArray *someArray = [[NSArray alloc] init]];

they would be:

NSArray *someArray = [NSArray arrayWithObjects:@”One”, @”Two”];

Another example:

  • UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
  • let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

ObjC class or factory methods get mapped as convenience initializers in Swift.  So:

  • UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

gets translated into this:

  • let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

Designated Initializer vs Convenience Initializer

A designated initializer calls its superclass’ init and defines all values added by the self class.  Unless explicitly provided, a class inherits a super initializer from its superclass.

Any other convenience initializer calls self.init and have the convenience keyword before the init keyword.

Initialization must be done in order; own properties, super, super properties.

Initializers & Optionals in one 🙂

  • class SurveyQuestion {
  • let text: String
  • var response: String?
  • init(text: String) {
  • self.text = text
  • }
  • func ask() {
  • println(text)
  • }
  • }
  • let beetsQuestion = SurveyQuestion(text: "How about beets?")
  • beetsQuestion.ask()
  • // prints "How about beets?"
  • beetsQuestion.response = "I also like beets. (But not with cheese.)"

Default Initializers

  • class ShoppingListItem {
  • var name: String?
  • var quantity = 1
  • var purchased = false
  • }
  • var item = ShoppingListItem()

All non-optional values are supplied with a default value and it is a Base Class (because it doesn’t have a super class)

Diagram:

class A {
    var x: Int
    convenience init() {
        self.init(x: 0)
    }
    init(x: Int) {
        self.x = x
    }
}

where init(x:Int) is the designated initializer and any other must have the convenience keyword.

class B: A {
    var y: Int
    convenience init() {
        self.init(y: 0)
    }
    convenience init(y: Int) {
        self.init(x: 0, y: y)
    }
    init(x: Int, y: Int) {
        self.y = y
        super.init(x: x)
    }
}

Parameter Names / Externals / The first

//Default: First Parameter is the local parameter (don't need to specify it), the rest are external parameters
    func greet (name: String, day: String) -> String {
        return "Hello \(name), today is \(day)."
    }
greet("John", day:"Monday")
    //Use Hash symbol to make the First parameter as external parameter
    func greet2 (#name: String, day: String) -> String {
        return "Hello \(name), today is \(day)."
    }
greet(name:"John", day:"Monday")

iOS : Swift : Blocks = Closures

Closure on closures
Closure on closures

I’ve never really liked blocks in ObjC.

When Swift came out it made things more complicated for me because I’ve never really liked C either.

Finally when I had to deal with closures in Swift, well that’s just gonna piss a lot of people off!

After a few days reviewing tons of material online, and I mean TONS!  I came to understand this:

The only C-like exposure I had prior to ObjC was a little PHP.  So that allows me to understand a function, which is the equivalent of a method in ObjC:

DECLARING

func sayHello( ) {

     println(“Hello World”)

}

CALLING

sayHello( )

RESULT

Hello World

Even if you didn’t have any exposure to C or PHP or some other “not-so-friendly” language as ObjC, you can surely understand that

  1. The function is called sayHello
  2. That it takes no input-parameters because the ( ) is empty
  3. That it has no return type because it returns nothing since its missing the keyword “return” inside of it 🙂
  4. And that all it does, instead of returning a value, is print out Hello World

Just to clarify, let’s look at a function with a return value:

DECLARING

func sayHello () -> String {

    var result = “Hello World”

    return result

}

CALLING

var whoAreYou = sayHello()

RESULT (value of whoAreYou)

Hello World

As you can see here, we actually return a value from this function, which we can assign to a variable.  I had to assign it to a variable so that it made sense to actually return a value from a function.  

So we added an output-value to an otherwise plain vanilla function.  Now lets go for the next kind of function, plain + output + input:

DECLARING

func sayHello (friendOne:String) -> String {

    println(“Hi \(friendOne)”)

    var result = “Hello, ” + friendOne

    return result

}

CALLING

var whoAreYou = sayHello(“Marcio”)

RESULT (value of whoAreYou)

Hello, Marcio

Great!  So you’ve got functions covered:

  • Plain void functions
  • Returning output-value functions
  • Input-Paramter, returning output-value functions

CLOSURES (or blocks from ObjC)

There really is no simple way to explain it in a few words.  But the first thing that stands out from a closure or block, is that IT IS a function, yes!  But it can be passed around like a variable.  So let’s take a look:

var someVariable: String

There, we just declared a variable of type string.  Let’s declare another variable:

var someOtherVariable: ( ) -> ( ) = { }

There, we have just declared another variable, of type…? :s

Simply combine the concepts:

variable = function

And we know that a function is:

function = functionName (input-parameter) -> (Output-value) {some code}

So now say:

variable = function = functionName (input-parameter) -> (Output-value) {some code}

Now drop the middle “function” 🙂

variable = functionName (input-parameter) -> (Output-value) {some code}

If you don’t want the function to have a name, because you are assigning it to a variable anyway, so you can just call it by calling the variable:

variable = (input-parameter) -> (Output-value) {some code}

Hey, that looks a lot like what we had above:

var someOtherVariable: ( ) -> ( ) = { }

Cool!  So what does it all mean Basil?

The important thing is that you will use closures in Swift.  I was working with Parse SDK the other day and I ran into this in Xcode:

Get closure on Closures
Get closure on Closures

This is the first stage of Autocomplete which you may already be familiar with.  It’s telling you this:

Void saveInBackgroundWithBlock(block: PFBooleanResultBlock!(Bool, NSError!) -> Void)

You already know what this means, its just a function/method that takes a block as a parameter.  

This function returns Void, according to the left Void in that line.  

Let’s say that the method is called saveInBackgroundWithBlock ( X ) and it takes 1 parameter, X, where X is a block.

The block is defined as a variable “block:” and its called PFBooleanResultBlock!

It has 2 output-values Bool & NSError.

Now you know how to fill it in.  But wait, there’s more…if you call in the next 15 minutes 🙂

But seriously, Xcode now has something new.  Check it out!  To select that method in the image above, you hit Enter.  This spits out the method signature in the Editor window and expects you to fill in the rest…THE NERVE!  Luckily, you can hit Enter again while that blue selection is highlighting the block and that will give you this:

tah dah!

Get closure on Closures
Get closure on Closures

Now that’s better!  This is Xcode’s new second stage Autocomplete.  Its telling us that the block is defined by { } and it takes 2 input-parameters and returns a Void.  That new “in” keyword serves to separate the return (which is in this case, Void) from the actual code block which follows.

So you can call closures like so:

object.saveInBackgroundWithBlock {succeeded, error in

//some code

}

OR

object.saveInBackgroundWithBlock { (succeeded, error) -> Void in

//some code

}

 OR

object.saveInBackgroundWithBlock( { (succeeded:Bool, error:NSError!) in

//some code

})

OR

object.saveInBackground( { (succeeded:Bool, error:NSError! ) -> Void in } )

OR you can assign it:

var someVar: () -> () = {              

println(“Hello World”)

}

Enjoy!

 

EDIT: In brief:

How to write or declare closures:

{ (succeeded: Bool, error: NSError?) -> Void in /* code */ }
{ (succeeded: Bool, error: NSError?) in /* code */ }
{ (succeeded, error) in /* code */ }
{ succeeded, error in /* code */ }
{ /* code using $0 for succeeded and $1 for error */ }

How to pass a closure:

object.saveInBackgroundWithBlock({ /* closure */ })
object.saveInBackgroundWithBlock() { /* closure */ }   // Only if closure is last arg
object.saveInBackgroundWithBlock { /* closure */ }     // Only if closure is only arg

iOS7 Custom Transitions

iOS7 Custom Transitions
iOS7 Custom Transitions

iOS7 Series –Custom Transitions

There is a hierarchy of actors you need to visualize here.  It goes a little something like:

  1. A TransitioningDelegate
  2. An AnimatedTransitioning
  3. A ContextTransitioning

The VC you start out with and that will call the transition will adopt the first protocol, the TransitioningDelegate Protocol.  The purpose of doing so is to obtain the authority to manage the entire transition process.

You will then create a Transitioning class which we can call the Transition Manager.  This class will adopt the AnimatedTransitioning protocol.  The purpose of this protocol is to animate the transition.

The Transition Manager class receives all the necessary information from the Transitioning Context (a protocol adopted by a class you wont really see) and it sends that info to the TransitioningDelegate in order for it to call the shots.

The process itself is quite simple.  We create a Transition Manager class, which adopts the AnimatedTransitioning protocol as stated above.  Then we instantiate this class and call its methods from our initial view controller, who has adopted the TransitioningDelegate protocol in order to call the shots.  Voila, our VC calls the transition for us.

So create a subclass of NSObject and call it what you wish, I called it PinRotatingTransitionManager.  Of course make it adopt the AnimatedTransitioning protocol like so:

<UIViewControllerAnimatedTransitioning>

There are 2 methods you must implement in order to adopt this protocol.  The first one is:

//Define the transition duration

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{

return 1.0;

}

As you can see this simply states how long the transition will last.  It returns a value of type NSTimeInterval and takes in the transition context.

The second method is for describing the animation and it’s a bit long so let’s go one step at a time:

//1. Get current state

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

CGRect sourceRect = [transitionContext initialFrameForViewController:fromVC];

First we get some values for the current state; who is our fromVC, who is our toVC and what is the relevant frame of our current, fromVC.  Remember we are transitioning between two vcs.  The one we are in is called the fromVC or initialVC or if you prefer to keep the original iOS lingo, our sourceVC.  The second one is called our toVC or finalVC or destinationVC.

We need to get a reference to both of them (basically to say THIS vc will do this and THAT vc will do that!).  And of course we need to know the frame we are starting from.

//2.Settings for the fromVC ……………………….

CGAffineTransform rotation;

rotation = CGAffineTransformMakeRotation(M_PI);

fromVC.view.frame = sourceRect;

fromVC.view.layer.anchorPoint = CGPointMake(0.5, 0.0);

fromVC.view.layer.position = CGPointMake(160.0, 0);

We create a rotation transform which will rotate anything by M_PI.  Then we set our fromVC frame to the sourceRect, we define an anchor point for it and a position for it.

//3.Insert the toVC view………………………

UIView *container = [transitionContext containerView];

[container insertSubview:toVC.view belowSubview:fromVC.view];

CGPoint final_toVC_Center = toVC.view.center;

Now we need to do something quite important…get a container view to put everything into in order to run the transition.  To that container view we must add the toVC, because the fromVC is already added for us.

//4.Insert the toVC view………………………

toVC.view.center = CGPointMake(-sourceRect.size.width, sourceRect.size.height);

toVC.view.transform = CGAffineTransformMakeRotation(M_PI/2);

Now we set the toVC’s center point and apply the transform created.

And finally we perform the animation:

//5. Animate..

[UIView animateWithDuration:1.0

delay:0.0

usingSpringWithDamping:.8

initialSpringVelocity:6.0

options:UIViewAnimationOptionCurveEaseIn

animations:^{

//Setup final params of the views

fromVC.view.transform = rotation;

toVC.view.center = final_toVC_Center;

toVC.view.transform = CGAffineTransformMakeRotation(0);

} completion:^(BOOL finished) {

//When done call completeTransition

[transitionContext completeTransition:YES];

}];

This is quite simple.  We define some parameters for the animation and call a block which applies the rotation and center etc.  Once complete we call completeTransition which is mandatory.

Now run your app and you should have a very nice transition where the fromVC slides left and the toVC rotates down into place.

 

Neat huh!

Business of iOS Apps

iOS apps business by Santiapps.com Marcio Valenzuela
iOS apps business

I keep reading articles or watching videos of iOS businesses who made it and they share their wisdom of the Common 10 Mistakes iOS developers make. Guess what? Most of those mistakes, although they are worded as developer concepts, they are really business concepts.

Common Mistakes: Don’t need a marketing guy. Don’t need a business guy. Don’t need a business perspective. Usually worded as, I thought I would get rich quick, or Im looking for a one hit wonder, or Im a great programmer and I thought that was enough.

Well guess what, if you are going to sell something and make more than 99c for it, its gonna need a Business Plan. But don’t fret, it doesn’t mean you need an MBA to help you come up with a business plan. If you are a level headed guy-or-gal, you should be ok. You just need to know what to put down on paper. You WILL need a plan if you are going to be selling something more than lemonade 🙂

Its a plan, take out the word ‘business’ if you don’t want to. But just think about this, Steve Jobs wasn’t the business plan type. He wanted to run his company the way he wanted to. So they kicked him out of his own company because of that. True, they begged him to come back, but Jobs had learned a thing or two about making plans. That combination took Apple to the top.

So let’s just call it a plan, because you will jot down ideas to help you organize what you need to do. Let’s add the word operating, because it will be a hands-on kind of plan. And if you wanna get fancy, throw in the word Strategic, because it will take some key ideas to put this plan into action.

Your ‘Strategic-Operating-Plan’

You need to analyze what you have and don’t have. Did you see the movie Public Enemy with Hackman and Smith? Well, if they’re big, you’re small, they’re slow and you’re mobile. To know what you can be, you gotta know what you are right now and what you’re missing.

(SWOT)

1) Know your Strengths

2) Accept your Weaknesses

3) Spot market Opportunities

4) Identify any Threats

Once you know what you have and don’t have, you probably realize you have programming skills but no selling skills. This is typical and it sucks! Guys who invented things (engine, nuclear fission, electricity) get credit, but they don’t get the ladies! Why? Cause they don’t get the moolah! You always see pictures of Einstein and Edison dying poor. But the Presidents and CEOs of companies who make cars, weapons and electricity are sitting pretty making millions every year plus bonuses and benefits.

Its a known fact, business types will always make the money while smarties slave away in a lab somewhere. You therefore need a plan to sell whatever it is you know how to make.

(Marketing Plan)

Product: The app you created is of what type? What exactly did you make and what can it do. It might seem silly, but write it down. More importantly, have others around you look at it, use it and write down what THEY think the product is and does. Did you make something you thought was cool or did you discover a need that nobody was covering quite that well? How many products can you make in a year? What kind of products will they be, will a client pull or will you push in the App Store? Your costs will vary whether its push or pull, but they won’t be zero I can promise you that!

Price: According to the type of app you made, how should you price it? Market vs Cost. You definitely need to cover your costs. But there are different types of costs. These are things you need to identify in your Strengths and Weaknesses. Your upfront costs or initial costs might be high but you can throw them all in a pile as part of the price.

If you took out a loan for 1 year of living expenses while you code (computer, internet, Apple Membership, electric bill, water bill, food, cellular etc) and ended up with a $25,000 loan, you can’t price your app at $25,500 :). You gotta know a little bit about finance such that you spread those costs out over a long period of time. If you made 1 app that sold for $1 (net) and expect 500 downloads a month, thats about $6,000 a year. That would pay off a no-interest loan in 4.1 years. But your loan payments may only be $100 a month. Think about how many apps you think you can put out a year because with 2 apps having 500 monthly downloads, your income doubles.

Place: Where will people buy it? AppStore, website, Facebook ads, Email, word of mouth. Your costs will vary depending on where you have to sell it. True, AppStore helps you lower the cost of marketing your app but it may not be the ONLY place you have to promote your app. A client-pulled app is safer in the sense that it will let you know your income upfront and significantly reduce your costs. Depending on how you defined your app, what needs it covers and how it is priced, you will decide the right place. Tech forums are not the right place for medical apps. A highly priced app would be better off at a local expensive supermarket with a nice banner than via massive emails to your friends.

Promotion: How will you promote it? InApp? iAds? As mentioned before, will this app be push or pull? That tells you where your app will be purchased and thus where you need to push it or have it be pulled. There are many ways to promote your app but in the end you need to monitor your promotions to know which ones are working our for you and which ones aren’t. That’s how you decide where to invest more money in order to promote it.

(Inherent offsync)

This is a heavy pill to swallow. Let’s define a few the kinds of concepts we have talked about and you know are required for app selling.

1) Programmers

2) Graphic Designers

3) Business

4) Sales

Like it or not, these are 4 very different types of people.

Programmers are introverted, mathematical geeks and abstract thinkers.

Graphic Designers are free spirited, un-organized rebels.

Business people are demanding, goal oriented doers.

Sales people are social, pushy creatures that hate work. Selling is not work, its their way of life.

These are mutually exclusive human traits. Ask any psychologist. This is basically why you can’t be a one-man show. You must at least be a two-man show where one programs and the other does business. That’s how most successful businesses are spawned, grown or nurtured. That means you would have to outsource graphic design and sales. Business management and operations really need to be in sync and thus should not be separated from each other and outsourced.

Graphic design is a bit easier to outsource than business-ing and programming. Sales can be ‘pushed’ or outsourced to many platforms nowadays either web, print or digital. You must still know what those platforms are, what their potential is, monitor them and grade them to see which ones work and which ones don’t. But you MUST measure everything and question why something is working (not working) the way it is (isn’t).

I don’t want you to read off with the wrong idea. Yes you CAN make it! Its just not gonna be easy, like everything in life, if you want it to be good, you have to work at it. Don’t be shy or scared of delegating and teaming up. Make sure you cover all angles, development (programming & design), business (operations & management) and sales!

Everyone must be a salesperson if they want to succeed!

NSURLSession vs NSURLConnection by Santiapps.com Marcio Valenzuela

Fetching data from an iOS app – The new NSURLSession API

NSURLSession vs NSURLConnection by Santiapps.com Marcio Valenzuela
NSURLSession vs NSURLConnection by Santiapps.com Marcio Valenzuela

Ok, this is gonna be short, I promise! 🙂

Do you remember those apps you’ve got stored away or the ones you are working on that fetch data from the web with a NSURLConnection? Time to update them, here’s how.

Basically you have a method that calls a web fetch and is somehow signaled to use that received data to refresh a UI. If you used NSURLConnection sendAsynchronousRequest:, you have the issue that it blocks the main thread. It does carry out requests asynchronously from each other, but each request does indeed block the main thread since it is carried out in the main queue. Alternatively, you can use a long brittle bunch of API’s named NSURLConnection initWithRequest: with a set of delegate callbacks. Instead, take a look at this.

If you have:

-(void)fetchDataFromWeb{
//1. LOAD DATA FROM WEB
NSURL *stringURL = [NSURL URLWithString:@"http://www.yourserver.com/appfolder/somewebserviceURL.php"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:stringURL];
[NSURLConnection sendAsynchronousRequest:myRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

//Once data is got, load local object & fire reloadData
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

//UPDATE CURRENT VIEW FIRST
[self setData];

}];
}

Replace with:

-(void)fetchDataFromWeb{
//1. LOAD DATA FROM WEB
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://www.yourserver.com/appfolder/somewebserviceURL.php"]
completionHandler:^(NSData *data, NSURLResponse *response,
NSError *error) {
// handle response
//Once data is got, load local object & fire reloadData
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

//UPDATE CURRENT VIEW FIRST
[self setData];

}] resume];
}

The most important thing to note here, is perhaps an little noticed piece of code in NSURLConnection, queue:[NSOperationQueue mainQueue].

You see, other than that, the both pieces of code do pretty much the same thing. They fetch data. NSURLConnection fetches data but it will block your main thread. This means that if you call the fetch, your app will stop or hand until the NSURLResponse is received.

You could go this route:

1. Adopt the delegate:
& create a data container NSMutableData *_responseData;

2. Call your web fetch:
// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.yourserver.com/appfolder/somewebserviceURL.php"]];

// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

3. Get your data from the callbacks:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
_responseData = [[NSMutableData alloc] init];
}

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
[_responseData appendData:data];
}

– (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}

– (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
//UPDATE CURRENT VIEW FIRST
[self setData];
}

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
}

That’s a BIG block of code! And it can get tedious & brittle to maintain.

NSURLSession automatically calls the web fetch in a background thread so as to not block your main thread. How cool is that? 🙂 Enjoy!

Creating a Menu in SpriteKit

SpriteKit Menu by Santiapps.com Marcio Valenzuela
SpriteKit Menu

Cocos2d has a easy to use CCMenu object to which you add CCMenuItems.  In SpriteKit however, you are back to UIKit objects.  This doesn’t not mean its more complicated, its just different :-).  You will need to create a UIControl such as a button or you can use SpriteKit’s SKNode to create the visual object onscreen:

SKLabelNode*  someNode = [SKLabelNode labelNodeWithFontNamed:@”Chalkduster”];
[someNode setText:@”Play Game”];
[someNode setPosition:CGPointMake(CGRectGetMidX(self.frame)+5,CGRectGetMidY(self.frame)-40)];
[self addChild: someNode];

Now you simply connect the object action to some event like so:

for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];

if ([someNode containsPoint:location]) {
SKTransition* present = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1];
GameScene* gameScene = [[GameScene alloc] initWithSize:CGSizeMake(1024, 768)];
[self.scene.view presentScene: someNode transition:present];

}
}

Voila!  You are DONE!