iOS

Navigation from and to views

struct ContentView: View {
    @State private var selection: Int? = 0

    var body: some View {
        NavigationView {
            VStack {
                if selection == 0 {
                    FirstView(selection: $selection)
                } else if selection == 1 {
                    SecondView(selection: $selection)
                } else if selection == 2 {
                    ThirdView(selection: $selection)
                }
            }
        }
    }
}

struct FirstView: View {
    @Binding var selection: Int?

    var body: some View {
        Button("Go to Second View") {
            selection = 1
        }
    }
}

struct SecondView: View {
    @Binding var selection: Int?

    var body: some View {
        Button("Go to Third View") {
            selection = 2
        }
    }
}

struct ThirdView: View {
    @Binding var selection: Int?

    var body: some View {
        Button("Go to First View") {
            selection = 0
        }
    }
}



#Preview {
    ContentView()
}

Dynamic UIFont

example by demo

UIFont

.largeTitle, .title1, .title2, .title3, .headline, .subheadline, .body, .footnote, .caption1, .caption2, .callout

Large (Default)

| Style | Weight | Size (points)
| ---------- | :------: | --------------: |
Large Title | Regular | 34
Title 1 | Regular | 28
Title 2 | Regular | 22
Title 3 | Regular | 20
Headline | Semi-Bold | 17
Body |Regular | 17
Callout | Regular | 16
Subhead | Regular |15
Footnote | Regular | 13
Caption 1 | Regular | 12
Caption 2 | Regular | 11

let label = UILabel()
label.font = UIFont.preferredFont(forTextStyle: .body)
label.adjustsFontForContentSizeCategory = true 

apple doc
article with examples

Tags: 

Duplicate Symbols for Architecture arm64

Duplicate Symbols for Architecture arm64

remedy in build settings

set to ON
No Common Blocks
.. and then OFF

Tags: 

Sequential Operations

class DownloadOperation : Operation {
   
    private var task : URLSessionDownloadTask!
   
    enum OperationState : Int {
        case ready
        case executing
        case finished
    }
   
    // default state is ready (when the operation is created)
    private var state : OperationState = .ready {
        willSet {
            self.willChangeValue(forKey: "isExecuting")
            self.willChangeValue(forKey: "isFinished")
        }
       
        didSet {
            self.didChangeValue(forKey: "isExecuting")
            self.didChangeValue(forKey: "isFinished")
        }
    }
   
    override var isReady: Bool { return state == .ready }
    override var isExecuting: Bool { return state == .executing }
    override var isFinished: Bool { return state == .finished }
   
    init(session: URLSession, downloadTaskURL: URL, completionHandler: ((URL?, URLResponse?, Error?) -> Void)?) {
        super.init()
       
        task = session.downloadTask(with: downloadTaskURL, completionHandler: { [weak self] (localURL, response, error) in
           
            /*
             if there is a custom completionHandler defined,
             pass the result gotten in downloadTask's completionHandler to the
             custom completionHandler
             */
            if let completionHandler = completionHandler {
                // localURL is the temporary URL the downloaded file is located
                completionHandler(localURL, response, error)
            }
           
            /*
             set the operation state to finished once
             the download task is completed or have error
             */
            self?.state = .finished
        })
    }
   
    override func start() {
        /*
         if the operation or queue got cancelled even
         before the operation has started, set the
         operation state to finished and return
         */
        if(self.isCancelled) {
            state = .finished
            return
        }
       
        // set the state to executing
        state = .executing
       
        print("downloading \(self.task.originalRequest?.url?.absoluteString ?? "")")
           
            // start the downloading
            self.task.resume()
    }
   
    override func cancel() {
        super.cancel()
       
        // cancel the downloading
        self.task.cancel()
    }
}

use it in vc:
class ViewController: UIViewController {

    @IBOutlet weak var downloadButton: UIButton!
   
    @IBOutlet weak var progressLabel: UILabel!
   
    @IBOutlet weak var cancelButton: UIButton!
   
    var session : URLSession!
    var queue : OperationQueue!
   
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
       
        session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: nil)
        queue = OperationQueue()
        queue.maxConcurrentOperationCount = 1
       
        self.cancelButton.isEnabled = false
    }

    @IBAction func downloadTapped(_ sender: UIButton) {
        let completionOperation = BlockOperation {
            print("finished download all")
            DispatchQueue.main.async {
                self.cancelButton.isEnabled = false
            }
        }
       
        let urls = [
            URL(string: "https:/...zip")!,
            URL(string: "https:/...zip")!,
            URL(string: "https:/...zip")!,
            URL(string: "https:/...zip")!,
            URL(string: "https:/...zip")!,
        ]
       
        for (index, url) in urls.enumerated() {
            let operation = DownloadOperation(session: self.session, downloadTaskURL: url, completionHandler: { (localURL, urlResponse, error) in
               
                if error == nil {
                    DispatchQueue.main.async {
                        self.progressLabel.text = "\(index + 1) / \(urls.count) files downloaded"
                    }
                }
            })
           
            completionOperation.addDependency(operation)
            self.queue.addOperation(operation)
        }
       
        self.queue.addOperation(completionOperation)
        self.cancelButton.isEnabled = true
    }
   
    @IBAction func cancelTapped(_ sender: UIButton) {
        queue.cancelAllOperations()
       
        self.progressLabel.text = "Download cancelled"
       
        self.cancelButton.isEnabled = false
    }
   
}

