• Skip to main content
  • Skip to primary sidebar

Ravi Shankar

Tweaking Apps

  • Swift
  • Tech Tips

Xcode

How to record and play sound in Swift

April 12, 2015 By Ravi Shankar 10 Comments

In this tutorial, we are going to see the required steps to record and play sound in Swift Programming language using AVAudioRecorder and AVAudioPlayer

Download source code from github (SoundController.swift)

User Interface

The user interface for this demo is simple with two buttons, one for recording and another for playing sound.

201504121626.jpg

Create corresponding IBAction and IBOutlets from the two button in the View Controller.

@IBOutlet weak var recordButton: UIButton!

@IBOutlet weak var playButton: UIButton!

@IBAction func recordSound(sender: UIButton)

@IBAction func playSound(sender: UIButton)

Dual Purpose Buttons

The Record button will be used to record and stop recording. Similarly the Play button will used to Play and Stop the audio.

Class level var and let declaration

  var soundRecorder: AVAudioRecorder!

var soundPlayer:AVAudioPlayer!

  

let fileName = “demo.caf”

Declare two class level variable for holding an instance of AVAudioRecorder and AvAudioPlayer. Also create constant for holding the file name.

Create Sound file path

For this demo, the sound file will be created under the Cache directory using the name defined in the constant. Add these two function to your class

  func getCacheDirectory() -> String {

  

let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory,.UserDomainMask, true) as [String]

  

return paths[0]

}

  

func getFileURL() -> NSURL {

  

let path = getCacheDirectory().stringByAppendingPathComponent(fileName)

let filePath = NSURL(fileURLWithPath: path)

  

return filePath!

}

The getCacheDirectory retrieves the caches directory and getFileURL appends the file name with the cache directory.

Setup Recorder

Create a new function that prepares the recorder and this function will be called during the viewDidLoad operation

func setupRecorder() {

  

//set the settings for recorder

  

var recordSettings = [

AVFormatIDKey: kAudioFormatAppleLossless,

AVEncoderAudioQualityKey : AVAudioQuality.Max.rawValue,

AVEncoderBitRateKey : 320000,

AVNumberOfChannelsKey: 2,

AVSampleRateKey : 44100.0

]

  

var error: NSError?

  

soundRecorder = AVAudioRecorder(URL: getFileURL(), settings: recordSettings, error: &error)

  

if let err = error {

println(“AVAudioRecorder error: \(err.localizedDescription)“)

} else {

soundRecorder.delegate = self

soundRecorder.prepareToRecord()

}

}

To create an AVAudioRecorder instance, you need to pass three parameters,

URL– Specifies the path and name of the file where the sound will be recorded.

settings – Configure AVRecorder settings

error – Capture error while creating AVRecorder instance.

If there is no error while creating Audio Recorder, the delegate it set to the View Controller and recorder is prepared for recording. Make sure the View Controller conforms to AVAudioRecorderDelegate

class SoundController: UIViewController, AVAudioRecorderDelegate {

Prepare Player

Add the following function that prepares the AVAudiPlayer to play the recorded sound

func preparePlayer() {

var error: NSError?

  

soundPlayer = AVAudioPlayer(contentsOfURL: getFileURL(), error: &error)

  

if let err = error {

println(“AVAudioPlayer error: \(err.localizedDescription)“)

} else {

soundPlayer.delegate = self

soundPlayer.prepareToPlay()

soundPlayer.volume = 1.0

}

}

AVAudioPlayer instance is created by passing sound file that needs to be played along with pointer to capture errors while creating AVAudioPlayer instance. Make sure the View Controller conforms to AVAudioPlayerDelegate. Then call the prepareToPlay function on the AVAudioPlayer instance.

Implement IBActions function to record and play sound

Add the following implementation to the IBAction functions which records and plays sound.

@IBAction func recordSound(sender: UIButton) {

if (sender.titleLabel?.text == “Record”){

soundRecorder.record()

sender.setTitle(“Stop”, forState: .Normal)

playButton.enabled = false

} else {

soundRecorder.stop()

sender.setTitle(“Record”, forState: .Normal)

}

}

  

@IBAction func playSound(sender: UIButton) {

if (sender.titleLabel?.text == “Play”){

recordButton.enabled = false

sender.setTitle(“Stop”, forState: .Normal)

preparePlayer()

soundPlayer.play()

} else {

soundPlayer.stop()

sender.setTitle(“Play”, forState: .Normal)

}

}

When the Record button is tapped, the name of the button is changed to Stop and starts recording the sound. Similarly when the title is Stop, the recording the stopped and play button is enabled. The same is done when the user taps the play button.

class SoundController: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate {

Implement AVAudioRecorderDelegate methods

