All posts by admin

Converting existing Project to read from Azure Backend

Import Data Model

File >> New >> File >> Data Model. Name it “Activities”.

Ctrl + click >> Show in Finder. Then drag that file onto a text editor such as sublime. You will see basic xml file.

Drag and drop an existing data model file onto the text editor. Copy and paste all the content into your Activities file. Save and close. Your data model should be now updated. Your iOS data model is ready.

Basic Core Stack Class

Create a basic core data stack class with a context, MOC, and PSC.
Make sure the your sql file name, and the data model name are specified.

core data demo

#define DATA_MODEL_FILENAME @”Activities”
#define SQL_FILENAME @”Activities.sqlite”

QSTodoService

Azure should generate a QSTodoService object that does all the reading and writing of data for you.

Unfortunately, it also generates core data code that sits in your AppDelegate. Pull all the core data code out onto your own CoreDataStack class so that AppDelegate is clean.

Then, make these modifications to your QSTodoService:

Use your core stack and its context in QSTodoService’s init method. Commented out code is the original.

ViewController

conform to NSFetchedResultsControllerDelegate protocol

specify what/how you want to fetch for the fetchedResultsController

In the viewDidLoad, make sure you create your QSTodoService because we are going to implement a refresh method that uses it to sync all the data between your app the backend service.

use the fetchedResultsController to get the objects

Add data attribute to table and app

Let’s say we want to add an attribute event_date, so that the iOS app takes in that date, and can send and store it in an Easy Table on Azure backend.

Azure backend side

Click on the designated table, you add the column attribute. Save it.

add_column

iOS side

Note: For ever new attribute you add, make sure you delete the old app that’s installed on your device. This is so that the existing app’s Core Data mode does not conflict with your new addition.

After you have finished your Easy Table, you use Quick Start to generate an iOS project that connects its Core Data to the Easy Table in Azure backend.

What you pull from the Easy Table depends on your NSFetchController:

  • entity
  • predicate
  • sortDescriptors

of the NSFetchController get method like so:

So we want to match the event_title attribute we added on the Azure backend.

We do so by manipulating our .xcdatamodelId file. In core data, each entity matches that of a table. Look for the TodoItem (or whatever table name you have created in Azure) entity. Click on it, and click the plus button to add it.

add_attribute_to_entity

In your iOS code, we pass the data dictionary to the Azure backend to fill in on the attribute. Thus, just make sure you put the key for “event_date”, and the value that you want to send, which in our case is NSDate.

Then, run your app. Add an entry. Go to your dashboard, and refresh the table rows. You will see your results there.

column_reflected

Logging in Azure

In order to log in Azure

Settings >> Diagnostic Logs >> Logs

diagnostic_logs

Make sure the Application Logging is turned on

azure_logs2

Create FTP credential accounts

In order to view your logs, you must create a FTP account so you can log in.

credentials

After creating a new FTP user, you’ll see your user name, and the FTP URLs. You will be using these FTP urls and credentials to view your logs.

azure_logs

Use the user name and password you just created to log into FTP client like Filezilla

filezilla_url

Once you log in, go to /LogFiles/Application and you’ll see all your logs with timestamps

filezilla_url2

You can copy the files onto your desktop and view it. However that is not efficient because you don’t want to do a copy every time a log is updated.

Web browser to view your logs

Hence, just put the FTP url into your browser, insert your credentials and update the browser whenever you make a change.

http_log_view

Programmatically add a Navigation Controller to your project

objective C demo
swift 3 demo

AppDelegate.swift

SWIFT 3

ViewController

CustomViewController.swift

OBJECTIVE C

The whole idea is that your window strongs UINavigationController, and UINavigationController strongs your main ViewController.

The UINavigationController is set up in your AppDelegate. Then your UINavigationController is init-ed with your main view controller.

nav-1

Then, in your main view controller, use self.navigationItem to set up the buttons and title.

nav-2

UINavigationController

First we create a UINavigationController property.

Then, we create the UINavigationController and init it with the main view controller of your project.
Set the UINavigationController as the root view controller of our window.

In your main view controller, make sure in your viewDidLoad, you set the navigation button like so:

The nav button has a button responder:

This means when you click on the nav button, we want to navigate to a new view controller. Hence, let’s implement the view controller that we want to navigate to.

File >> New >> File >> Cocoa Touch Class

Put in AddViewController for the “class name”.
Put in UIViewController for the “subclass of”.

