Monday, March 11, 2019

Create BKS using portecle

download certificate from windows google chrome with cer extention
        open portcle
            create new bks file
            open downloaded certificate
            save with entering pwds

        use saved bks file in android app with the given passwords
Swift - AppToApp communication 

https://developer.apple.com/documentation/uikit/core_app/communicating_with_other_apps_using_custom_urls

communicate with using URL
---------
create url schemes
    go to prokject-> info -> urlTypes
        fill identifier - Actually there is no usage at all. you can use anything. only the sceme and role considered.
        URL schemes - unique app scheme which other apps use to open the app, cannot use existing ios system schemes in here (https://developer.apple.com/library/content/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007899)
        Role -
            Editor - schemes if we are defines
            Viewer - existing schemes in iOS system (like photo viewer, email , sms apps)

    how it works
        if we want to open app2 from app1
            in app2
                identifier - dont know the correct usage. in apple Doc also not gives a full Description
                schecme - used iPay
                role - Editor (this is our own define scheme. so need to use as Editor. if systemdefine scheme should as view)

            in App1
                app1 we should also have to define url scheme for matching for appys2. scheme should be same and role should None.
                    identifier - can use anything
                    schecme - used iPay
                    role - None

                let kCustomURLScheme = "ipay://" // only the sceme used. not identifier
                let customURL = URL(string: customURLScheme)!
                if UIApplication.shared.canOpenURL(customURL) {
                    if #available(iOS 10.0, *) {
                        UIApplication.shared.open(customURL, completionHandler: { (success) in
                            print("Open url : \(success)")
                        })
                    } else {
                        UIApplication.shared.openURL(customURL)
                    }
                    return true
                }
    ** if we use same scheme for two application

        system starts first installed application. if we uninstall first app then it will open second app.


Swift push notification

https://firebase.google.com/docs/cloud-messaging/ios/client
    create project
    add required POD
    create apns key in apple developer portal
    upload that token in to firebase project
------------
push notfication in appDelegate method execution steps

didFinishLaunchingWithOptions
didReceiveRegistrationToken  -- this return the push token

        didRegisterForRemoteNotificationsWithDeviceToken  --  this will run when app kill and run again

send notification from firebase
app is in foreground - userNotificationCenter - willPresent
app in bg -
    notification shows in notification bar
    click on notification' - userNotificationCenter - didReceive

app kill and send notification  (same as above)
     notification shows in notification bar
    click on notification' - userNotificationCenter - didReceive

-------------
{
    "to": "PUSH_TOKEN_HERE",
    "notification": {
        "body": "You have authorized LKR 20.00 to test from your A/C *******0269 on 23-04-2018 at 11:10. TXN ID : 20857",
        "title": "Payment Successful !!",
        "icon": ""
    },
    "data": {
        "notificationType": "WEB_PAYMENT",
        "data": {
            "instrumentReference": "W000000000000631"
        }
    }
}

notification  - this part automatically handled by app when only app in background (both android and ios). it shows notification. we need to pass body and title

data - this part only trigger when app is in forground (in both ios & android). we can catch these values inside data object.

CocoaPods

What is CocoaPods
    CocoaPods manages library dependencies for your Xcode projects.

    The dependencies for your projects are specified in a single text file called a Podfile. CocoaPods will resolve dependencies between libraries, fetch the resulting source code, then link it together in an Xcode workspace to build your project.

POD
    command line tool to work with pod files

Installation
    sudo gem install cocoapods

    pod required ruby installation. checko ruby version
        ruby -v

    to maintain pod local repository use
        pod setup
            this will create master repo in user-> name-> .cocoapods -> repos...
            i think this is lile maven repo. we can maintain repo from local rather than downloading same repo.
            this is the main repo path
                https://github.com/CocoaPods/CocoaPods

add pod in to project
    pod init
        to init pod it needs a xcode project. without project no pod init ;)
        this will create a pod file.

open pod file using text editor
    use xcode interminal use this command
        open -a Xcode Podfile

adding required library projects as this
    pod 'JLocationKit', '~> 1.0.3'

downloading lib projects
    pod install

update missing pods
    pod install --repo-update

