Search Your Question

Json serialization and deserialization

Ans :  


JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
When transmitting data or storing them in a file, the data are required to be byte strings, but complex objects are seldom in this format. Serialization can convert these complex objects into byte strings for such use. After the byte strings are transmitted, the receiver will have to recover the original object from the byte string. This is known as deserialization.

import UIKit

var str = "Hello, playground"

// Starting decode -> json to class or object
// ------------- De-Serialization ----------------

let singleDict = """
{
    "foodName" : "Banana"
    "calories" : 100
}
""".data(using: .utf8)

class Food: Codable {
    
    let foodname : String
    let calories : Int
    
    init(foodname: String, calories: Int) {
        self.foodname = foodname
        self.calories = calories
    }
}

let jsonDecoder = JSONDecoder()
do {
    let foodResult = try jsonDecoder.decode(Food.self, from: singleDict!)
    print(foodResult.foodname)
} catch {
    print("failed to decode \(error.localizedDescription)")
}

// Starting encode -> class or object to json
// ------------- Serialization ----------------

let apple = Food(foodname: "apple", calories: 80)
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
do {
    let jsonData = try jsonEncoder.encode(apple)
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
} catch {
    

}

What is Codable?
Codable is a type alias for the Encodable and Decodable protocols. When you use Codable as a type or a generic constraint, it matches any type that conforms to both protocols.

Before Swift 4, You’d have to serialize the JSON yourself with JSONSerialization, and then typecast every property of the JSON to the right Swift type. We have to do manually map data with struct (Model) properties.
If we are using Codable, then we don't required to map response data with struct property manually. If response's name is different then we can use CodingKey

struct User:Codable 
{
    var firstName: String
    var lastName: String
    var country: String

    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
        case lastName = "last_name"
        case country
    }
}


If you have any comments, questions, or recommendations, feel free to post them in the comment section below!

What is Deep link in iOS?

Ans : 

Deep linking is the idea of not only having a clickable link to open up your app but a smart one that will also navigate to the desired resource.

There are 2 ways of implementing deep linking in IOS: URL scheme and Universal Links.

Comparison :


 Neither of these options will redirect you to the App Store if the app is not installed.

URL Scheme : 

Open Xcode, got to Project Settings -> Info, and add inside ‘The URL Types” section a new URL scheme. Add something of the sort of com.myApp and that’s it. Now install your app, open the app notes and type com.myApp and press enter.



Nothing will happen as IOS do not recognise this as URL. So, type com.myApp://main. Now when we press enter, we can see IOS detected the link and when we click it, a pop up will ask for permission to open MyApp from Notes.

To redirect to specific page or controller : 

Write following AppDelegate method,

  func application(_ app: UIApplication, open url: URL,
                     options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        if let scheme = url.scheme,
            scheme.localizedCaseInsensitiveCompare("com.myApp") == .orderedSame,
            let view = url.host {
            
            var parameters: [String: String] = [:]
            URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
                parameters[$0.name] = $0.value
            }
            
            redirect(to: view, with: parameters)
        }
        return true
    }


and open com.myApp://profile?user=”mananshah”  from notes app.
Here,
     url.scheme = “com.myApp”
     url.host = “profile”
     parameters = [ “user” : “mananshah” ]

This URL will not work if app is not installed. If app is not installed, this will open safari and show blank page. For solving, we should implement Universal link.

Universal Link : 

Universal links are a bit more complex. Basically, we want IOS to relate a webpage URL to our app. Hitting URL expect a json in following format to ensure valid apps :

{
        “applinks”: {
            “apps”: [],
            “details”: [
                {
                    “appID”: “T5TQ36Q2SQ.com.myapp.production”,
                    “paths”: [“*”],
                }
            ]
        }

    }

Applinks indicate this is indeed for the Universal Link declaration.
Apps should be left as an empty array. This is most likely because these types of JSON are used for other purposes other than universal links as well.
Details will then contain an array of your apps and the mapping of each subpath to the respective app.
For each app, you should add a field called appID which is obtained concatenating your teamID and your app’s bundleID. For example, if your TeamID is 123456 and your AppID is com.myApp, then the result is 123456.com.myApp.
In the paths field, an array of strings representing with expressions of the paths which correspond to this app. For example, if you want myApp.com/store to open up a different app than myApp.com/maps, here you can declare that is a wildcard for any string, while ? is a wildcard for any character. As we only have one app, any subpath will lead here, hence the *. If you want to exclude a subpath, just add NOT at the beginning.
-----
Once that is done, we now must add the correct metadata to the app. 
First, open Xcode, go to Project settings -> capabilities. Scroll down to Associated Domains and turn it on. Once it is enabled, we shall add any URL that implements our apple-app-site-association resource, preceded by app links. Inside the Domains section, add a applinks:myApp.com. Once this is done, go ahead and try out your app.
To redirect to specific page or controller : 


public func application(_ application: UIApplication,
                               continue userActivity: NSUserActivity,
                               restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
           if let url = userActivity.webpageURL {
               var view = url.lastPathComponent
               var parameters: [String: String] = [:]
               URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
                   parameters[$0.name] = $0.value
               }
               
               redirect(to: view, with: parameters)
           }
           return true
      }



Universal links allow us to have a fallback webpage if a user does not have the app installed
if the user has the app, the link will open it, and if not, it will fall under the webpage.

Credit : WOLOX

How to release app to testflight?

Ans :

Q. What is TestFlight?
A. TestFlight is a platform provided by Apple that allows you to send a testable version of your app to specific beta users. It’s important to realise this is different than the App Store (which is available to the general public). Once you send a user a TestFlight invitation, they must download the TestFlight app where they can download and use a specific version of your app for 60 days.

App resource and deployment to TestFlight :