Then import AddViewController to your main view controller, and implement the button responder like so:

Make sure you set background color for every view controller because if its default as clear, there may be animation issues.

@public, @private, @protected (objc)

ref – http://stackoverflow.com/questions/844658/what-does-private-mean-in-objective-c

The @public, @protected, @private are called accessor modifiers. They provide access visibility to the instance variable.

So we declare 3 iVar using @public, @protected, @private.

We then declare a child class, and declare MyFirstClass as a parent class.

The basics are laid out here.

  • @public iVars CAN be accessed by the child class
  • @protected iVars CAN be accessed by the child class
  • @private iVars CANNOT BE accessed by the child class

Since we do not provide any accessor methods via properties, the instance varaibles are not accessed via the dot notation (.)

Rather, they are accessed through the arrow ( -> ).

enforce the use of accessors

Say a developer writes a class, then write properties and accessors. However, what if some other developer goes

xcode 4.x+ automatically puts @private in the template for an object. Thus, you don’t have to worry about other people accessing your instance variable with the arrow and modifying unexpectedly.

The only way to modify the instance variables, is through your property methods.

NSURLSession – Out of process upload/download

ref – http://www.techotopia.com/index.php/An_iOS_7_Background_Transfer_Service_Tutorial

demo project

Background Uploads and Downloads

Adding support for background uploads and downloads is surprisingly easy with NSURLSession. Apple refers to them as out-of-process uploads and downloads as the tasks are managed by a background daemon, not your application. Even if your application crashes during an upload or download task, the task continues in the background.

Enabling background uploads and downloads is nothing more than flipping a switch in your session’s configuration. With a properly configured session object, you are ready to schedule upload and download tasks in the background.

When an upload or download is initiated:

  1. background daemon comes into existence
  2. The daemon takes care of the task and sends updates to the application through the delegate protocols declared in the NSURLSession API
  3. If app stops, daemon continues task
  4. If download task finishes, daemon informs session.
  5. The session then invokes the appropriate delegate methods to make sure your application can take the appropriate actions, such as moving the file to a more permanent location.

When the Background Transfer Service gets in action, what is actually happening is that the operating system takes charge of all the download process, performing everything in background threads (daemons).

While a download is in progress, delegates are used to inform the app for the progress, and wakes it up in the background to get more data if needed, such as credentials for logging in to a service. However, even though everything is controlled by the system, users can cancel all downloads at any time through the application.

A reminder that a block parameter has 3 parts. The return, the parameter, and the block name. Like so:

So this means that the block is used where it takes 2 doubles, and does not return anything. It is called by using the block name ‘block’.

Handle Events for Background Session

Apps that (using an NSURLSession with a background configuration) may be launched or resumed in the background in order to handle the
completion of tasks in that session, or to handle authentication.

In other words, when an app uses NSURLSession with background service (whether its a GET request or downloading/uploading), NSURLSession needs to let the app know and to handle the completion of tasks for that session.

We simply strong the completionHandler block in order to call it later to let the system know that we complete all tasks.

NSURLSessionDelegate’s PROTOCOL METHOD will be called. In there you access the appDelegate and call the completionHandler.

Hence when you’re using it, if an application has received an -application:handleEventsForBackgroundURLSession:completionHandler:
message, the session delegate will receive this message to indicate
that all messages previously enqueued for this session have been
delivered.

Declare the session completion handler member variable:

AppDelegate.h

Then, have its set property copy the completion handler:

AppDelegate.m

Go to your ViewController and conform to NSURLSessionDelegate.

This is so that we need to implement URLSessionDidFinishEventsForBackgroundURLSession.

Now when your session object’s delegate queue tasks have all been processed, in your AppDelegate, you will receive a
application has received an -application:handleEventsForBackgroundURLSession:completionHandler:
message and your protocol method

will be called.

Then your session delegate will send a message to protocol method URLSessionDidFinishEventsForBackgroundURLSession to indicate that all messages previously enqueued for this session have been
delivered.

Hence that’s why its the job of your URLSessionDidFinishEventsForBackgroundURLSession method to simply call the completionHandler and clean it up.

If your session delegate sends a message to call protocol method:

for authentication purposes, then you need to something similar. Where you give authentication information, then call the completionHandler().

Prepare the UI

Configuration Object

Session Object

Updating download progress percentages

When you resume a download task

Send last message related to a specific task

When your download have completed