iOS Revisited: Xcode

Hot

Post Top Ad

Showing posts with label Xcode. Show all posts
Showing posts with label Xcode. Show all posts

13 Nov 2017

Limit characters in TextField or TextView Swift

11/13/2017 08:33:00 am 0
In this article we will learn how to set maximum character length to a UITextField and UITextView.

We go through each one separately.

UITextField:

First add UITextField to the view and conform to UITextFieldDelegate.

Next add the following delegate method for setting up the maximum limit:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let currentText = textField.text ?? ""
    guard let stringRange = Range(range, in: currentText) else { return false }
    let updatedText = currentText.replacingCharacters(in: stringRange, with: string)
    return updatedText.count <= 10 // Change limit based on your requirement.
} 

Above example is for, if user asked to enter his/her mobile number, assume maximum length as 10.

Download the sample project from the bottom of this article.

UITextView:

Add UITextView to the view and conform to UITextViewDelegate.

Next add the following delegate method for setting the maximum limit:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    let currentText = textView.text ?? ""
    guard let stringRange = Range(range, in: currentText) else { return false }
    let updatedText = currentText.replacingCharacters(in: stringRange, with: text)
    return updatedText.count <= 50 // Change limit based on your requirement.
}

Above example is for, if user asked to enter about his/her, assume maximum limit here 50 characters.

Download sample project with example :

Read More

28 Oct 2017

Argument of '#selector' refers to instance method that is not exposed to Objective-C | Add '@objc' to expose this instance method to Objective-C

10/28/2017 08:29:00 am 1
After installing Xcode 9 and migrating to Swift 4 from Swift 3 , @objc inference warning comes like below:

The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings, test your code with “Use of deprecated Swift 3 @objc inference” logging enabled, and then disable inference by changing the “Swift 3 @objc Inference” build setting to “Default” for the “AppName” target.


If you introduce new methods or variables to a Swift class, marking them as @objc exposes them to the Objective-C run time. This is necessary when you have Objective-C code that uses your Swift class, or, if you are using Objective-C-type features like Selectors.

Fix compiler Errors:

We can fix this @objc inference warning by using two ways.

Solution 1:

One is to use @objc on each function or variable that needs to be exposed to the Objective-C run time as follow:

@objc func getSomeData() {

}

This is the best way for converting your code so that compiler doesn't complain.

Solution 2:

Second one is to add @objcMembers by a Class declaration as follow:

@objcMembers
class Photo {

}

This will automatically add @objc to ALL the functions and variables in the class.

This is a easy way but it increases the application size by exposing functions that did not need to be exposed.

Official Documentation

Read More

5 Aug 2017

Face Detection using Vision Framework - Swift, iOS11

8/05/2017 03:36:00 am 1

Face Detection using Vision Framework - Swift, iOS11


In iOS 11 Apple provide frameworks for specific areas. We will dive into Vision API. Using Vision framework tools we can process image or video to detect and recognize face, detect barcode, detect text, detect and track object, etc.

For detecting objects using Machine Learning Image Analysis follow this link - Real Time Camera Object Detection with Machine Learning - CoreML: Swift 4

In this article, we will bash out face detection. In vision API there are three roles.

Getting Started:

1. Request :

     Ex: VNDetectFaceRectanglesRequest to detect face in an image.

2. Request handler :

    Ex: VNImageRequestHandler, VNSequenceRequestHandler. VNImageRequestHandler for single image and VNSequenceRequestHandler is for a sequence of multiple images.

3. Observation :

     Provide informations like bounding box.


First create a new project -> open Xcode -> File -> New -> Project -> Single View App, then tap next button. Type product name as 'Face Recognization' then tap next and select the folder to save project.

Before start, download one sample image with faces and add to Assests.xcassets and name it as 'sample1'.

Now it's time to start writing a code. Open ViewController.swift add this line in viewDidLoad() method. 


 guard let image = UIImage(named: "sample1") else {
    return
}

Here image is an UIImage object used to detect faces. Then for displaying image add UIImageView as subview. Add the following code in viewDidLoad() method after else part.

 /........

let scaledHeight = view.frame.width / image.size.width * image.size.height
let imageView = UIImageView(image: image)
imageView.frame = CGRect(x: 0, y: 20, width: view.frame.width, height: scaledHeight)
view.addSubview(imageView)
Here scaledHeight is the imageView height calculated from ratio of device width and image size.