Tags: 

tableview

//
//  TableViewController.swift
//  SwipeActions
//
//  An exercise file for iOS Development Tips Weekly
//  by Steven Lipton (C)2018, All rights reserved
//  For videos go to http://bit.ly/TipsLinkedInLearning
//  For code go to http://bit.ly/AppPieGithub
//

import UIKit

class TableViewController: UITableViewController {

    let rowCount = 12
   
    override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let greenAction = UIContextualAction(style: .normal, title: "Green") { (action, view, actionPerformed) in
            self.setCell(color: .green, at: indexPath)
        }
        greenAction.backgroundColor = .green
       
        let blueAction = UIContextualAction(style: .normal, title: "Blue") { (action, view, actionPerformed) in
            self.setCell(color: .blue, at: indexPath)
        }
        blueAction.backgroundColor = .blue
       
        return UISwipeActionsConfiguration(actions: [greenAction,blueAction])
    }
   
    override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let greenAction = UIContextualAction(style: .normal, title: "Green") { (action, view, actionPerformed) in
            self.setCell(color: .green, at: indexPath)
        }
        greenAction.backgroundColor = .green
       
        let blueAction = UIContextualAction(style: .normal, title: "Blue") { (action, view, actionPerformed) in
            self.setCell(color: .blue, at: indexPath)
        }
        blueAction.backgroundColor = .blue
       
        return UISwipeActionsConfiguration(actions: [blueAction,greenAction])
    }
   
    //A simple example of what you can do in the cell
    func setCell(color:UIColor, at indexPath: IndexPath){
       
        // I can change external things
        self.view.backgroundColor = color
        // Or more likely change something related to this cell specifically.
        let cell = tableView.cellForRow(at: indexPath )
        cell?.backgroundColor = color
    }
   
   
    //Your standard Table Delegate and Data Source methods
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rowCount
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = String(format:"Row #%i",indexPath.row + 1)
        cell.textLabel?.font = UIFont(name: "GillSans-Bold", size: 26)
        return cell
    }
   
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Sample Action Table"
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

xcrun simctl

xcrun simctl list
xcrun simctl boot UUID
xcrun simctl list | grep Booted
xcrun simctl delete unavailable

Long method

func async(_ runner: @escaping @autoclosure () ->())
{
    DispatchQueue.global(qos: .default).async {
        runner()
    }
}

func longMethod() {
    for _ in 1...2 {
        sleep(5)
    }
    print("run like a boss")
}
async(longMethod())

Tags: 

Readfile Rxswift

let disposebag = DisposeBag()
 
  enum FileReadError: Error {
    case fileNotFound, unreadable, encodingFailed
  }
 
  func loadText(from filename: String) -> Single<String> {
    return Single.create {
      single in
      let disposable = Disposables.create()
     
      guard let path = Bundle.main.path(forResource: filename, ofType: "txt") else {
        single(.error(FileReadError.fileNotFound))
        return disposable
      }
      guard let data =  FileManager.default.contents(atPath: path) else {
        single(.error(FileReadError.unreadable))
        return disposable
      }
      guard let contents = String(data: data, encoding: .utf8) else {
        single(.error(FileReadError.encodingFailed))
        return disposable
      }
      single(.success(contents))
     
      return disposable
    }
  }
  loadText(from: "filename")
    .subscribe{
      switch $0 {
      case .success(let string):
        print(string)
      case .error(let descript):
        print(descript)
     
      }
  }
    .disposed(by: disposebag)

Tags: 

Dispatch async

DispatchQueue.global(qos: .background).async {
    // Background Thread
    DispatchQueue.main.async {
        // Run UI Updates or call completion block
    }
}

Main and Background Queues

let main = DispatchQueue.main
let background = DispatchQueue.global()
let helper = DispatchQueue(label: "another_thread")
Working with async and sync threads!

background.async { //async tasks here }
background.sync { //sync tasks here }

Tags: 

NSAttributedString

One liner swift 4:

label.attributedText = NSAttributedString(string: "Text", attributes:
    [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue])

Tags: 

App installed

func isAppInstalled(name:String)->Bool {
    return UIApplication.sharedApplication().canOpenURL(NSURL(string:"\(name):")!)
}

Tags: 
Subscribe to RSS - iOS