iOS Revisited

Hot

Post Top Ad

17 Oct 2017

How to add TextField to Alert View in swift 4?

10/17/2017 03:19:00 am 0
Adding UITextField to alertview became easy from swift 3 by using UIAlertController.

Here we will show step by step.

How to add UITextField to Alert View in swift 4?

Step 1:

First create UIAlertController object with title and message as follow:

let alertVC = UIAlertController(title: "Enter credentials", message: "Provide Email & Password", preferredStyle: .alert)

Step 2:

Next add UITextField's to alertVC using addTextField() method as follow:

alertVC.addTextField { (textField) in
    textField.placeholder = "Email"
}
alertVC.addTextField { (textField) in
    textField.placeholder = "Password"
    textField.isSecureTextEntry = true
}

Step 3:

Then add the UIAlertAction with title and completion handler as follow:

let submitAction = UIAlertAction(title: "Submit", style: .default, handler: {
    (alert) -> Void in
    
    let emailTextField = alertVC.textFields![0] as UITextField
    let passwordTextField = alertVC.textFields![1] as UITextField
    
    print("Email -- \(emailTextField.text!), Password -- \(passwordTextField.text!)")
})

Step 4:

Finally add the UIAlertAction to alertVC and present alertVC as follow:

alertVC.addAction(submitAction)
alertVC.view.tintColor = UIColor.black
present(alertVC, animated: true)

The final output will looks like following image:

uialertcontroller with textfield swift 4

Read More

16 Oct 2017

Concatenate/Merge Two Arrays into One Array in Swift 4

10/16/2017 08:46:00 am 0
Append two arrays into a new array with Swift standard library's.

There are 5 different ways for merging arrays in swift. We may choose one of the five following ways according to your needs and requirements.

Sorting Arrays in Swift

Concatenate/Merge Two Arrays into One Array in Swift 4

1. +(_:_:) generic operator:

The following piece of code shows how to merge two arrays of type [Int] into a new array using +(_:_:) generic operator:

var arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
let finalArray = arr1 + arr2
print(finalArray)
// output will be '[1, 2, 3, 4, 5, 6]'


2. append(contentsOf:):

The following piece of code shows how to append two arrays of type [Int] into a new array using append(contentsOf:) method:

var arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
arr1.append(contentsOf: arr2)
print(arr1)
// output will be '[1, 2, 3, 4, 5, 6]'


3. flatMap(_:):

The following piece of code shows how to concatenate two arrays of type [Int] into a new array using flatMap(_:) method:

var arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
let finalArray = [arr1, arr2].flatMap({ (element: [Int]) -> [Int] in
    return element
})
print(finalArray)
// output will be '[1, 2, 3, 4, 5, 6]'

4. joined():

Swift provides a joined() method for all types that conform to Sequence protocol (including Array).

So, following piece of code shows how to join two arrays of type [Int] into a new array using Sequence's joined() method:

var arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
let flattenCollection = [arr1, arr2].joined()
let finalArray = Array(flattenCollection)
print(finalArray)
// output will be '[1, 2, 3, 4, 5, 6]'

5. reduce(_:_:):

The following piece of code shows how to merge two arrays of type [Int] into a new array using reduce(_:_:) method:

var arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
let finalArray = [arr1, arr2].reduce([], { (result: [Int], element: [Int]) -> [Int] in
    return result + element
})
print(finalArray)
// output will be '[1, 2, 3, 4, 5, 6]'

Use any one of above methods based on your requirement.

Read More

14 Oct 2017

Sorting Arrays in Swift 4 - iOS 11

10/14/2017 10:10:00 am 0
Sorting Arrays using swift 4 is a simple using sorted() built-in method.

Sorting Arrays in Swift 4 - iOS 11

Here is a example for sorting an simple array containing string objects.
let friends = ["Sophia", "James", "Olivia", "Mike", "Nina"]
print(friends.sorted())

//output is '["James", "Mike", "Nina", "Olivia", "Sophia"]'