Now Build and Run , You will see image with aspect size based on device size.




We start with Vision API to detect face rectangles. For that we need to import vision add below 'import UIKit'.

 import Vision

As we mentioned earlier we are using three roles in this face detection. First we are going to create request using VNDetectFaceRectanglesRequest. Second step is to use request handler in this we are analyzing single image so we will use VNImageRequestHandler. This is an asynchronous so it's better to put VNImageRequestHandler in background thread. Third one Observations, we will use inside request completion handler. Let implement everything using code. Add the following code to the end  of viewDidLoad() method.

 /........

let request = VNDetectFaceRectanglesRequest { (req, error) in
    if let error = error  {
        print("Failed to detect faces",error)
        return
    }
    print(req.results)
}

guard let cgImage = image.cgImage else {
    return
}

DispatchQueue.global(qos: .background).async {
    let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
    
    do {
        try handler.perform([request])
    } catch let reqError {
        print("Error in req",reqError)
    }
}

Execution starts from VNDetectFaceRectanglesRequest after that it will not call completion handler. Then the flow goes to cgImage -> handler then we will perform request on handler. If the request succeded then it calls VNDetectFaceRectanglesRequest completion handler. It will analyze image and give results as array of VNFaceObservation.

Now Build and Run , Great You will see VNFaceObservation object in console.


Finally, we are getting rectangle. Parse VNFaceObservation to draw rectangles on detected faces in an image. For that copy the following lines of code and replace the line

'print(req.results)'.

guard let observations = req.results as? [VNFaceObservation]
    else { fatalError("unexpected result type") }



observations.forEach({ (observation) in
    DispatchQueue.main.async {
        print(observation.boundingBox)
        let x = self.view.frame.width * observation.boundingBox.origin.x
        let width = self.view.frame.width * observation.boundingBox.size.width
        let height = scaledHeight * observation.boundingBox.size.height
        let y = scaledHeight * (1 - observation.boundingBox.origin.y) - height
        let redSquare = UIView()
        redSquare.backgroundColor = UIColor.clear
        redSquare.layer.borderColor = UIColor.red.cgColor
        redSquare.layer.borderWidth = 2.0
        redSquare.frame = CGRect(x: x, y: y, width: width, height: height)
        self.view.addSubview(redSquare)
    }
})
Now Build and Run , Great detected faces in an image with red borders.


Download sample project with examples :

Read More

3 Aug 2017

11 Reasons Why Not to Use Storyboards and Interface Builder || Why I stopped using storyboards and Interface Builder

8/03/2017 04:54:00 am 1



Actually, up until a few months ago, I could not imagine creating a project without my beloved storyboard. I had looked a little into laying out constraints in code, and the syntax alone had scared the hell out of me. And yet, a couple of weeks after letting go of the storyboard, I couldn’t imagine myself ever using one again. 

So here are top 11 reasons why not using storyboards:

Reason 1 : Merge conflicts will drive you crazy. If you are working to team its better to avoid storyboards.

Reason 2 : Teaching beginner iOS programmers what is exactly going on is difficult with storyboards. Because we need to use drag and drop for outlets it's really pain.
 
Reason 3 : Difficult to record and explain things on storyboard because switching between stotyboards and View Controllers will take time.


Reason 4 : Screen size on laptop too small for storyboards. So we need a big external display.

Reason 5 : Productivity decrease when hands leave the keyboard.



Reason 6 : Refactoring all fonts in Storyboard components take too long.


Reason 7 : Compile time for complicated storyboards increases if you are building a big project.


Reason 8 : Cell Identifiers and Storyboard Id strings are unsafe it may leads to crash.


Reason 9 : IBOutlet & IBAction crashes when refactoring so we need to be carefull while refactoring.
 

Reason 10 : Difficulty in laying out views that are stacked. If there are so many subviews under , its difficult to give layouts.

Reason 11 : They complicate code reusability. In code, if you have 11 screens that look almost the same, it’s so easy to use a protocol to efficiently reuse your UI code between them. With a storyboard, good luck figuring out how to share outlets and actions!


For more updates follow us.

 

Read More

2 Aug 2017

Creating Youtube Home Feed using UITableView - Swift

8/02/2017 06:43:00 am 0



First create a new project -> open Xcode -> File -> New -> Project -> Single View Application, then tap next button. Type product name as Youtube HomeFeed then tap next and select the folder to save project.