to run pod project open xcode using App.xcworkspace
    do not open using project file

remove pod from a project
    $ sudo gem install cocoapods-deintegrate cocoapods-clean
    $ pod deintegrate
    $ pod clean

    $ rm Podfile
uiviewcontroller life cycle

application  - AppDelegate
viewDidLoad
viewWillAppear
viewDidAppear
applicationDidBecomeActive  - AppDelegate
applicationWillResignActive - AppDelegate

home click
----------
applicationDidEnterBackground - AppDelegate
applicationWillEnterForeground - AppDelegate

again open app from icon click
--------------
applicationDidBecomeActive - AppDelegate
applicationWillResignActive - AppDelegate

app killed by using running apps
---------------
applicationWillTerminate - AppDelegate


viewDidLoad  -  oncreate
viewWillAppear  - onresume
viewDidAppear  - onresume
viewWillDisappear - onpause ( these will called when open another controller, not at home click )

viewDidDisappear - ondestroy ( these will called when open another controller , not at home click)

Swift localization

first need to setting project localization
    select project-> info -> localization
        click + sign and select required languages

in ios string files can add in two places
    for storyboard wise localization
        these strings cannot apply programatically
        in inspector tab select required locations
            this will create new string files in project->project name folder->  lancode.IProj folder -> Main.String
                if launcher storyboard localization added it will create LaunchScreen.strings file in same folder

        *** These language applied when user changed the device language in setting.
        when app specific language change can do by changing the budle as below. but user needs to restart the app to use these strings.

    programatically access strings
        select project-> new file -> String -> name as Localizable.strings (name should be this)
            this will create a file in  project-> Localizable.strings file
        select that file and click localize button in inspector tab
            select required languages
            add strings in this format
                "key" = "value";

        these string files access in program by attach bundle path to these files. to change path
            let path: String? = Bundle.main.path(forResource: lang, ofType: "lproj")
            if path == nil {
                bundle = Bundle.main
            }
            else {
                bundle = Bundle(path: path!)

            }
Swift- Working with rest service

parts of a web request
    protocol    - rules
    subdomain   - point a more specifc server or etc
    domain      - unique reference to specific site
    port        -
    path        - refer specifi sub directory or file
    query param - more detail of request

    request type - GET, POST etc
    headers - key value pair which tells server how to handle the request
            response also has header which describe how the client use the information
    body    - data send or received

playgroud setup for network request
    playground default support for synchronous request. means lines runs top to bottom. so to call network requet has some changes in playground. add these lines in top
        import PlaygroundSupport

        PlaygroundPage.current.needsIndefiniteExecution = true