We can sort complex arrays also easily using same built-in method sorted().

Creating an array with custom struct:

struct friendStruct {
    var name: String
    var age: Int
}

let array = [
    friendStruct(name: "Sophia", age: 23),
    friendStruct(name: "Olivia", age: 25),
    friendStruct(name: "James", age: 21),
    friendStruct(name: "Nina", age: 26),
    friendStruct(name: "Mike", age: 23)
]

Sort by name:

let sortedArray = array.sorted { (firstStruct, secondStruct) -> Bool in
    if firstStruct.name < secondStruct.name {
        return true
    }
    return false
}

Sort by age:

let sortedArray = array.sorted { (firstStruct, secondStruct) -> Bool in
    if firstStruct.age < secondStruct.age {
        return true
    }
    return false
}


We can sort Date also like above.

5 Ways To Concatenate/Merge Two Arrays into One Array in Swift 4
Read More

12 Oct 2017

Convert One Date Format To Another Date Format Swift 4 - iOS

10/12/2017 03:07:00 am 0
Converting a date string from one date format to another date format is an easy by using the following method:

Convert One Date Format To Another Date Format Swift 4 - iOS


Date Formats:

Following are the some Date Formats:

Thursday, Oct 12, 2017 - EEEE, MMM d, yyyy
10/12/2017 - MM/dd/yyyy
10-12-2017 09:48 - MM-dd-yyyy HH:mm
Oct 12, 9:48 AM - MMM d, h:mm a
October 2017 - MMMM yyyy
Oct 12, 2017 - MMM d, yyyy
Thu, 12 Oct 2017 09:48:59 +0000 - E, d MMM yyyy HH:mm:ss Z
2017-10-12T09:48:59+0000 - yyyy-MM-dd'T'HH:mm:ssZ
12.10.17 - dd.MM.yy

For more check here.

One Date Format To Another:

For converting we are going to create String extension as follow:
extension String
{
    func toDateString( inputDateFormat inputFormat  : String,  ouputDateFormat outputFormat  : String ) -> String
    {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = inputFormat
        let date = dateFormatter.date(from: self)
        dateFormatter.dateFormat = outputFormat
        return dateFormatter.string(from: date!)
    }
}

Usage:

Add the following lines of code for usage:
let dateString = "2017-10-10 15:56:25"
let requiredFormat = dateString.toDateString(inputDateFormat: "yyyy-MM-dd HH:mm:ss", ouputDateFormat: "dd 'at' hh:mm:ss")
print(requiredFormat)

//output will be '10 at 03:56:25'

The inputDateFormat should be same as dateString, but the ouputDateFormat can be different as we required.
Read More

11 Oct 2017

Convert Date To String & Vice-Versa Swift 4 - iOS

10/11/2017 05:54:00 am 0
Convert Date To String & Vice-Versa Swift 4 - iOS

Date To String:


For converting Date to String we are going to create extension for Date as follow:
extension Date
{
    func toString( dateFormat format  : String ) -> String
    {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        return dateFormatter.string(from: self)
    }
}

In above method we can set the required output date format.

Usage:

Add the following lines of code for usage:

let dateString = Date().toString(dateFormat: "yyyy/MMM/dd HH:mm:ss")
print("dateString is \(dateString)")

// output will be 'dateString is 2017/Oct/11 17:16:23'

String To Date:


For converting string to date, we have to give the date format as the string.

Add the following extension to String:
extension String
{
    func toDate( dateFormat format  : String) -> Date
    {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
        return dateFormatter.date(from: self)!
    }
    
}

Usage:

Add the following lines of code for usage:
let dateString = "2017-10-10 15:56:25"
let date = dateString.toDate(dateFormat: "yyyy-MM-dd HH:mm:ss")
print("Date is \(date)")

// output is 'Date is 2017-10-10 15:56:25 +0000'
Read More

10 Oct 2017

Convert UTC Timezone To Local/Device Current Timezone and Vice-Versa Swift 4 - iOS