  func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {

playButton.enabled = true

recordButton.setTitle(“Record”, forState: .Normal)

}

  

func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {

println(“Error while recording audio \(error.localizedDescription)“)

}

Implement AVAudioPlayerDelegate methods

  func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {

recordButton.enabled = true

playButton.setTitle(“Play”, forState: .Normal)

}

  

func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {

println(“Error while playing audio \(error.localizedDescription)“)

}

Now you are good to go and try this demo. You can download the source code for recording and playing audio in swift from github.

Filed Under: Develop, ios, Programming, Xcode Tagged With: AvAudioPlayer, AVAudioRecorder, Xcode

UITextFieldDelegate in Swift

April 7, 2015 By Ravi Shankar Leave a Comment

This is a beginners tutorial on UITextFieldDelegate in Swift. We are going to see how to use UITextFieldDelegate by writing a Simple Interest Calculator.

201504071303.jpg

Download the source code from here

This calculator uses UILabels and TextFields for displaying and accepting amount and interest. We are going to use the UITextFieldDelegate method to navigate from “Principal Amount” to “Rate of Interest”. And when the user taps done on “Rate of Interest” UITextField, the interest is calculated and displayed on the corresponding label.

Source Code

import UIKit

class TextFieldDemoController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var amountTextField: UITextField!

  

@IBOutlet weak var rateTextField: UITextField!

  

@IBOutlet weak var interestLabel: UILabel!

  

var textFields:[UITextField] = []

  

override func viewDidLoad() {

super.viewDidLoad()

  

self.amountTextField.delegate = self

self.rateTextField.delegate = self

  

textFields = [amountTextField, rateTextField]

  

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

// Dispose of any resources that can be recreated.

}

  

//MARK :- TextField Delegate

  

func textFieldShouldReturn(textField: UITextField) -> Bool {

  

var currentTextField = textFields[0]

  

if (currentTextField == textField) {

currentTextField = textFields[1]

currentTextField.becomeFirstResponder()

} else {

currentTextField.resignFirstResponder()

interestLabel.text = “\(calculateInterest())“

}

  

return true

}

  

//MARK :- Calculation

  

func calculateInterest() -> Double {

let amount: Double = (amountTextField.text as NSString).doubleValue

let rate:Double = (rateTextField.text as NSString).doubleValue

  

return amount * rate

}

}

Step 1: Make sure your view controller class conforms to UITextFieldDelegate

Step 2: In ViewDidLoad method, set the delegate for the textfields to self (ViewController)
Step 3: Implement textFieldShouldReturn(textField: UITextField) -> Bool(UITextFieldDelegate method) and the code that makes the UITextField FirstResponder and calculates the Interest once the values are entered.
Download the source code from here

Filed Under: Apple, Develop, ios, Programming, Xcode Tagged With: Apple, textFieldShouldReturn, UITextFieldDelegate, Xcode

SplitViewController example in Swift

April 1, 2015 By Ravi Shankar 4 Comments

This is a beginners tutorial on SplitViewController using Interface builder with programming language as Swift. There are also some good articles available on SplitViewController, check them out as well – nhipster and whoisryannystrom.

Create a new Single View Application.

201503290525.jpg

Choose Language option as Swift and provide a product name.

201504011302.jpg

Navigate to Main.Storyboard and select default View Controller and delete it.

201504011304.jpg

Add a Split View Controller from the object library to the interface builder.

201504011305.jpg

Using Attributes Inspector make Split View Controller as the Initial View Controller

201504011307.jpg
Select View Controller in the Interface builder then click Editor menu and select Navigation Controller under Embed In menu option.

201504011308.jpg

Rename ViewController.swift to DetailViewController.swift and change the class name as well.

201504011317.jpg

Navigate to Interface builder and set the class name for ViewController scene to DetailViewController

201504011321.jpg

Now Control + drag and drop TablevIew Prototype cell to NavigationController (DetailViewController) and select segue as show detail. Also set the identifier for the Storyboard Segue as “ShowDetailIdentifier“

201504011323.jpg

201504011326.jpg

Navigate to RootViewController (TableViewController) Provide the Identifier as CellIdentifier for the Prototype Cells.

201504011325.jpg

Right click on the Project Navigator, select New File and Choose the template as Cocoa Touch Class

201504011331.jpg

In the next screen, select subclass as UIViewController and provide a name as SplitViewController

201504011332.jpg

After creating the file, edit SplitViewController subclass to UISplitViewController. Then add the following line to the viewDidLoad method.