///////////////////////
 like in java we can seperately invoke service call and get the response as callback function. everything step by step in here. last class is using all concepts

        import Foundation
        import PlaygroundSupport


        PlaygroundPage.current.needsIndefiniteExecution = true  // make playgroud to run asnchronous request

        //let url = URL(string: "https://api.nasa.gov/planetary/apod?api_key=NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo")!
        //let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        ////    if let data = data {
        ////        print(data) // print as bytes
        ////        print(data as? NSData)// print as object
        ////    }
        //   
        //    //get as json object
        //    if let data = data,
        //        let string = String(data: data, encoding: .utf8) {
        //        print(string)
        //    }
        //    // end of return json object
        //}
        //
        //task.resume()
        ///////////////////////////////////////////////////////////

        // add query parameters seperately

        //extension URL {
        //    func withQueries(_ queries: [String: String]) -> URL? {
        //        var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
        //        components?.queryItems = queries.flatMap
        //            { URLQueryItem(name: $0.0, value: $0.1) }
        //        return components?.url
        //    }
        //}
        //
        //let baseURL = URL(string: "https://api.nasa.gov/planetary/apod")!
        //let query: [String: String] = [
        //    "api_key": "NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo",
        //    "date": "2011-07-13"
        //]
        //
        //let url = baseURL.withQueries(query)!
        //let task = URLSession.shared.dataTask(with: url) { (data,
        //    response, error) in
        //    if let data = data,
        //      let string = String(data: data, encoding: .utf8) {
        //        print(string)
        //    }
        //}
        //
        //task.resume()

        ///////////////////////////////////////////////////////////
        /*josn serilization

        struct PropertyKey {
            static let title = "title"
            static let description = "explanation"
            static let url = "url"
            static let copyright = "copyright"
        }

        class PhotoInfo{
            var url : URL
            var description : String
            var title : String
            var copyright : String?
           
            init?(json: [String: Any]) {
               
                guard let title = json[PropertyKey.title] as? String,
                    let description = json[PropertyKey.description] as? String,
                    let urlString = json[PropertyKey.url] as? String,
                    let url = URL(string: urlString) else { return nil }
           
                self.url = url
                self.description = description
                self.title = title
                self.copyright = json[PropertyKey.copyright] as? String
               
            }
        }

        extension URL {
            func withQueries(_ queries: [String: String]) -> URL? {
                var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
                components?.queryItems = queries.flatMap
                    { URLQueryItem(name: $0.0, value: $0.1) }
                return components?.url
            }
        }

        let baseURL = URL(string: "https://api.nasa.gov/planetary/apod")!
        let query: [String: String] = [
            "api_key": "NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo",
            "date": "2011-07-13"
        ]

        let url = baseURL.withQueries(query)!
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let data = data,
                let rawJSON = try? JSONSerialization.jsonObject(with:data),
                let json = rawJSON as? [String: String],
                let photoInfo = PhotoInfo(json:json) {
                    print(photoInfo)
               
            }
           
        //  to get normal json object use this way
        //    if let data = data,
        //        let rawJSON = try? JSONSerialization.jsonObject(with:
        //            data),
        //        let json = rawJSON as? [String: String] {
        //            print(json)
        //        }
        }

        task.resume()
         **/

        //////////////////////////
        //getting a callback with params
         /* func performLongRunningOperation(callbackFuncName: @escaping (retunFunctionParam1,retunFunctionParam2) ->
            Void) {
            // Code that performs a long running operation
            successFunc(returnParam1Value,returnParam2Value)
        }
        //example
        func callService (callbackFunc : @escaping (String, Int) -> Void) {
            callbackFunc("hi", 10)
        }
       
         // pass callback function as parameter and other parameters also
       
         func callService (urlStr : String, callbackFunc : @escaping (String, Int) -> Void) {
            callbackFunc("hi", 10)
         }
       
       
         callService (urlStr: "sss",callbackFunc : { (strVal,intVal) in
            print(strVal)
         })
       
         */

        ///////////////////////////// network request with callback
        struct PropertyKey {
            static let title = "title"
            static let description = "explanation"
            static let url = "url"
            static let copyright = "copyright"
        }

        class PhotoInfo{
            var url : URL
            var description : String
            var title : String
            var copyright : String?
           
            init?(json: [String: Any]) {
               
                guard let title = json[PropertyKey.title] as? String,
                    let description = json[PropertyKey.description] as? String,
                    let urlString = json[PropertyKey.url] as? String,
                    let url = URL(string: urlString) else { return nil }
               
                self.url = url
                self.description = description
                self.title = title
                self.copyright = json[PropertyKey.copyright] as? String
               
            }
        }

        extension URL {
            func withQueries(_ queries: [String: String]) -> URL? {
                var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
                components?.queryItems = queries.flatMap
                    { URLQueryItem(name: $0.0, value: $0.1) }
                return components?.url
            }
        }

        //The @escaping keyword tells the compiler that the code in the closure will be executed after the function has returned, or has finished executing all the code.

        func callService(urlStr:String , funcCallback : @escaping (PhotoInfo) -> Void) {
            let baseURL = URL(string: urlStr)!
            let query: [String: String] = [
            "api_key": "NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo",
            "date": "2011-07-13"
            ]
           
            //here multiple conditions checking using , instear && mark
            let url = baseURL.withQueries(query)!
            let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let data = data,
            let rawJSON = try? JSONSerialization.jsonObject(with:data),
            let json = rawJSON as? [String: String],
            let photoInfo = PhotoInfo(json:json) {
                funcCallback(photoInfo)
                }
            }

            //                if let data = data{
            //                    print(data)
            //                    let rawJSON = try? JSONSerialization.jsonObject(with:data)
            //                    if let jsona = rawJSON as? [String: String] {
            //                        if let photoInfoa = PhotoInfo(json:jsona){
            //                            funcCallback(photoInfoa)
            //                        }
            //                    }
            //                }
           
           
            task.resume()
        }

        var urls = "https://api.nasa.gov/planetary/apod"

        callService (urlStr: urls, funcCallback:  { (photoInfoObj ) in
            print(photoInfoObj.title)
        } )

        //we can call this way also.
        callService (urlStr: urls) { (photoInfoObj ) in
            print(photoInfoObj.title)
        }
