Explanation: UserDefaults iOS


How to save and retrieve data using UserDefaults in Swift. 

UserDefaults is an important data storage instance in Swift. Here we can store Any data type values by using Key value pair.

UserDefaults

Change Google Map style using GMSMapStyle in Swift


Hi Buddy,

This is a Step by step tutorial about how to apply map style in GoogleMaps for iOS using Swift and Cocoapods to build the App. 

Basic design on SwiftUI


Check my channel on YouTube and subscribe.

Hi Friends,

Learn SwiftUI from YouTube by my channel. Subscribe my channel and learn more and more.

Launch multiple simulator on a single compile in Xcode


Hi Friends,

I have develop a communication application. I will run same build in multiple simulators each time to test a design. So, I did like run on iPhone X and Stop. Then run on iPhone 7 and stop. This method of developing was ate my time for running with multiple simulator for any single changes.

So, That I found a solution for Launch multiple simulator on a single compile in Xcode

It is easy to setup and useful for developers to develop or test a Design changes for various device sizes, pair to pair communications and etc.

Lets step in.

Follow this 4 steps.

Step 1:

Create a new simulator named “Custom Simulators” in the pre-action build script.

In Xcode -> Edit schema (Near run, stop button at top left corner) -> Build -> Pre-actions. Add Run Script by clicking + button on the bottom left.

custom_sim=`xcrun simctl list | grep 'Custom Simulators' | awk -F'[()]' '{print $2}'`
if [ -z "${custom_sim}" ]; then
    xcrun simctl create Custom\ Simulators com.apple.CoreSimulator.SimDeviceType.iPhone-X `xcrun simctl list runtimes | grep iOS | tail -1 | sed -e 's/^.*) - //p' | sort -u`
fi

Copy this script and paste it in script field.

This will creates a simulator named “Custom Simulators” with a device type of iPhone X running on the latest iOS runtime. If you didn’t find this in device drop down list. reopen the Xcode and build your project.

Step 2:

Create a MultiSimConfig.txt file in the root directory of your project. This file specifies list of simulators which you are going to run.

find Simulators identifier open your Terminal and run

instruments -s devices

This will list all available simulators and respective identifiers. They will appear like

iPhone Model (iOS version) [IDENTIFIER] (Simulator)

Here I selecting two simulators

806E56CE-8919-4337-8ABD-2A8277599982
D2900E07-7B3F-4AA9-A874-F4227A001487

Step 3:

Create a script file launch_multiple_simulators.sh file in the root directory of your project. That consumes MultiSimConfig.txt and launch the simulators specified.

xcrun simctl shutdown all # Remove this line if you dont need to launch every time

path=$(find ~/Library/Developer/Xcode/DerivedData/${project_name}-*/Build/Products/Debug-iphonesimulator -name "${app_name}.app" | head -n 1)
echo "${path}"

filename=MultiSimConfig.txt
grep -v '^#' $filename | while read -r line
do
xcrun simctl boot "$line" # Boot the simulator with identifier hold by $line var
xcrun simctl install "$line" "$path" # Install the .app file located at location hold by $path var at booted simulator with identifier hold by $line var
xcrun simctl launch "$line" ${bundle_identifier} # Launch .app using its bundle at simulator with identifier hold by $line var
done

Copy this script and paste it.

In this script replace
${project_name} as your project’s name
${app_name} as your name of the .app
${bundle_identifier} as your project bundle identifier.

The script begins by shutting down any simulators you have opened. Read your MultiSimConfig file and loops each simulator and launches it.

Step 4:

Setup your project to this script on the post build action.

Project’s target -> Build Phases -> New Run Script Phase by clicking + button and choose New Run Script.

custom_sim=`xcrun simctl list | grep 'Custom Simulators' | awk -F'[()]' '{print $2}'`
if [ ! -z "${custom_sim}" ] && [ "${TARGET_DEVICE_IDENTIFIER}" = "${custom_sim}" ]; then
/bin/sh launch_multiple_simulators.sh
fi

This script saves the UUID of your “Custom Simulators” to a custom_Sim variable and executes your launch_multiple_simulators.sh script if the current target device matches your “Custom Simulators” UUID.

Build your project and run your project with the “Custom Simulators”


Check Live demo on below Video and Subscribe my channel on YouTube

– How to make an iOS App
Kathiresan Murugan

Protocol Oriented programming in Swift


Hi Friends,

One of the powerful concept called Protocol Oriented Programming (POP) was introduced in WWDC 2015

Here I have some eg. for understanding POP

Basically we use protocols to implement delegation. But now protocols will split a logics from class, structures and enums.

struct People {
    var fatherName: String

    var name: String

    var age: Int
}