Apple’s Developer Portal. Here you create a distinct IDs for an App, get your certificates and much more.
iTunes Connect is where you manage your app, its details, screenshots, and who all has access to the different types of the app info (like Revenue, and User stats).


  1. Register bundle identifier i.e com.benefit.me on developer.apple.com site. Add capabilities if any.
  2. Develop, Download and Install required certificates (ad hoc distribution for TestFlight). 
  3. In iTunes Connect, register your app with required fields.
  4. Goto TestFlight tab, there is no any builds right now.
  5. Now goto  Xcode and Select generic device and then goto  Product > Archive and Choose valid distribution certificate and upload to App Store. It will only uploaded to iTunes Connect portal.


If you go back to the TestFlight tab and click on the iOS TestFlight Builds sidebar item you will now see that your archive is being processed by iTunes Connect. This should take ~15 mins and you will receive an email when done.

Now that our build is on iTunes Connect we need to set up Internal and/or External TestFlight Testing.

After processing, select version no to send to tester, fill required information about what to test, what types of testers or group app has to be sent for testing. After submit, after  sometime, tester will get email or may get notification about new build with version is ready to test.

BuddyBuild or Hockey App are for alternatives to TestFlight.

Source : Quick Guide - Daniel Mathews

How you show current location blue dot on map?

Ans :

self.mapView.myLocationEnabled = YES to hide the blue dot.
set a class to implement CLLocationManagerDelegate to track user's location.

https://stackoverflow.com/a/40058423

What is subscript?

Ans : 

Subscripts are used to access information from a collection, sequence and a list in Classes, Structures and Enumerations without using a method.

These subscripts are used to store and retrieve the values with the help of index without the use of separate method.

To access elements via subscripts write one or more values between square brackets after the instance name.

For example: Array elements are accessed with the help of someArray[index] and its subsequent member elements in a Dictionary instance can be accessed as someDicitonary[key].

Code :

In coding, subscript is same as computed property.



 class monthsInYear {
 private var months = [“Jan”, “Feb”, “Mar”, “Apr”, “May”, “Jun”, “Jul”, "Aug",  "Sep" , "Oct", "Nov" , "Dec"
 subscript(index: Int) -> String {

 get {
       return months[index] // getter is mandatory
  }
 set(newValue) {
       self.months[index] = newValue // setter is optional
     }
   }
 }
 var p = monthsInYear()
 print(p[0]) // prints Jan
 p[0] = “Jan”
 print(p[0]) // prints Jan



If you have any comment, question, or recommendation, feel free to post them in the comment section below!

What is Object mapping that helping Jon parsing?

Ans. : Object mapping is convert to JSON to SomeOtherObject, BussinessModel to PersistenceModel, etc or map fields of JSON to SomeOtherObject fields.

There are many third party library available for same purpose.

1. We use mapping using init method without third party library :

struct User {
  let id: Int
  let name: String
  
  init?(dictionary: [String: Any]) {
    guard let id = dictionary["id"] as? Int else { return nil }
    guard let name = dictionary["user_name"] as? String else { return nil }
    
    self.id = id
    self.name = name
  }
}

do {
  if let userDictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
    let user = User(dictionary: userDictionary)
    //Do something with user
  }
} catch {
  print(error)

}

3. Using codable protocol  (Without third party)
4. SwiftyJson 

In today's world mostly people using 3rd option for  object mapping.

Different task available in NSURLSession

Ans : 

NSURLSession   :       The NSURLSession class and related classes provide an API for downloading data from and uploading data to endpoints indicated by URLs. Your app can also use this API to perform background downloads when your app isn’t running or, in iOS, while your app is suspended.
It is replacement of NSURLConnection from iOS 7.

Types of URL Sessions :


  1. default sessions: behaviour like NSURLConnection 
  2. ephemeral sessions: not cache any content to disk 
  3. download sessions: store the result in file and transferring data even when app is suspended, exits or crashes
Based on above sessions, developers can schedule three types of tasks: 

  1. data tasks: retrieve data to memory 
  2. download tasks: download file to disk 
  3. upload tasks: uploading file from disk and receiving response as data in memory 


func httpGet(request: NSURLRequest!, callback: (String, String?) -> Void) {
            var session = NSURLSession.sharedSession()
            var task = session.dataTaskWithRequest(request){
                 (data, response, error) -> Void in
                 if error != nil {
                     callback(“”, error.localizedDescription)
                 } else {
                     var result = NSString(data: data, encoding:
                                           NSASCIIStringEncoding)!
                     callback(result, nil)
                 }
            }
            task.resume()
        }
        

Which type inheritance objective c support?

Ans : Objective-C supports multi-level and hierarchical inheritance.

How many times Viewdidload and viewDidLayoutSubviews called?

Ans : 

ViewDidLoad called once only when all views are loaded.

viewDidLayoutSubviews :  Apple gave a very good explanation on this by saying that it is called to notify the view controller that its view has just laid out its subviews.

In another word, viewDidLayoutSubviews is called every time the view is updated, rotated or changed or it’s bounds change.

But know that with viewDidLayoutSubviews, it only take places after all the auto layout or auto resizing calculations on the views have been applied. Meaning the method viewDidLayoutSubviews is called every time the view size changes and the view layout has been recalculated.

Read More : AppCoda

Which method will first called if I came from back button?

Ans : 

The navigation controller sends viewWillAppear: to a view controller before putting its view on the screen, and viewDidAppear: after.

Inside viewWillAppear: and viewDidAppear:, the view controller can check self.isMovingToParentViewController.

If isMovingToParentViewController is YES, the view controller is being added to the navigation controller in the first place (presumably because it's the navigation controller's root view controller, or because it is being pushed).

If isMovingToParentViewController is NO, the view controller is already in the navigation controller's stack, and another view controller is being popped to reveal it.