10/10/2017 11:01:00 am 0
In this article we are going to convert UTC Date format to Current device date format.

UTC is the time standard commonly used across the world. The world's timing centers have agreed to keep their time scales closely synchronized - or coordinated - therefore the name Coordinated Universal Time.

Convert UTC Timezone To Local/Device Current Timezone and Vice-Versa Swift 4 - iOS

I know that you guys are totally confused of this date Timezone conversions.

Here we simply use following method to convert UTC to local.

UTC to Local:

Use the following method for converting:
func UTCToLocal(UTCDateString: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" //Input Format
    dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
    let UTCDate = dateFormatter.date(from: UTCDateString)
    dateFormatter.dateFormat = "yyyy-MMM-dd hh:mm:ss" // Output Format
    dateFormatter.timeZone = TimeZone.current
    let UTCToCurrentFormat = dateFormatter.string(from: UTCDate!)
    return UTCToCurrentFormat
}

Usage:

Call above method as follow:
let dateString = "2017-10-10 9:56:25"

let date = self.UTCToLocal(UTCDateString: dateString)

//output date should be '2017-10-10 15:26:25'

In above method we can customize date formats as per our usage. But the input date format must be same format as input date string.

Local to UTC:

Use the following method for converting:
func localToUTC(date:String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    dateFormatter.calendar = NSCalendar.current
    dateFormatter.timeZone = TimeZone.current
    
    let dt = dateFormatter.date(from: date)
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = "yyyy-MMM-dd hh:mm:ss"
    
    return dateFormatter.string(from: dt!)
}

Usage:

Call above method as follow:
let dateString = "2017-10-10 15:56:25"

let date = self.localToUTC(date: dateString)

//output date should be '2017-10-10 09:26:25'

Read More

8 Oct 2017

Storing/Downloading/Deleting images or videos Using Firebase Cloud Storage

10/08/2017 10:07:00 am 9
Cloud Storage for Firebase is a powerful, simple, and cost-effective object storage service built for Google scale. Firebase SDK adds Google security to file uploads and downloads for your Firebase apps, either if connectivity is slow or fast.

Storing/Downloading images or videos Using Firebase Cloud Storage


If the network connection is poor, the client is able to retry the operation right where it left off, saving your users time and bandwidth. Everything will be done asynchronously in background threads, so that UI won't hang.

We can store images, videos, files, audio in cloud storage by using Firebase SDK. For accessing those files we can use same Google cloud storage.

Uploads and downloads are robust, meaning they restart where they stopped, saving your users time and bandwidth.

Google provides strong security, so that only authenticated users can upload or download files.

Before getting in to Sample Project, Integrate your project with Firebase.

Add the following dependency to podfile:
pod 'Firebase/Storage'

Run pod install and open the created .xcworkspace file.

Configure Firebase Storage Rules:

The Firebase Storage provides a set rules so that files can structure according to the rules.

By default, only authenticated users can access to the Firebase Storage for uploading & downloading files.

There are different authenticated methods choose any one of them.

Using Facebook Login
Using Email & Password
Anonymous Login

In this project we are going to start without setting up Authentication, you can configure your rules for public access.

Go to Firebase console -> Storage -> Rules

Add the following rule and publish:
// Anyone can read or write to the bucket, even non-users of your app.
// Because it is shared with Google App Engine, this will also make
// files uploaded via GAE public.
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}


 Firebase console -> Storage -> Rules


Set up Firebase Storage To iOS Project :

We need to initialize Firebase.

First import the Firebase SDK in AppDelegate.swift file:
import Firebase

Then, in the application:didFinishLaunchingWithOptions: method, initialize the FirebaseApp object:
// Use Firebase library to configure APIs
FirebaseApp.configure()

Open ViewController.swift file add the following code inside viewDidLoad() method:
let storage = Storage.storage()

Create a Reference To upload, download, or delete:

References are created using the FirebaseStorage service and calling its reference method.
// Create a storage reference from our storage service
let storageRef = storage.reference()