Here I create People structure. Its contains name, age properties.

Declaring Protocol

/// Report protocol
protocol Report {
    
    var fullName: String { get }
    
    func textualDescription()
    
    func myAge() -> Int
}

Here I create a protocol named Report contains variable with get and set (read and write) permission.

functions with return types.

Notes: let is not allowed in protocols.

/// Extending people struct. conforming Report protocol
extension People: Report {
    var fullName: String {
        get {
            return name + " " + fatherName
        }
    }
    
    func textualDescription() {
        print("Father's name: \(fatherName), Name: \(name), Age: \(age)")
    }
    
    func myAge() -> Int {
        age
    }
}

Here I extend people struct with conforming Report protocol. and added protocols stubs.

// Implementation
let people = People(fatherName: "Murugan", name: "Kathiresan", age: 27)
people.fullName 
//Kathiresan Murugan

people.textualDescription() 
//Father's name: Murugan, Name: Kathiresan, Age: 27

people.myAge() 
//27

Protocol Composition

protocol Named {
    var name: String { get }
}
protocol Aged {
    var age: Int { get }
}

Here I created two protocols Named and Aged.

struct Person: Named, Aged {
    var name: String
    var age: Int
}

Person structure conformed with Named and Aged protocols.

Implementation

func wishHappyBirthday(to celebrator: Named & Aged) {
    print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!")
}

let birthdayPerson = Person(name: "Kathiresan", age: 27)
wishHappyBirthday(to: birthdayPerson)
//Happy birthday, Kathiresan, you're 27!

Another eg. with class

class Location {
    var latitude: Double
    var longitude: Double
    init(latitude: Double, longitude: Double) {
        self.latitude = latitude
        self.longitude = longitude
    }
}
class City: Location, Named {
    var name: String
    init(name: String, latitude: Double, longitude: Double) {
        self.name = name
        super.init(latitude: latitude, longitude: longitude)
    }
}

Implementation

func beginConcert(in location: Location & Named) {
    print("Hello, \(location.name)!")
}

let seattle = City(name: "Seattle", latitude: 47.6, longitude: -122.3)
beginConcert(in: seattle)
// Prints "Hello, Seattle!"

 
Try POP in your project and optimise your code.

– How to make an iOS App
Kathiresan Murugan

“Finding Emojis in String😀” using Swift


Hi Friends,

Emoji detection is very Important in Chat application.

After I done chat conversation screen and I saw a WhatsApp application and I find a Emoji dictation That will show little bit larger than text. So, I analyse how they are finding the emoji in string?.

Finally I found the solution for this.

Using CoreText Framework, UnicodeScalar in Foundation

import Foundation
import CoreText

extension UnicodeScalar {
    /// Note: This method is part of Swift 5, so you can omit this.
    /// See: https://developer.apple.com/documentation/swift/unicode/scalar
    var isEmoji: Bool {
        switch value {
        case 0x1F600...0x1F64F, // Emotions
        0x1F300...0x1F5FF, // Misc Symbols and Pictographs
        0x1F680...0x1F6FF, // Transport and Map
        0x1F1E6...0x1F1FF, // Regional country flags
        0x2600...0x26FF, // Misc symbols
        0x2700...0x27BF, // Dingbats
        0xE0020...0xE007F, // Tags
        0xFE00...0xFE0F, // Variation Selectors
        0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
        0x1F018...0x1F270, // Various asian characters
        0x238C...0x2454, // Misc items
        0x20D0...0x20FF: // Combining Diacritical Marks for Symbols
            return true
            
        default: return false
        }
    }
    
    var isZeroWidthJoiner: Bool {
        return value == 8205
    }
}

In String Extension class

extension String {
    
    // Not needed anymore in swift 4.2 and later, using `.count` will give you the correct result
    var glyphCount: Int {
        let richText = NSAttributedString(string: self)
        let line = CTLineCreateWithAttributedString(richText)
        return CTLineGetGlyphCount(line)
    }
    
    var isSingleEmoji: Bool {
        return glyphCount == 1 && containsEmoji
    }
    
    var containsEmoji: Bool {
        return unicodeScalars.contains { $0.isEmoji }
    }
    
    var containsOnlyEmoji: Bool {
        return !isEmpty
            && !unicodeScalars.contains(where: {
                !$0.isEmoji && !$0.isZeroWidthJoiner
            })
    }
    
    // The next tricks are mostly to demonstrate how tricky it can be to determine emoji's
    // If anyone has suggestions how to improve this, please let me know
    var emojiString: String {
        return emojiScalars.map { String($0) }.reduce("", +)
    }
    