Swift UI Navigation

three main ways (App development with swift iBook)
        using navigation controller
        using normal segues direclty link to viewcontrollers
        using segues programatically (use segue id to navigate after check conditions)

    https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/ImplementNavigation.html

     A navigation controller manages transitions backward and forward through a series of view controllers. The set of view controllers managed by a particular navigation controller is called its navigation stack. The first item added to the stack becomes the root view controller and is never popped off (removed from) the navigation stack.

     add navigation controller to scene
        select scene doc
            Choose Editor > Embed In > Navigation Controller
        the story board entry point will be automatically added to navigation controller

        this will add a bar in all scenes called navigation bar. this can handle all backword and forward navigation
            to use auto back item
                add Navigation item to view. this will automatically add back arrow and click will move to back.
                the segue shoud show. not work for present as popover

            to use button add
                add bar buttons for add back and forward.
                To go back
                    dismiss(animated: true, completion: nil)
                To go forward
                    click -> control drag to relavant scene

                create super view controller and make other viewCOntrollers as children. make commont nav bar button items click event if you want and link click event with super controller function.

    using normal segues direclty link to viewcontrollers
        in this normal button use. no navigation controller. button segue link with view controller. to go back click use "Unwind Segue" way. it means
            if you want to come back second to first
                in first viewcontroller add method like
                    @IBAction func funcName(unwindSegue: UIStoryboardSegue) {}
                in secind button click+control+ drag to exit icon in viewController header. this will suggest that function, it will auto do back process.

    using segues programatically
        here we add buttons to normal way to viewcontroller. but create segeue is doing by click on firstviewController header bar yellow icon(first icon)+ control+ drag to second view controller. another segue like same wat to another viewController. remember to add segue identifier.
        then create action event to each button by normal control+click+ drag to viewcontroller. add this line to connect with each segue
             performSegue(withIdentifier: "segue_id", sender: nil)
        this way can use to check condition and open specific view controller

        to perform back event in second to first use above any way.

pass values from viewControllers
    https://stackoverflow.com/questions/5210535/passing-data-between-view-controllers?rq=1

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let secViewCtrl = segue.destination as! SecondVcViewController
        secViewCtrl.strFromFirst = "From first".
    }

    in secondvc create var
        var strFromFirst

tabviewcontroller
    drag view controller to story board and editor-> embed in -> tab bar controller
    connect other view controllers as normal way by click + control+drag

UIViewController life cycle
    https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html

    viewDidLoad. - like oncreate
    viewWIllAppear. - like onresume
    ViewDidAppear
    viewWIllDisappear. - like onpause
    viewDidDisappear   - can handle ondestroy part.

    when app open
        TabFirstViewController - viewDidLoad
        TabFirstViewController - viewWillAppear
        TabFirstViewController - viewDidAppear
    swcond VC load
        TabSecondViewController - viewDidLoad
        TabFirstViewController - viewWillDisappear
        TabSecondViewController - viewWillAppear
        TabSecondViewController - viewDidAppear
        TabFirstViewController- viewDidDisappear
    back to first VC
        TabSecondViewController - viewWillDisappear
        TabFirstViewController - viewWillAppear
        TabFirstViewController - viewDidAppear
        TabSecondViewController - viewDidDisappear
    kill app in first VC
        TabFirstViewController - viewWillDisappear
        TabFirstViewController- viewDidDisappear

    what to handle viewWillDisappear vs viewDidDisappear
        when viewWillDisappear called next viewDidDisappear called. viewWillDisappear can use to hide keyboard, save edits etc. viewDidDisappear can use to stop running services etc