You can create a reference to a location lower in the tree, say 'images/car.jpg', by using the child method on an existing reference.
var carRef = storageRef.child("images/car.jpg")

Uploading To Cloud Storage :

For uploading a file firstly we need a reference, we can use the one which created earlier.

We can upload files to storage using two ways:

1. Upload from data in memory
2. Upload from a URL representing a file on device

Here we will show using memory.

Before doing that drag one image to the project and name its as 'car.jpg'.

Add the following method and call in viewDidLoad() method:
func uploadImageToStorage() {
    let storage = Storage.storage()
    var storageRef = storage.reference()
    
    if let image = UIImage(named: "car.jpg") {
        let data = UIImagePNGRepresentation(image)
        print("data \(String(describing: data))")
        
        
        // Create the file metadata
        let metadata = StorageMetadata()
        metadata.contentType = "image/jpeg"
        
        storageRef = storageRef.child("images/car.jpg")
        
        let uploadTask = storageRef.putData(data!, metadata: metadata)
        
        // Listen for state changes, errors, and completion of the upload.
        uploadTask.observe(.resume) { snapshot in
            // Upload resumed, also fires when the upload starts
        }
        
        uploadTask.observe(.pause) { snapshot in
            // Upload paused
        }
        
        uploadTask.observe(.progress) { snapshot in
            // Upload reported progress
            let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
                / Double(snapshot.progress!.totalUnitCount)
            
            print("Upload Percentage == \(percentComplete)")
        }
        
        uploadTask.observe(.success) { snapshot in
            // Upload completed successfully
            print("Upload completed successfully")
        }
        
        uploadTask.observe(.failure) { snapshot in
            if let error = snapshot.error as? NSError {
                switch (StorageErrorCode(rawValue: error.code)!) {
                case .objectNotFound:
                    // File doesn't exist
                    break
                case .unauthorized:
                    // User doesn't have permission to access file
                    break
                case .cancelled:
                    // User canceled the upload
                    break
                    
                    /* ... */
                    
                case .unknown:
                    // Unknown error occurred, inspect the server response
                    break
                default:
                    // A separate error occurred. This is a good place to retry the upload.
                    break
                }
            }
        }
    }
}

Above method will give percentage of upload done,failures causes, pause, resume and success observer.

Build and Run,if everything is correct then we will see 'Upload completed successfully' message in the console.

Then open Firebase console check inside storage -> images -> car.jpg should be there like below:

 storage -> images -> car.jpg


Downloading Image From Cloud Storage:

Now we will download the car image what we uploaded before.

Add the following code and call in viewDidLoad() method:
func downloadImageFromStorage() {
    let storage = Storage.storage()
    var storageRef = storage.reference()
    
    // Create a reference to the file we want to download
    storageRef = storageRef.child("images/car.jpg")
    
    // Start the download (in this case writing to a file)
    let downloadTask = storageRef.getData(maxSize: 5 * 1024 * 1024) { data, error in
        if let error = error {
            // Uh-oh, an error occurred!
        } else {
            // Data for "images/island.jpg" is returned
            let image = UIImage(data: data!)
            
            print("image succesfully downloaded \(image!)")
        }
    }
    
    
    // Observe changes in status
    downloadTask.observe(.resume) { snapshot in
        // Download resumed, also fires when the download starts
    }
    
    downloadTask.observe(.pause) { snapshot in
        // Download paused
    }
    
    downloadTask.observe(.progress) { snapshot in
        // Download reported progress
        let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
            / Double(snapshot.progress!.totalUnitCount)
    }
    
    downloadTask.observe(.success) { snapshot in
        // Download completed successfully
    }
    
    // Errors only occur in the "Failure" case
    downloadTask.observe(.failure) { snapshot in
        guard let errorCode = (snapshot.error as? NSError)?.code else {
            return
        }
        guard let error = StorageErrorCode(rawValue: errorCode) else {
            return
        }
        switch (error) {
        case .objectNotFound:
            // File doesn't exist
            break
        case .unauthorized:
            // User doesn't have permission to access file
            break
        case .cancelled:
            // User cancelled the download
            break
            
            /* ... */
            
        case .unknown:
            // Unknown error occurred, inspect the server response
            break
        default:
            // Another error occurred. This is a good place to retry the download.
            break
        }
    }
}

