Friday, November 11, 2016

Network Router and Request in Swift 3 using Alamofire and SwiftyJSON



Alamofire and SwiftyJSON are the ultimate framework of choice when it comes to Native Swift application development. But there is one small issue we need to manually bridge this two framework manually to get the final output. Hence here is the ultimate guide for how to make Network Request in Swift using Alamofire and get the response as SwiftyJSON using a Router Path.

1. URL Request

We have to first create - enum of a URLRequestConvertible

enum ActivitieRouter: URLRequestConvertible {
case activitiesIndex // Activities Index

case createActivities(param: Parameters) // Create Activities
case updateActivity(activityID: Int, param: Parameters) // Update Activity
case destoryActivity(activityID: Int) // Destroy Activity
}
On each of the request we need to define the http Method 
var method: HTTPMethod {
switch self {
case .activitiesIndex:
return .get
case .activityDate:
return .get
case .getActivity:
return .get
case .createActivities:
return .post
case .updateActivity:
return .put
case .destoryActivity:
return .delete
}
}

each Request can have a sub path like -


var path: String {
let subPath = "activities"
switch self {
case .activitiesIndex:
return subPath
case .updateActivity(let activityID, _):
return subPath + "?" + "\(activityID)"
case .destoryActivity(let activityID):
return subPath + "?" + "\(activityID)"
}
}
Finally the most important for a Protocol is a asURLRequest function which returns the URLRequest

func asURLRequest() throws -> URLRequest {
var urlRequest = NetworkManager.getTokenRequest(path)
urlRequest.httpMethod = method.rawValue
switch self {
case .createActivities(let parameters):
urlRequest = try URLEncoding.default.encode(urlRequest, with: parameters)
case .updateActivity(_, let parameters):
urlRequest = try URLEncoding.default.encode(urlRequest, with: parameters)
default:
break
}
return urlRequest
}

Refer - Gist - https://gist.github.com/bishalg/4d554cd79a138c43c00c17cebf6eb3d3

2. Response Serializable

Now task is to use extend the DataRequest so that we can response back SwiftyJSON object from our network request.





3. Network Request


Finally with our Response Serializer and Network Router ready we can finally make our Network Request. 


static func mostRecent(
onSuccess: ObjectsCallBack? = nil,
onError: ErrorCallback? = nil) {
let route = ActivitieRouter.activityDate(activitiesDate: ActivitiesDate.recentMonth)
let _ = Alamofire.request(route)
.responseSwiftyJSON { request, response, json, error in
guard error == nil else { return }
// create - objects array or object
// return - objects
onSuccess?(objects)
}
}

Thats is it ! Out Networkig code is complete ! 

But you may have noticed that there is one class NetworkManager which is not present ! But that is upto you to manage as per project basic which can be generalized code for say like base url etc.

Links - 



Tuesday, March 1, 2016

RK03 - ResearchKit "Hello World" with Instruction Step

"Hello World" with Instruction Step


No software can go forward without a simple "Hello World" application.
If we break this rule, the Gods of "Programming for Dummies" will crush us !
So without any further due lets do some coding !!!

https://gist.github.com/bishalg/c5268460b81344451e44


// 1
   @IBOutlet weak var gettingStartedButton: UIButton!   
// 2
    @IBAction func gettingStartedAction(sender: UIButton) {        self.sayHellowToTheWorld()    }        func sayHellowToTheWorld() {        // Make Steps         let step1 = ORKInstructionStep(identifier: "step1")        step1.title = "Hello World!"                let step2 = ORKInstructionStep(identifier: "step2")        step2.title = "That is it ! :] Thanks"        
                 // Make a Ordered Task of steps
        let task = ORKOrderedTask(identifier: "ourFirstTask", steps: [step1, step2])
                  // Present the ViewController of hence made Task !
        let taskVC = ORKTaskViewController(task: task, taskRunUUID: nil)        taskVC.delegate = self        presentViewController(taskVC, animated: true, completion: nil)    }
// 3
extension HomeVC: ORKTaskViewControllerDelegate {