  splitViewController?.preferredDisplayMode = .PrimaryOverlay

The above line is to keep the PrimaryViewController (TableViewController) on top of SecondaryViewController (DetailViewController). You can change this behaviour by setting other types, check the documentation for more details.

201504011407.jpg

Now add the PrimaryViewController (TableViewController) by right clicking and selecting New File. Select Cocoa Touch class and in the subclass field pick UITableViewController. Provide the the name for the TableViewController ListTableViewController.

201504011409.jpg

Set the class name for the RootViewController (TableViewController) to the newly created class, ListTableViewController.

201504011424.jpg

Navigate to DetailViewController in the Interface builder, add a label and make it horizontally and vertically centred.

201504011524.jpg

Then add a new IBOutlet in DetailViewController and connect the Outlet to the label in interface builder.

  @IBOutlet var numberLabel:UILabel?

Also add property of type Int and the value for this property will be set during the segue transition.

var selectedIndex:Int = 1

Make changes to the viewDidLoad method, to set the value for the label and to add back button to the navigation bar.

override func viewDidLoad() {

super.viewDidLoad()

  

numberLabel?.text = “\(selectedIndex)“

  

// add back button to the navigation bar.

  

if splitViewController?.respondsToSelector(“displayModeButtonItem”) == true {

navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem()

navigationItem.leftItemsSupplementBackButton = true

}

}

In the ListTableViewController, add the following code that sets the datasource.

  let names = [“One”,“Two”,“Three”,“Four”,“Five”,“Six”,“Seven”,“Eight”,“Nine”,“Ten”] (class level declaration)

  // MARK: – Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

return 1

}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return names.count

}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier(“CellIdentifier”, forIndexPath: indexPath) as UITableViewCell

   cell.textLabel?.text = names[indexPath.row]

return cell

}

Then make changes to the prepareForSegue method to navigate to DetailViewController after setting the selectedIndex property

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if (segue.identifier == “ShowDetailIdentifier”) {

var detail: DetailViewController

if let navigationController = segue.destinationViewController as? UINavigationController {

detail = navigationController.topViewController as DetailViewController

} else {

detail = segue.destinationViewController as DetailViewController

}

  

if let path = tableView.indexPathForSelectedRow() {

detail.selectedIndex = path.row + 1

}

}

}

201504011556.jpg

Download the source from here.

Filed Under: ios, iPad, iPhone, Programming, Xcode Tagged With: Demo, iPad, UISplitViewController, Xcode

Debugging Swift App in Xcode

February 17, 2015 By Ravi Shankar 1 Comment

Any beginner iOS developer should be aware of the NSLog statement. This is quite frequently used to debug Objective-C programs. In Swift you can use println or print statement instead of NSLog to write the debug information to the console log.

[code language=”swift”]var primeFlag:Bool = true
println("input number is \(number)")
if ((number == 2) || (number == 3)) {
return primeFlag
}
[/code]

 

This will write the following message in the console log.

input number is 5

But debugging a large app using println statement will be a time consuming process, instead you can use Xcode built-in features for debugging.

Breakpoint

 

Xcode users can place breakpoint at a specific statement and when the program execution reaches that line it pauses the execution. The breakpoint allows users to examine the value of variables at that specific context.

201502160926.jpg