Above method will give percentage of download done,failures causes, pause, resume and success observer.

Build and Run,if everything is correct then we will see 'image successfully downloaded with file' message in the console.


Deleting Image From Firebase Storage:

We will delete the car image from Firebase storage.

Add the following code and call in viewDidLoad() method:
func deletingImageFromStorage(){
    let storage = Storage.storage()
    var storageRef = storage.reference()
    
    // Create a reference to the file we want to download
    storageRef = storageRef.child("images/car.jpg")
    
    storageRef.delete { error in
        if let error = error {
            // Uh-oh, an error occurred!
        } else {
            print("File deleted successfully")
        }
    }
    
}

Build and Run,if everything is correct then we will see 'File deleted successfully' message in the console.

Open the Firebase console and check whether image deleted or not.

Read More

7 Oct 2017

Safe Area Layout Guides Tutorial iOS 11

10/07/2017 03:39:00 am 0
The layout guide representing the portion of your view that is unobscured by bars and other content. In iOS 11, Apple is deprecating the top and bottom layout guides and replacing them with a single safe area layout guide.

Safe Area Layout Guides Tutorial iOS 11

  • Bottom layout guide & top layout guide are deprecated from iOS 11.
  • We can change safeArea layout insets by using a safeAreaInsets property.
  • safeAreaInsetsDidChange() method will call when the safe area of the view changes.
In iPhone X we have to use safe area layout otherwise in landscape mode the top notch will cut some content as below:

iPone X top notch will cut some content in landscape

Safe area layout guide Using Storyboards:

It's easy by using storyboard, just go to storyboard and select any one of controller.

Left side go to File inspector there simple check mark the use Safe Area Layout Guides.

File inspector there simple check mark the use Safe Area Layout Guides.

We can migrate old projects to Safe area layout guide.

The Storyboard automatically replaces the top and bottom layout guides with a safe area and updates the constraints:

Safe area layout guide Programmatically:

Create your constraints in code use the safeAreaLayoutGuide property of UIView to get the relevant layout anchors.

Now unless you are targeting iOS 11 only you will need to wrap the safe area layout guide constraints with #available and fall back to top and bottom layout guides for earlier iOS versions:

Code:

if #available(iOS 11, *) {
    let guide = view.safeAreaLayoutGuide
    label.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
    label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
   
} else {
    label.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor).isActive = true
    label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}

Conclusion:

  • The safeAreaLayoutGuide is a property of UIView where topLayoutGuide and bottomLayoutGuide are properties of UIViewController
  • The constraintEqualToSystemSpacingBelow method is new in iOS 11 and removes the need to hard code standard spacing. There are also less than and greater than versions. For horizontal spacing there is also constraintEqualToSystemSpacingAfter.
  • We can increase or decrease of safe area size using safeAreaInsets property.

Next Steps :

iOS 11[Swift 4] Navigation Bar With Large Titles and LargeTitleTextAttributes

Read More

5 Oct 2017

Firebase Cloud Firestore Example Project in iOS - Swift

10/05/2017 06:43:00 am 1
Cloud Firestore is a scalable database like Firebase Realtime Database, it keeps your data in sync across client apps through real time listeners and offers offline support for mobile and web so you can build responsive apps that work regardless of network latency or Internet connectivity.

The advantage of using Cloud Firestore is Expressive querying. You can use queries to retrieve individual, specific documents or to retrieve all the documents in a collection that match your query parameters. Your queries can include multiple, chained filters and combine filtering and sorting.

Data Structure:

Cloud Storage data structure will be like following image:

Firebase Cloud Firestore Data Structure
Here we store data in Documents. Documents are like Dictionaries a key value pair which support many different data types, from simple strings and numbers, to complex, nested objects.