Swift Reference

declaring variable
    var str = "Hello"

declaring constant
    let str ="hello"
    str = "world" // this wont compile constant cannot reassign

data types
    Int , Double, Bool, String, Character

    String equality check
        empty check
            str.isEmpty
        double equal ==
            this check identical caharacter in same order. simple capital cases checked here
        .contains
            check substring found or not

if condition
    same as java. but && can check using , in swift
        var x = 10

        if x != 9, x != 10 , x != 6 {
            print("aaa")
        }else {
            print("bbb")
        }

        output  = bbb

optionals ? !
    variable without initialize and use throw compile time error

    //var y  // swift is type safety. so cannot use without type
    //var y = 10 // this is ok. type is int
    //var y : Int
    //print(y) // this return errr because no value

    var y : Int?
    //print(y) // this print nil
    //print(y!) // this is error. beacause cannot use nil value because of optional
    var z = y // this is fine. but assign nil value to z. this may cause crash

    //var z2 = y! // ! use to wrap z2 as int. this raise error because nill value

    // so have to check nill. two ways
    if y != nil {
    //    var z2 = y  // without unwrapping z is not idetified as INT
    //    var k = z2 + 5 // so without z2 type raise error
        var z3 = y!  // Wrap using ! to Int value
        var k2 = z3 + 5 // now z3 is Int . so run fine
       
    }
    // second way. best way
    if let y2  = y {
        print(y2)
    }


    ** so in my knowledge optional is use to make app without crash due to nil value. we have to use if let for optional variables and else part to handle nil values

declaring function
    func funcName( name : String, lastname : String){
        print("my name is \(name) \(lastname)")
    }

    2nd way
    func aa(x1 var1:String, x2 var2 :String){
        print ("hello v\(var1) df \(var2)")
    }

    aa(x1: "dd", x2: "sdasd")


invoke function
    funcName(name: "thu",lastname: "wijre")

invoke. function without variable name
    define function parameter with underscore

    func abc(_ name:String){
        print (name)
    }

    abc( "dsfdsf").  // no need to add variable name when invokint if uderscore used

function with default parameter values
    func abc(_ name:String, age : Int = 10){
        print ("\(name) sdfdf \(age)")
    }
    abc( "dsfdsf")

function return value
    func returnInt(x1 :Int, x2 :Int) ->Int{
        return x1+x2
    }

    print (returnInt(x1: 10, x2: 20))