https://www.spandidos-publications.com/article_images/or/31/2/OR-31-02-0701-g00.jpg 


Open Main.Storyboard, Drag TableView on to the ViewController and give Autolayouts as mentioned in the following picture. Make sure to uncheck the 'Constraints to margins'. 



Then drag TableViewCell on to the TableView. Change cell row height to 250 in size inspector. Add ImageView to cell and add constraints as below image.


Add Label to cell and give horizontal spacing to imageView , trailing to container margin, and top to imageView. Change label text alignment to left and text color to dark gray.




Add one more imageView to cell and give leading , trailing, top to container margins and bottom space to thumbnail ImageView.
Create new swift file by tapping File -> New -> File -> Swift file and name it as 'CustomTableViewCell'. Remove all lines of code and add the following code.
import Foundation
import UIKit

class CustomTableViewCell: UITableViewCell {
    
    @IBOutlet weak var contentImageView: UIImageView!
    
    @IBOutlet weak var channelThumbnailView: UIImageView!
    
    @IBOutlet weak var titleLabel: UILabel!

}
Open Main.Storyboard, select TableViewCell from hierarchy of views then change class to 'CustomTableViewCell'.




Then open connection inspector and give the links to TableViewCell subviews.


Open ViewController.Swift and this line before viewDidLoad() method and give link in storyboard. Tap tableview and give links to delegate and datasource.

@IBOutlet weak var tableView: UITableView!

Great upto now evrthing is ok. UI part preety much done. The main thing is getting data. For getting data we are going to create model. So again create new class by tapping File -> New -> File -> Swift file and name it as 'DataModel'. Add the follwing code.
class DataModel {
    
    var originalImageName : String?
    var thumbnailImageName : String?
    var title : String?
    
    
    init(originalImage: String, thumbnailImage: String, titleStr: String ) {
        originalImageName = originalImage
        thumbnailImageName = thumbnailImage
        title = titleStr
    }
}
Open ViewController.Swift and add dataArray property before viewDidLoad() method. 

var dataArray = [DataModel]()
Inside viewdidLoad() add these lines of code for getting model.

let dataModel1 = DataModel.init(originalImage: "Image-1", thumbnailImage: "Thumbnail Image -1", titleStr: "The Avengers")
let dataModel2 = DataModel.init(originalImage: "Image-2", thumbnailImage: "Thumbnail Image -2", titleStr: "Iron Man 3")
let dataModel3 = DataModel.init(originalImage: "Image-3", thumbnailImage: "Thumbnail Image -3", titleStr: "Thor")
let dataModel4 = DataModel.init(originalImage: "Image-4", thumbnailImage: "Thumbnail Image -4", titleStr: "The Incredible Hulk")
let dataModel5 = DataModel.init(originalImage: "Image-5", thumbnailImage: "Thumbnail Image -5", titleStr: "Spider Man 3")
        
dataArray = [dataModel1 ,dataModel2, dataModel3, dataModel4, dataModel5]

Now it's time to add Tableview Delegate and DataSource methods at the bottom of ViewController.Swift class.
extension ViewController : UITableViewDelegate,UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1;
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArray.count;
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = CustomTableViewCell()
        return cell
    }
}
Replace cellForRowAt method with the follwing code

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
         let data = dataArray[indexPath.row]
        cell.contentImageView.image = UIImage(named: data.originalImageName!)
        cell.contentImageView.contentMode = .scaleAspectFill
        cell.contentImageView.clipsToBounds = true
        cell.channelThumbnailView.image = UIImage(named: data.thumbnailImageName!)
        cell.channelThumbnailView.contentMode = .scaleAspectFill
        cell.channelThumbnailView.clipsToBounds = true
        cell.channelThumbnailView.layer.cornerRadius = 25
        cell.titleLabel.text = data.title!
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 300
    }


Build and run the app, you will see our super heros on our devices.

Download sample project with examples :

Read More

1 Aug 2017

Real Time Camera Object Detection with Machine Learning - CoreML: Swift 4

8/01/2017 04:05:00 am 1
This iOS machine learning tutorial will introduce you to Core ML and Vision, two brand-new frameworks introduced in iOS 11. For this we need Xcode 9 or greater, iOS 11 or greater.


Getting Started:

First create a new project -> open Xcode -> File -> New -> Project -> Single View Application, then tap next button. Type product name as 'Object Detector' then tap next and select the folder to save project.