Firebase Cloud Firestore Documents

These documents are stored in collections, which are containers for your documents that you can use to organize your data and build queries.

Firebase Cloud Firestore Collection of Documents
Querying in Cloud Firestore is expressive, efficient, and flexible. We can do query to retrieve data at the document level without needing to retrieve the entire collection, or any nested subcollections.

We can do pagination by adding sorting, filtering, and limits to queries. Adding realtime listeners to your app notifies you with a data snapshot whenever the data your client apps are listening to changes, retrieving only the new changes.

Getting Started:

First create sample project in Xcode and add one UILabel, two UITextField's and one UIButton and give outlets. Build and Run that should look like as below:

Sample Demo

Next open Firebase Console -> Database -> Cloud Firestore, next pop up will come with two options, select start in test mode then enable.

Set up Firebase Cloud Firestore To iOS Project :

Next getting into Sample Project,First Integrate your project with Firebase.

Add the following dependencies to podfile:
pod 'Firebase/Core'
pod 'Firebase/Firestore'

Save the file, Run 'pod install' and open the created .xcworkspace file.

Next, We need to initialize Firebase.

Open Xcode project.

First import the Firebase SDK in AppDelegate.swift file:
import Firebase

Then, in the application:didFinishLaunchingWithOptions: method, initialize the FirebaseApp object:
// Use Firebase library to configure APIs
FirebaseApp.configure()

Saving/Adding data to Cloud Firestore:

Open ViewController.swift, add the docRef property.
var docRef : DocumentReference!

Add the following code in viewDidLoad() method:
docRef = Firestore.firestore().document("friends/profile")

By the way, here we are storing friends name and his/her profession. Above reference is the path where we are going to store our data as a Document.

Next add the code for saving data. Add the following code in save button action method:
@IBAction func saveButtonTapped(_ sender: UIButton) {
    guard let name = nameField.text, !name.isEmpty else { return }
    guard let profession = professionField.text, !profession.isEmpty else { return }
    
    let dataToSave : [String: Any] = ["name": name, "profession": profession]
    docRef.setData(dataToSave) { (error) in
        if let error = error {
            print("Oh no! Some error \(error.localizedDescription)")
        }else {
            print("Data has been saved")
        }
    }
}

Run and enter the data in text fields, then tap save button. We will see message as 'Data has been saved'.

Next open Firebase console -> Database -> Cloud Storage:

Firebase console -> Database -> Cloud Storage:

Fetching/Getting data From Cloud Firestore:


Fetching is very simple, we need to get the data from same docRef.

Before that add fetch button to the view and give action outlet.

Adding Button

Add the following code inside fetch button action method:
@IBAction func fetchButtonTapped(_ sender: Any) {
    docRef.getDocument { (docSnapshot, error) in
        guard let docSnapshot = docSnapshot, docSnapshot.exists else { return }
        let data = docSnapshot.data()
        let name = data["name"] as? String ?? ""
        let profession = data["profession"] as? String ?? ""
        self.titleLabel.text = "\(name) is a \(profession)"
    }
}

Run and tap Fetch button, we will see the data at the top like follow:

Fetching/Getting data From Cloud Firestore:

 

Listening for RealTime in Cloud Firestore:

First add the following listener property.
var dataListener : FIRListenerRegistration!

Next add the viewWillAppear() method as following:
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    dataListener =  docRef.addSnapshotListener { (docSnapshot, error) in
        guard let docSnapshot = docSnapshot, docSnapshot.exists else { return }
        let data = docSnapshot.data()
        let name = data["name"] as? String ?? ""
        let profession = data["profession"] as? String ?? ""
        self.titleLabel.text = "\(name) is a \(profession)"
    }
}

Above listener will keep on calling every time the data changes. So we need to remove the observer on viewWillDisappear. So that we can avoid memory problems.

Add the following method:
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    dataListener.remove()
}

Run the project, we can see the title without tapping fetch button. That's good.

Next step is update data in real time. Now add some text in text field then tap save button.