    var emojis: [String] {
        var scalars: [[UnicodeScalar]] = []
        var currentScalarSet: [UnicodeScalar] = []
        var previousScalar: UnicodeScalar?
        
        for scalar in emojiScalars {
            if let prev = previousScalar, !prev.isZeroWidthJoiner, !scalar.isZeroWidthJoiner {
                scalars.append(currentScalarSet)
                currentScalarSet = []
            }
            currentScalarSet.append(scalar)
            
            previousScalar = scalar
        }
        
        scalars.append(currentScalarSet)
        
        return scalars.map { $0.map { String($0) }.reduce("", +) }
    }
    
    fileprivate var emojiScalars: [UnicodeScalar] {
        var chars: [UnicodeScalar] = []
        var previous: UnicodeScalar?
        for cur in unicodeScalars {
            if let previous = previous, previous.isZeroWidthJoiner, cur.isEmoji {
                chars.append(previous)
                chars.append(cur)
                
            } else if cur.isEmoji {
                chars.append(cur)
            }
            
            previous = cur
        }
        
        return chars
    }
}

Here I unit test emojis

  func testEmojo() {
        
        XCTAssertTrue("😀".isSingleEmoji)
        XCTAssertTrue("👋🏽🏛".containsOnlyEmoji)
        XCTAssertTrue("Hello 👨‍👩‍👧‍👧".containsEmoji)
        
        XCTAssertFalse("a".isSingleEmoji)
        XCTAssertFalse("🙀1😈".containsOnlyEmoji)
        XCTAssertFalse("Hello world".containsEmoji)
        
        XCTAssertEqual("🙀5🎃".emojis, ["🙀","🎃"])
        XCTAssertEqual("👣1🙏🏽".emojiString, "👣🙏🏽")
        XCTAssertEqual("👨".glyphCount, 1)
        XCTAssertEqual("👨‍👨‍👧🤳".glyphCount, 2)

        XCTAssertEqual("🐽".count, 1)
        XCTAssertEqual("🦊🥛".count, 2)
        
        XCTAssertNotEqual("🛴1🚘".emojis, ["🛴"])
        XCTAssertNotEqual("🚄asdf🚜".emojiString, "🚄asdf🚜")
        XCTAssertNotEqual("🗽US🌂".emojiString, "🗽US")
        XCTAssertNotEqual("🗽US🌂".emojiString, "US🌂")
    }

– How to make an iOS App
ktrkathir

3D Touch – Home screen quick actions dynamically in Swift


Hello Friends,

Here I have implemented a dynamic Home screen Quick action – shortcutItems

Home screen QuickActions

In this tutorial I have created 3 shortcuts to access a TabBarController screens.

  • Dashboard
  • Health
  • Games

UIApplicationShortcutItem contains

  • Type
  • localizedTitle
  • localizedSubtitle
  • icon and UserInfo
let dashboard = UIApplicationShortcutItem(type: "Screen1", localizedTitle: "Dashboard", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "dashboard"), userInfo: nil) // shortcut 1
        
let health = UIApplicationShortcutItem(type: "Screen2", localizedTitle: "Health", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "Health"), userInfo: nil) // shortcut 2
        
let games = UIApplicationShortcutItem(type: "Screen3", localizedTitle: "Games", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "Games"), userInfo: nil)
// shortcut 3
 
UIApplication.shared.shortcutItems = [dashboard, health, games] // Assigning all shortcuts

Handle user tapped shortcut item in AppDelegate.

   func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
        
       if let tabController = window?.rootViewController as? UITabBarController {
            switch shortcutItem.type {
            case "Screen1":
                tabController.selectedIndex = 0
            case "Screen2":
            tabController.selectedIndex = 1
            default:
                tabController.selectedIndex = 2
            }
        }
        completionHandler(true)
    }

– How to make an iOS App
ktrkathir

UIColor+Hexcode in iOS


Hi Friends,

I have updated this post to Swift 5.1. This method is used to get  color from Hex.

Swift 5.1

import Foundation
import UIKit

extension UIColor {
    
    /// Hex color
    /// - Parameter hex: hex code
   public class func hexColor (hex:String) -> UIColor {
        var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        
        if (cString.hasPrefix("#")) {
            cString.remove(at: cString.startIndex)
        }
        
        if ((cString.count) != 6) {
            return UIColor.gray
        }
        
        var rgbValue:UInt64 = 0
        Scanner(string: cString).scanHexInt64(&rgbValue)
        
        return UIColor(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
            alpha: CGFloat(1.0)
        )
    }
}


In Objctive-C

Download a Category file here

Import the Category File UIColor+HexaCode.h and .m file in to your Project.
and implement this one line code.

colorLbl.backgroundColor = [UIColor colorWithHexString:"F0F0F0"];

– How to make an iOS App
ktrkathir