Like any other IDE, Xcode provides option to Step Into, Step Out, Step Over and Continue option.

201502160929.jpg

Exception Breakpoint

When your app crashes and you want the app the stop at the line of statement that causes the crash then you can use Exception breakpoint. Click Debug menu and select Create Exception Breakpoint from the menu list.

201502161005.jpg

Conditional breakpoint

If you want to pause the execution using a breakpoint when a condition is met then you can use conditional breakpoint.

201502162238.jpg

Right click a breakpoint and select Edit BreakPoint from the list. Then add the add the condition for the breakpoint. In the below screenshot, when index reaches 251 the breakpoint will be activated.

201502170549.jpg

Symbolic breakpoint

Symbolic breakpoint pauses the program execution when it reaches the specified method. For example you want to pause the program execution in all the viewDidLoad methods then you can specify that using Symbolic breakpoint.

Debug menu -> Breakpoints -> Create Symbolic Breakpoint

201502170555.jpg

Enter the method name in symbol field and to target only specific module instead of all viewDidLoad methods you can enter the module name as well.

201502170820.jpg

Watch Point

When you want to pause the app execution whenever the value of a variable changes then you can use watch point. You can add a watch point by selecting variable and picking Watch option from the context menu.

201502170829.jpg

Breakpoint navigator

Xcode Breakpoint navigator will show the list of breakpoints that are currently active in your project.

201502170836.jpg

And you can remove all and selected breakpoints by right clicking on the Breakpoint navigator and selecting Delete Breakpoints option.

201502170838.jpg

Enable sound

Another useful feature which is available as part of Xcode debugging tool is to play sound when a breakpoint condition is met. This is quite useful when you have Xcode debugging in the background and want to let you know when the condition is met by playing the sound.

201502170845.jpg

To specify the condition, click on the Action drop down and select Sound from the list. Then add the notification sound that needs to played when the condition is met.

201502170846.jpg

Filed Under: Apple, ios, Programming, Xcode Tagged With: Apple, debugging, Swift, Xcode

Test Driven Development in Swift

February 9, 2015 By Ravi Shankar Leave a Comment

Here is a beginner tutorial on TDD in Swift by writing a program that checks for a prime number. Let us start by creating a new project, selecting template as Single View Application. Though we won’t be adding anything to the storyboard as we will focus only on the business logic.

201502082101.jpg

201502082103.jpg

After creating the project, the project navigator should have the following structure.

201502082104.jpg

from wikipedia

A prime number is a natural number greater than 1 that no positive divisors other than 1 and itself. – 2,3,5,7,11,13 ….

So now that we know the first prime number is 2, let us add a unit test that checks if number 2 is a prime number. We are going to have a new class called Util that will have the required function to check if a number is prime number. Before creating a Util class, create unit test class called TestsForUtil.swift.

201502082115.jpg

Select the template as Test Case Class and go with the default settings. Now you should see the newly added class as part of the project navigator under CheckForPrimeTests.

201502082117.jpg

As we don’t need CheckForPrimeTests.Swift, we can delete the file. And on opening TestsForSwift.swift, you should notice the following default test methods. setup(), tearDown(), testExampe(), testPerformanceExample(). In this demo, we are not going to use any of these methods and so you can remove them as well.

Let us add our first unit test that checks if number 2 is prime number. Add the following method,

func testTwoIsPrime() {

let number:Int = 2;

XCTAssertTrue(Util().isPrime(number), “2 is a prime number”);

}

You should see use of Unresolved identifier “Util as we are yet to add the class.

In TDD we write the tests first and then add the required functionality. Test Driven Development will ensure that you add only required code to pass your tests.

What this test function does is, it calls isPrime function in Util and receives if a boolean on whether the entered number is prime number. This unit test will show Pass status when the value received from isPrime is true.

Now add a Swift file with name as Util and make sure to select CheckForPrimeTests under Targets. This would ensure you can call functions written in Util class

201502082151.jpg

201502082152.jpg

Create a public class with name as Util and add function isPrime as shown below.

public class Util {

  

func isPrime(number:Int) -> Bool {

return number == 2

}

}

All we are doing here is to make sure the function validates number 2. Now executing unit test should show a green tick mark as shown below.