On saving only we can see the title changes in real time without fetch action.

Listening for RealTime in Cloud Firestore:


Conclusion:

Cloud Firestore offers robust access management,Expressive querying and authentication. Secure data by using authentication and rules.


Download sample project with examples :

Read More

1 Oct 2017

Firebase RealTime Database Example Project in iOS - Swift 4

10/01/2017 01:40:00 am 0
Data is stored as JSON and synchronized in realtime to every connected client devices. The Firebase RealTime Database is a cloud-hosted database.

Firebase RealTime Database Example Project in iOS - Swift 4

Data is persisted locally, and even while offline, realtime events continue to fire, giving the end user a responsive experience.

Here we need to structure data, so that inserting and fetching will be done easily. Because the Firebase RealTime Database allows nesting data up to 32 levels deep, you might be tempted to think that this should be the default structure.

Best practices for data structure

Before getting in to Sample Project, Integrate your project with Firebase.

Add the following dependency to podfile:
pod 'Firebase/Database'

Run pod install and open the created .xcworkspace file.

Configure Firebase Database Rules:

The RealTime Database provides a set rules so that data can structure according to the rules.

By default, only authenticated users can access to the RealTime Database for performing read and write operations.

There are different authenticated methods choose any one of them.

Authenticate with Firebase using Facebook Login

Firebase Authentication using Email & Password

Authenticate with Firebase Anonymously on iOS

In this project we are going to start without setting up Authentication, you can configure your rules for public access.

Go to Firebase console -> Database -> Rules

Add the following rule and publish:
// These rules give anyone, even people who are not users of your app,
// read and write access to your database
{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Go to Firebase console -> Database -> Rules

Set up Firebase Realtime Database :

We need to initialize Firebase.

First import the Firebase SDK in AppDelegate.swift file:
import Firebase

Then, in the application:didFinishLaunchingWithOptions: method, initialize the FirebaseApp object:
// Use Firebase library to configure APIs
FirebaseApp.configure()

Once you've initialized Firebase Realtime Database, define and create a reference to your database as follows:

Open ViewController.swift file add the following code inside viewDidLoad() method:
var ref: DatabaseReference!

ref = Database.database().reference()

Writing Data:

Here we can show basic write operations.

Pass types that correspond to the available JSON types as follows:
  •     NSString
  •     NSNumber
  •     NSDictionary
  •     NSArray
For instance, we can add a username by using 'setValue' as follow:
ref.child("users").setValue(["username": "Jhon"])

Build and Run, It runs successfully. Open Firebase console we can see the users dictionary with username as John.

Open Firebase console we can see the users dictionary

Reading Data By Listening :

The FIRDataEventTypeValue event is fired every time data is changed at the specified database reference, including changes to children. To limit the size of your snapshots, attach only at the highest level needed for watching changes. For example, attaching a listener to the root of your database is not recommended.

Add the following method and call in ViewDidLoad() method:
func readData() {
    let userRef = Database.database().reference().child("users")
    let refHandle : DatabaseHandle!
    refHandle = userRef.observe(.value, with: { (snapshot) in
        let userDict = snapshot.value as? [String : AnyObject] ?? [:]
        print(userDict)
        // ...
    })
}

Build and Run, we see an output in Xcode console.

Next for testing realtime go to firebase console and change the name from 'Jhon' to 'Snow'. We can see the log in Xcode console without sending any new request.

For removing the observer add the following code.
if let handle = refHandle {
    Database.database().reference().removeObserver(withHandle: handle)
}

SingleEvent Observer:

let userID = Auth.auth().currentUser?.uid
ref.child("users").observeSingleEvent(of: .value, with: { (snapshot) in
  // Get user value
  let value = snapshot.value as? NSDictionary
  let username = value?["username"] as? String ?? ""
  let user = User.init(username: username)

  // ...
  }) { (error) in
    print(error.localizedDescription)
}

The above observer will call only one time. Here no need to remove observer, it will be removed automatically after single request.

Read More

Post Top Ad