   func taskViewController(taskViewController: ORKTaskViewController, didFinishWithReason reason: ORKTaskViewControllerFinishReason, error: NSError?) {        self.dismissViewControllerAnimated(true, completion: nil)        let buttonTitle: String?        switch reason {        case .Completed:            buttonTitle = "Completed"        case .Discarded:            buttonTitle = "Discarded"        case .Failed:            buttonTitle = "Failed"        case .Saved:            buttonTitle = "Saved"        }
        gettingStartedButton.setTitle(buttonTitle, forState: .Normal)    }

// 1 - Getting Started -
In our VC we have a button which will start a ResearchKit survey and will change based on our action

// 2 - Action on button will start the survey

If we do "Next" and "Done" after  we started from "Getting Started" button it would present us a Task-ViewController which will make a delegate at the end of it step.

// 3
// Extend out View Controller so that it handles the Delegate of TaskVC
// Once the task is completed we will update our button to reflect the result !
// And finally its our responsibility to dismiss the VC we presented.

Here is one of the expected flow -

1. Home Screen


2. Research Kit - TaskVC presented with "Hello World" Instruction Step ( ORKInstructionStep )



3. Second Instruction Step with "DONE" button - 2/ 2



Finally if we will get any one of the following result ( ORKTaskViewControllerFinishReason ) -
In this case we will have either Completed or Discarded result.

    







Monday, February 29, 2016

RK 02 - ResearchKit - Native App on HTML ?

As an iOS developer you would tend to think that Framework that Apple has developed must be on native Objective-C or Swift. The ResearchKit framework itself may be on Objective-C but the Architecture of the App development includes lots and lots of HTML and JSON files.

So you might need to revise your HTML / CSS skills before we proceed further.

If we dig inside "Resources" folder for the sample app for Parkison.



The major of contents are in HTMLContent folder, and  JSON is used to map the those HTML to each Views or ViewControllers.

Now lets examine  StudyOverview.json -

"questions":
    [
     {
     "title":"Welcome to mPower",
     "details":"A Parkinson Disease Research Study",
     },
     
     {
     "title":"About this Study",
     "details":"AboutStudy_intro",
    
     },
     
     {
     "title":"About the App",
     "details":"Please tap on the image below to watch a short video introduction to mPower.",
     "video_name" : "Intro",
     },
     
     {
     "title":"How this Study works",
     "details":"howstudyworks_intro",
     

     },


Hence the app framework binds your HTML via JSON files -
for example to bind your AboutStudy_intro.html file you have following JSON -

{
     "title":"About this Study",
     "details":"AboutStudy_intro",
 }

Which has the content like this -






Links -

https://github.com/ResearchKit/mPower/tree/master/Parkinson/Resources
www.w3schools.com/html/
www.w3schools.com/json/

Thursday, February 25, 2016

RK01 - ResearchKit - App Store Apps - diagnostic

As our tutorial is more focused towards making an app lets start from AppStore itself !



There are many app right now in App Store which are based on ResearchKit and the number is increasing day by day !




Following are the apps features by apple right now -

Asthma Health by Mount Sinai


By Icahn School of Medicine at Mount Sinai

https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=972625668&mt=8&ls=1&v0=www-us-researchkit-itms-asthma-health


Autism & Beyond


By Duke Health

https://itunes.apple.com/us/app/autism-beyond/id1025327516?mt=8

Breast Cancer: Share the Journey study


By Sage Bionetworks, a Not-For-Profit Research Organization

https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=972180604&mt=8&ls=1&v0=www-us-researchkit-itms-Sage-Bionetworks


EpiWatch


By Johns Hopkins Digital

https://itunes.apple.com/us/app/epiwatch/id1047757228?mt=8

Mole Mapper Melanoma Study


By Sage Bionetworks, a Not-For-Profit Research Organization

https://itunes.apple.com/us/app/mole-mapper-melanoma-study/id1048337814?mt=8


MyHeart Counts


By Stanford University

https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=972189947&mt=8&ls=1&v0=www-us-researchkit-itms-my-heart


Parkinson mPower study app


By Sage Bionetworks, a Not-For-Profit Research Organization

https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=972191200&mt=8&ls=1&v0=www-us-researchkit-itms-mpower


GlucoSuccess

https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=972143976&mt=8&ls=1&v0=www-us-researchkit-itms-Glucosuccess


RK00 - Getting Started with ResearchKit

RK00 - Getting Started with ResearchKit

Published On - 2/25/16, 4:52 AM
Updated On - 3/30/16

I guess as you have already searched for ResearchKit, you need no introduction to it !
But if you really don't know what it is here is an intro for you -

ResearchKit is an open source software framework that makes it easy to create apps for medical research or for other research projects.

Normally when we start to develop iOS app the first place we start to search for tutorial is Raywenderlich. No wonder there is already one on ResearchKit ! Believe me only other place to learn about ResearchKit is one WWDC video from apple and that is it :[.

Other learning resources we should follow is the ResearchKit blog. And as always there is StackOverflow to get around.

But in this tutorial series I would not use conventional tutorial.  Like intro to ResearchKit, for which you can always follow apple documentation. Rather I would make you go thought the app that is already on App Store and hence at the end you can make your own app ;]. For which I would use open Gluco Sucess app. But the fun part is I wont make you follow same app ! Instead we would make a app for COPD called StopCOPD which isnt OpenSource app.

So lets get started !

RK01 - ResearchKit - App Store Apps - diagnostic
RK 02 - ResearchKit - Native App on HTML ?
RK03 - ResearchKit "Hello World" with Instruction Step


Links -

http://www.apple.com/researchkit/
http://www.raywenderlich.com/104575/researchkit-tutorial-with-swift
http://researchkit.org
http://researchkit.org/blog.html
https://developer.apple.com/videos/play/wwdc2015/213/
http://stackoverflow.com/questions/tagged/researchkit?sort=newest&pageSize=50
http://researchkit.org/docs/docs/Overview/GuideOverview.html

https://github.com/researchkit/researchkit
https://github.com/ResearchKit/GlucoSuccess
https://itunes.apple.com/us/app/stopcopd/id1020845469?mt=8

Friday, September 11, 2015

Swift 2.0 Strings


After functional coding I feel the biggest change from Obj-C world to Swift was in support of Unicode string.

Then again the huge change from Swift 1.2 to Swift 2.0 might be in String.
In someway its a dramatic change !
As stated in Swift Blog

Swift provides a performant, Unicode-compliant string implementation as part of its Standard Library. In Swift 2, theString type no longer conforms to the CollectionType protocol, where String was previously a collection of Character values, similar to an array. Now, String provides a characters property that exposes a character collection view.


var letters: [Character] = ["c", "a", "f", "e"]
var string: String = String(letters)

print(letters.count) // 4
print(string) // cafe
print(string.characters.count) // 4


let acuteAccent: Character = "\u{0301}" // ´ COMBINING ACUTE ACCENT' (U+0301)

string.append(acuteAccent)
print(string.characters.count) // 4
print(string.characters.last!) // é



https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html


NOTE
Extended grapheme clusters can be composed of one or more Unicode scalars. This means that different characters—and different representations of the same character—can require different amounts of memory to store. Because of this, characters in Swift do not each take up the same amount of memory within a string’s representation. As a result, the number of characters in a string cannot be calculated without iterating through the string to determine its extended grapheme cluster boundaries. If you are working with particularly long string values, be aware that the count(_:) function must iterate over the Unicode scalars in the entire string in order to calculate an accurate character count for that string.


The character count returned by the count(_:) function is not always the same as the length property of an NSString that contains the same characters. The length of an NSString is based on the number of 16-bit code units within the string’s UTF-16 rpresentation and not the number of Unicode extended grapheme clusters within the string. To reflect this fact, the length property from NSString is called utf16Count when it is accessed on a Swift String value.

Reference - 

Tuesday, September 1, 2015

Catching generic Exceptions in Swift 2.0

Erro handeling is always a chalange in any development enviroment.


In general, we will never spot an error if we log or catch. Only developers will see those, and if you're muffling to avoid user-visible behavior, succeeding means nobody will notice!

So our guideline is: 
"if it's something wrong that we want to fix, let it crash, find and fix before release. "

If it's something wrong that might seriously impact the user experience, or is not indicative of a programming error, then muffle but make sure we have a test or some other way to find the problem. 

Or make sure that failure propagates around the application through some other kind of logic — return values, fall through, whatever. 

Also: if you write 'catch Exception', consider writing 'Throwable' instead. I often see this:

  // This might run out of memory. 
  catch (Exception e) {

which won't work — Exception and Error are siblings, and OOMs are OutOfMemoryErrors. That'll catch everything but an Error!

I am a huge fan of open source Firefox iOS Developed in Swift and consider it as an inspiration.
I found the following discussion on bugzilla 

Inspired by buzilla form - 

Richard Newman 
https://mail.mozilla.org/pipermail/mobile-firefox-dev/2015-August/001451.html

Bugzilla - https://bugzilla.mozilla.org/show_bug.cgi?id=1191067#c25
Github - https://github.com/mozilla/firefox-ios