201502090829.jpg

Navigate back to TestsForUtil.swift and add second tests which checks for number 3.

  func testThreeIsPrime() {

let number:Int = 3;

XCTAssertTrue(Util().isPrime(number), “3 is a prime number”);

}

On executing this test you should notice failure message as we have hard coded isPrime function to work only for 2.

201502090831.jpg

And to make this test pass, we are going to check for 2 and 3 in isPrime function.

  func isPrime(number:Int) -> Bool {

return (number == 2) || (number == 3)

}

Let us add the unit test that checks for 4 which is not a prime number.

  func testFourIsPrime() {

let number:Int = 4;

XCTAssertFalse(Util().isPrime(number), “4 is not a prime number”);

}

We have used XCTAssertFalse as we are expecting isPrime to return false. This test would pass with out making any changes to isPrime function.

201502090838.jpg

Now let us add out next test case that checks for number 11.

  func testElevenIsPrime() {

let number:Int = 11;

XCTAssertTrue(Util().isPrime(number), “11 is a prime number”);

}

201502090841.jpg

We need to make changes to isPrime function so it returns true for number 11. But we cannot just keeping on hardcoding the numbers. So let us change the logic to handle all the prime numbers.

  func isPrime(number:Int) -> Bool {

  

var primeFlag:Bool = true

  

if ((number == 2) || (number == 3)) {

return primeFlag

}

  

if (number > 3) {

  

for index in 2…number-1 {

if (number % index == 0) {

primeFlag = false

break

}

}

}

  

return primeFlag

}

The above function would validate all prime and not a prime numbers and test written for number 11 should pass. Now you can write some tests for prime and not a prime number. For not a prime number make sure to use XCTAssertFalse.

  func testThirtyOneIsPrime() {

let number:Int = 31;

XCTAssertTrue(Util().isPrime(number), “31 is a prime number”);

}

  

func testFiftyIsPrime() {

let number:Int = 50;

XCTAssertFalse(Util().isPrime(number), “50 is not a prime number”);

}

Now let us check this logic for a negative number say -1. Negative numbers are not prime number so isPrime function should handle this. But this test would fail as we don’t have any check for negative numbers.

  func testMinusOneIsPrime() {

let number:Int = –1;

XCTAssertFalse(Util().isPrime(number), “-1 is not a prime number”);

}

Making a minor modifications to isPrime function should pass the test.

func isPrime(number:Int) -> Bool {

  

var primeFlag:Bool = true

  

if ((number == 2) || (number == 3)) {

return primeFlag

}

  

if (number > 3) {

  

for index in 2…number-1 {

if (number % index == 0) {

primeFlag = false

break

}

}

} else {

primeFlag = false

}

  

return primeFlag

}

And the test navigator in Xcode should show status for all your tests.

201502090920.jpg

The logic used in isPrime function can be improved and you can probably do that as your exercise. And make sure all the unit tests have green tick mark after changing isPrime function.

Download the source code from here.

Filed Under: Develop, ios, Programming, Xcode Tagged With: Swift, TDD, Test Driven Development, Xcode

Remove Apple Mach-O Linker directory not found

November 23, 2014 By Ravi Shankar Leave a Comment

Listed below are the steps to remove Apple Mach-O linker warning directory not found warning message.

201411232014.jpg

1. Navigate to Project Navigator, select the Project then navigate to Build Settings.

201411232016.jpg

2. Under Build Settings, scroll down to Search Paths and double click on Library Search Paths.

201411232021.jpg

3. Select the missing folder paths and remove them using “-“ sign.

201411232028.jpg

Filed Under: Develop, ios, Xcode Tagged With: Xcode

Apple Mach-O Linker error – Xcode 6 Beta 6

August 19, 2014 By Ravi Shankar 2 Comments

After downloading Xcode 6 beta 6, If you are receiving Apple Mach-O Linker error, Undefined symbols for architecture then try clearing the DerivedData for Xcode.

Undefined symbols for architecture x86_64:

“__TFSs26_forceBridgeFromObjectiveCU__FTPSs9AnyObject_MQ__Q_”, referenced from:

Derived data folder location