enum
    like enum in java. same concept
        enum CompassPoint {
          case north, east, south, west
        }
    usage
        let compassHeading: CompassPoint = .west
        switch compassHeading {
          case .north:
            print("I am heading north")

structures
    structures are same as classes but no inhertance in structures.

    struct xx{
        var x2=10
       
        func printX(){
           print(x2)
        }
    }

    var a1 = xx()
    //let a1 = xx() // this cannot be done. constant cannot assign properties. because next line trye to assign x2 value.
    a1.printX()
    a1.x2 = 89
    a1.printX()

    this is OK
        let b1 = xx().x2
        print(b1)

        let b2 = xx(x2: 50)
        print(b2)

    Initializers
        “All Swift types come with an initializer, which is similar to a function that returns a new instance of the type. The default initializer is init().”

        var string = String.init() // ""
        var integer = Int.init() // 0
        var bool = Bool.init() // false”

        this is short version
            var string = String() // ""
            var integer = Int() // 0
            var bool = Bool() // false”

        Memberwise initializer
            struct Person {
              var name: String
           
              func sayHello() {
                print("Hello, there!")
              }
            }
           
            let person = Person(name: "Jasmine")

        initialize multiple values
            struct Temperature {
                var celsius: Double
                init(celsius: Double) {
                    self.celsius = celsius
                }
                init(fahrenheit: Double) {
                    celsius = (fahrenheit - 32) / 1.8
                }
            }
            let currentTemperature = Temperature(celsius: 18.5)
            let boiling = Temperature(fahrenheit: 212.0)
            print(currentTemperature.celsius)
            print(boiling.celsius)

    mutating methods
        in cases need to update values using instance methods rather than using above init methods u need to use mutating keyword

        struct test{
            var x : Int = 0
           
             mutating func increment(){
                x = x+1
               
            }
           
             mutating  func  incrementByVal(by val : Int){
                x = x+val
            }
           
            func printx(){  // here no updation. so no need mutating keyword
                print(x)
            }
        }

        var a = test()
        a.increment()
        a.incrementByVal(by: 5)
        a.printx()

        same class declarion is here
            class test1{
                var x : Int = 0
               
                func increment(){
                    x = x+1
                   
                }
               
                func  incrementByVal(by val : Int){
                    x = x+val
                }
               
                func printx(){
                    print(x)
                }
            }

            var a1 = test1()
            a1.increment()
            a1.incrementByVal(by: 5)
            a1.printx()

    computed properties
    property to perform a calculation to return value use this way

        struct temp{
            var celcius :Double
           
            var farenhite : Double {
                return celcius + 32
            }
           
        }

        let b1 = temp(celcius: 24)
        print(b1.farenhite)

    Property Observers
        Swift allows to get previous value when set a new value. willset and didset keywords used
        here two more keywords, newValue oldValue

        struct test{
            var x :Int = 10{
                willSet{
                    print("new val \(newValue)")
                }
                didSet{
                    print("Old val \(oldValue)")
                }
            }
        }

        var x = test()
        x.x = 9

        output
            new val 9
            Old val 10

    static veriables and methods
        struct test{
            static var x :Int = 10;
           
            static func m(){
                print("m")
               
            }
        }

        print(test.x)
        test.m()

        ** static vars cannot use in when instantiated
            var aa = test()
            aa.x = 20 // this cannot done. error

    copying
        assign a structer to a variable and again changed structer may not changed previous assigned value
            struct test{
                  var x :Int = 10;

               
                static func m(){
                    print("m")
                   
                }
            }

            var t = test()
            var t2 = t
            t.x = 20

            print(t.x)
            print( t2.x)

            output
                20,10

    self
        self refers to the current instance of the object. like this in java

    Variable Properties
        if assigned structer instance to a constant you cannot change structer variable too
            struct test{
                var x :Int = 10;
            }

            let t = test()
            t.x = 3. // this is compile error

create class
    same as above discussed structer. only difference is classes can iherited.
    in same file you cannot use class and structer using same name. :)

    class A{
        var x="etstwrwrt";
       
        func printx(){
            print(x)
        }
       
        func A(){
            print ("df")
        }
    }

    instantite class
        let a  = A()
        a.printx()
        a.A()

    aa(x1: "wq", x2: "ere")

    Constructor
        not like in java. constructor no need class name. just require init keyword

        class A{
            init() {
                 print ("A1")
            }
            func  A(){// this is not a contructor. work as normal function
                print ("A2")
            }
        }

        var x = A()
        x.A()



    Inheritance
        same as in java
            class A{
                var x :Int = 10
            }

            class B : A{. // inherit class A (use : )
                func printXInB(){
                    print(x)
                }
            }

            var x = B()
            x.printXInB()

    override
        only functions can override, not varibles. sholud use override keyword

        class A{
            var x :Int = 10
            func printX(){
                print(x)
            }
        }

        class B : A{
           
           override var x : Int = 90. // this is not allowed
            var x : Int = 90 // this is not allowed
           
           override func printX(){ // functions can override using override keyword
             var x : Int = 90. // this is ok. initialization inside function

              x = 80. // this change function variable
                print(x)
            }
        }

    super
        use super keyword to override super class variables

        class A{
            var x : Int = 10
           
            init(x : Int) {
                self.x = x
                print(x)
            }
        }

        class B :A{
            init() {
                super.init(x: 20)
            }
        }

        var b = B()

    reference
        in structer we discuss this in copy section. but in class when we instance a class it store in memory. when we copy the referenct to another variable it also refer same memory location. but in structer when copy instance it create another memory location. so in classes newly refence var update class var or constant it will change both reference var values

        class A{
            var x : Int = 10
        }

        var a = A()
        var a2 = a
        a2.x = 20

        print(a.x). // output as 20