For detecting objects we need to access device camera. Open ViewController.swift and import this framework, just below 'import UIKit'.

import AVKit
Now its time to write some code, open ViewController.swift and inside viewDidLoad() method write the following code to access camera.

 let captureSession = AVCaptureSession()
 captureSession.sessionPreset = .photo
 guard let captureDevice = AVCaptureDevice.default(for: .video) else {
      return
 }
 guard let input = try? AVCaptureDeviceInput(device: captureDevice) else {
      return
 }
 captureSession.addInput(input)
 captureSession.startRunning()
Build and run, Ouchh app crashes. No worries we need to add cameraUsageDescription in info.plist. Open info.plist add 'Privacy - Camera Usage Description' and description as 'We need to access camera for detecting objects'.

 
Now build and run. Great we see camera permission alert then tap ok.



We need to add camera to the view for that create 'PreviewLayer' as the following. Add these lines of code after 'captureSession.startRunning()' line in viewDidLoad().

let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
view.layer.addSublayer(previewLayer)
previewLayer.frame = view.frame
Build and run , now you can see camera running on your device.

Great, now for detecting object we need image containg object for that we need to get frames from the camera. So use the following code at the end of viewDidLoad().

let dataOutput = AVCaptureVideoDataOutput()
dataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
captureSession.addOutput(dataOutput)
Add 'AVCaptureVideoDataOutputSampleBufferDelegate' delgate to the ViewController.swift class.

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
.....
}
 Add delegate method, it will call every time when camera is going to capture a frame.

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

}
Now it's time to start using 'Machine Learning'. Open ViewController.swift and import this framework, just below 'import AVKit'.

import Vision
Go to this url 'https://developer.apple.com/machine-learning/' and download Resnet50 file. Drag that ML file to our project.

Add the following code inside delegate method.

guard let pixelBuffer : CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return }

guard let model = try? VNCoreMLModel(for: Resnet50().model) else {
return }
let request = VNCoreMLRequest(model: model) { (finishedReq, error) in
print("results ==",finishedReq.results)
}

try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])
VNImageRequestHandler will perform all operation on image using VNCoreMLRequest.

VNCoreMLRequest accepts a VNCoreMLModel, here our model is Resnet50 model.

Build and Run, you will see the output in console with VNClassificationObservation objects.



Great we are getting some data. Lets parse the data using following code.
Replace 'print("results ==",finishedReq.results)' with the code below.


guard let results = finishedReq.results as? [VNClassificationObservation] else {
return
}

guard let firstObservation = results.first else {
return
}

print(firstObservation.identifier, firstObservation.confidence)
Build and Run the project we will see detected objects with confidence in console.



Download sample project with examples :

Read More

15 Apr 2016

Cocoapods 'pod install' not working after updating to OS X EI Capitan - iOS

4/15/2016 12:05:00 am 0

Cocoapods  'pod install'  not working after updating to OS X EI Capitan - iOS


Its a common issue after updating mac operating system to OS X EI Capitan but easy to solve this issue. Simply copy the below command and paste in your terminal.

sudo gem install -n /usr/local/bin cocoapods
It worked fine for me.
Detailed explanation for more clarification:

These instructions were tested on all betas and the final release of El Capitan.

Custom Gem_Home:

This is the solution when you are receiving the "Operation not permitted" error.

$ mkdir -p $HOME/Software/ruby
$ export GEM_HOME=$HOME/Software/ruby
$ gem install cocoapods
[...]
1 gem installed
$ export PATH=$PATH:$HOME/Software/ruby/bin
$ pod --version
0.37.2

  Standard system installation:

For whatever reason, the rootless stuff seems less restrictive when one simply upgrades the system. I could sudo gem install cocoapods just fine on a machine upgraded from 10.10 - however, binstubs are no longer installed into /usr/bin:
$ sudo gem install cocoapods
[...]
1 gem installed
$ export PATH=$PATH:/Library/Ruby/bin
$ pod --version
0.37.2
We have heard from some users that they receive this error when doing a system-wide installation:
ERROR: While executing gem ... (Errno::EPERM)
Operation not permitted - /usr/bin/pod

We aren't sure why gem behaves differently on some systems, but this can be solved by passing -n /usr/local/bin to the install command, so that the pod executable gets installed there.
Thanks for reading.....
Read More

Post Top Ad