You find out the location of derived data using Xcode Preferences. Click Xcode -> Preferences.

201408191239.jpg

Click Locations tab and navigate to Derived Data section. Then click the arrow next to folder the path.

201408191241.jpg

Now delete DerivedData folder under Xcode.

201408191243.jpg

Useful link – http://stackoverflow.com/questions/25371556/swift-beta-6-confusing-linker-error-message

Filed Under: Programming, Xcode Tagged With: Mach error, Xcode, Xcode 6

Quotes app – Simple page based application in Swift

August 13, 2014 By Ravi Shankar 8 Comments

This is a very basic tutorial on how to create a simple page based app in Swift. We are going to use Page Based Application project template for displaying quotes in different pages.

201408131144.jpg201408131148.jpg

 

Create Page-Based Application in Swift

Click Xcode File menu, navigate to New and select Project from sub menu list.

201408131151.jpg

Select Page-Based Application in template screen and click Next button.

201408131152.jpg

In the Project Options screen, provide a name for your project and select language as Swift. Then click Next button and save your project.

201408131154.jpg

This should create a default page based application in Swift with the following project structure.

201408131156.jpg

Run the project on Simulator should display a page based app displaying names of months. When you tap or swipe the screen, next page should be displayed.

201408131159.jpg

Modifying the default Page-based application

We are going to modify the existing app to display quotes instead of months. The default project follows MVC pattern for retrieving and displaying the data. RootViewController.swift does the controller part, DataViewController.swift/Storyboard is used for displaying Views and ModelViewController.swift provides the data.

Let us first start with the changes to Storyboard. Navigate to Main.storyboard, select and delete the View and Label under Data View Controller.

201408131217.jpg

Set the background colour of the View to Purple using Attributes Inspector.

201408131220.jpg

Drag and drop a UILabel from Object library on to View Controller. Make sure to Centre align the label both vertically and horizontally.

201408131231.jpg

Use the Attributes Inspector to set the colour, alignment and Font for UILabel’s Text. Then change the number of lines displayed in UILabel to 3. Next use the align option in Interface builder to add the Horizontal and Vertical Center constraints (select Use Current Canvas Value)

201408131246.jpg

Click Connection Inspector and connect dataLabel to the newly added UILabel. dataLabel property was already added to the DataViewController.swift to display month name.

201408131250.jpg

Make changes to ModelViewController

Now we need to provide the required data for the display. Click ModelViewController.swift and change the pageData variable in to a constant and add array of four quotes as shown below.

[code language=”swift”]let pageData:NSArray = ["I’m as proud of what we don’t do as I am of what we do – Steve Jobs", "That’s one small step for man, one giant leap for mankind – Neil Armstrong","An ant on the move does more than a dozing ox – Lao Tzu","I mean, it’s impossible But that’s exactly what we’ve tried to do – Jonathan Ive"]
[/code]

 

Then delete the following lines from init() function

[code language=”swift”]// Create the data model.

let dateFormatter = NSDateFormatter()

pageData = dateFormatter.monthSymbols[/code]

 

Now compile and run the app on the simulator to see a Simple Page-based app in action written in Swift.

201408131315.jpg

Since we had gone with the default page-based template, we are unaware of the logic behind UIPageViewController. In another post, I will try to build a UIPageViewController from scratch without using the template and see more about the UIPageViewControllerDelegate and UIPageViewControllerDataSource.

Download source code from here

Filed Under: Develop, ios, iPhone, Programming, Xcode Tagged With: PageBaed App, Swift, Xcode

  1. Pages:
  2. «
  3. 1
  4. 2
  5. 3
  6. 4
  7. 5
  8. 6
  9. 7
  10. 8
  11. »
« Previous Page
Next Page »

Primary Sidebar

TwitterLinkedin

Recent Posts

  • How to block keywords in Jio broadband
  • How to disable opening an app automatically at login in Mac
  • How to set preferred Wifi network on Mac
  • Attribute Unavailable: Estimated section warning before iOS 11.0
  • How to recover Firefox password from Time Machine backup

Pages

  • About
  • Privacy Policy
  • Terms and Conditions

Copyright 2022 © rshankar.com

Terms and Conditions - Privacy Policy