class ot structure
Because classes and structures are so similar, it can be hard to know when to use classes and when to use structures for the building blocks of your program.
As a basic rule, you should start new types as structures until you need one of the features that classes provide.
Start with a class when you're working with a framework that uses classes or when you want to refer to the same instance of a type in multiple places.
when you need to maintain stable identity (want to get updated value rather than copied) use classes

protocol. -  seems like interfaces in java
    A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality.

    creating variable
        var varname : String {
            get
        }
        every variable sholud mark inside curly bracket with get or set (get means readonly var and set means write.  get set means read and write)

        protocol testp{
            var x : Int {
                get set. // var as getter and setter. cannot only setter. but can only getter
            }
            func printx() // need to overrite in inherited classes or structs
        }

        class A : testp{
            func printx() {
                print("dd")
            }
           
            var x : Int {
                get{
                    return 10
                }
                set (newVal){
                    print(newVal) // setter happen here. enter anythig when set value. but cannot assign like this x = newVal
                }
            }
           
        }

        let a1 : A = A()
        print(a1.x)  // print 10
        a1.printx()  // print dd
        a1.x = 98   // print 98

extension
    extensions is add new functionality to anything

    extension String {
        func sayHello(){
            print("hello")
        }
    }
    var str = "hi"
    str.sayHello()


    ///////////////////////
    extension Int{
        func square() -> Int {
            return (self * self)
        }
    }

    var x = 8
    print(x.square())

    //////////////////////
    class User {
        var firstname = "hello"
        var lastname = "swift"
    }

    extension User{
    //    var fullname : String  = firstname + " " + lastname  // cannot use variables in extensions
       
        func getFullname() -> String {
            return firstname + " " + lastname
        } 
    }

    var bob = User()
    print (bob.getFullname())

closure
    this is work same as functions but these has noname and no func keyword, and also very short

    func adding (x : Int, y :Int) -> Int{
        return x + y
    }

    print(adding(x: 5, y: 6))

    var addClosure : (Int, Int) -> (Int) = { x, y in
        return x + y
    }

    //shortestway
    var addClosure2 : (Int, Int) -> (Int) = {
        return $0 + $1  // can use param order with $ sign
    }

    print(addClosure(5,6))
    print(addClosure2(5,6))

    //var addClosure : (firstParamType, SecondParamTyoe) -> (ReturnType) = { FirstParamRefereName, secondParamRefereName in
    //    return x + y  // operation
    //}

    // without parameters
    // normal way
    func printHello () -> String{
        return "hello"
    }

    // with closure
    var helloClosure : () -> (String) = {
        return "hello"
    }
    print(printHello())
    print(helloClosure())


collections
    Arrays
        var x : [Int] = [2]   // declare array
        x [0] = 12

        var y : Array<Int> = [2]   // declare array
        y[0] = 23

        var z  = [Int] () // declare array
        z = [2]
        z[0] = 8

        var a1 = [Int] (repeating : 0 , count : 100)  // declare array with 100 zeros
        print(a1[20])

        var x1 = ["abc", "cde", "dfds"] // can contains only single type
        var x2 : [Any] = ["abc", "cde", "dfds",10]  // can caontaint any type
        var x3 : [String] = ["abc", "cde", "dfds"] // can contain only String type

        print(x[0])
        //print(y[0])
        print(x1[0])
        x1.insert("bbb", at : 0)  // insert item dynamically. here at value sholud inside array length.
        print(x1[0])

    Dictionary
        dictionary is a associated key with a value. key is unique. dictionay arrange as alphabatically order to search easy

        var ff = ["a" : 100, "b" : 45]
        //var ff = ["a" : "ttt", "b":45] // this is compile error, cannot contain different types
        print(ff["a"])

        var x1  = Dictionary<String,Int>()
        x1.updateValue(120, forKey: "xx")
        print(x1["xx"])

        var a1 : [String : Int] = [:]  // initialize empty dictionary
        a1.updateValue( 134, forKey: "aa") // key and value
        print(a1["aa"])

Loops
    for loop
        for i in 1...5 { // included 5 also here
            print("xx \(i)")
        }

        var x1 = ["a","b","c"]
        for c in x1 {
            print(c)
        }

        for letter in "abcd".characters{
            print(letter)
        }

        // index with value
        for (index,letter) in "abcd".characters.enumerated(){
            print("\(index) \(letter)")
        }
        // output
        //0 a
        //1 b

    while loop
        var x = 0
        while x < 3
        {
            print(x)
            x = x+1

        }

My Git experience

installing git flow in mac

need homebrew
https://brew.sh
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

install gitflow
https://github.com/nvie/gitflow/wiki/Mac-OS-X

$ brew install git-flow

initialize gitflow
git flow init

this will ask to provide release and development branches. this means you need to maintain two different main branches to development and release. If you already created branches in origin, bring them in to local by
git checkout origin/branchname
this will automatically switch you to that branch.

then do required things once tyoe git flow init.
init      Initialize a new git repo with support for the branching model.
    feature   Manage your feature branches.
    release   Manage your release branches.
    hotfix    Manage your hotfix branches.
    support   Manage your support branches.
    version   Shows version information.

git flow cheat sheet
https://danielkummer.github.io/git-flow-cheatsheet/

start new feature
git flow feature start feature_name

commit changes to feature branch
add files
git add .
commit
git commit -m "message"

finish feature
git flow feature finish feature_name
this will
Merges MYFEATURE into 'develop'
Removes the feature branch
Switches back to 'develop' branch

push local developemnt to origin
you should be in local development branch
git push

cannot use branch name as release due to create releases
git flow release start
these branches create under release . so no more release branches there
/////////////////
delete branch
git branch -d branch_name

delete remote branch
*** in Origin there is a master branch, which means this branch is the main branch. other all branches merege with this. you cannot delete this master branch.

$ git push -d origin <branch_name>

deleted orign branch sync with local
git fetch -p origin

*** in Origin there is a master branch, which means this branch is the main branch. other all branches merege with this. you cannot delete this master branch.

Tagging
add tag
git tag tagname
push tag to origin
git push origin tag_name
or
git push --tags

merge conflicts
git mergetool
this will ask switch merge tool to open.
press enter and merge conficts and commit and push if works fine

merge branches
merge dev changes to master
in master
git merge develop

see previous commit changes
git show

see changes before commit
git diff

changes of a file
git diff filename.extension

difference between two branches
git diff branch_1..branch_2
use two dots between two branch names

reset
Reverting The Working Copy to an Older Commit
git reset commit_id (56e05fced )
git reset commit_id f9be0cde2e091368b8e3241a0e8d0a55bd6fa7a3
Reverting Working Copy to Most Recent Commit
git reset --hard HEAD

remove untracked files
git clean -f -d

view history
git log

discard changes
git stash

rename remote branch
$ git branch new-branch-name origin/old-branch-name
$ git push origin --set-upstream new-branch-name   (remember to change main branch in remote before this command)
$ git push origin :old-branch-name

remote deleted branch show in local. to delete it from local use
git remote prune origin

create gitignore file in mac
opent terminal
touch .gitignore

see ignore files
git status --ignored

To stop tracking a file that is currently tracked, use git rm --cached. (these filese should mention in .gitignore file)
git rm --cached iPay.xcodeproj/project.xcworkspace/xcuserdata/Thushara.xcuserdatad/UserInterfaceState.xcuserstate
git rm --cached .DS_Store

stuck in merge conflicts when feature finish
best thing is to forcely checkout to other branch without commit existing merge.0712773696
git checkout -f feature/ft

////////////////////
git maintain in submodule
https://blog.shopsys.com/how-to-maintain-multiple-git-repositories-with-ease-61a5e17152e0
https://git-scm.com/book/en/v2/Git-Tools-Submodules

///////////////
teams with plan
--------------
with the free plan one team can handle only with 5 users.
https://confluence.atlassian.com/bitbucket/plans-and-billing-224395568.html

structure is
team
project
repository

team has members
reposiroty has owner (it can be a team or individual, for free plan 1 repository can use only 5 members (sum of team members and individuals))
project has repositories

at any time repo can transger to any project. many teams can access one repository.

/////////////////