Add the Alamofire CocoaPods in your swift project.
Find your Google place API key on Google APIs Console.
ViewConroller.swift
[code language=”obj-c”]
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let gpaViewController = GooglePlacesAutocomplete(
apiKey: "YOUR API KEY",
placeType: .Address
)
gpaViewController.placeDelegate = self
presentViewController(gpaViewController, animated: true, completion: nil)
}
}
extension ViewController: GooglePlacesAutocompleteDelegate {
func placeSelected(place: Place) {
println(place.description)
}
func placeViewClosed() {
dismissViewControllerAnimated(true, completion: nil)
}
}
[/code]
GooglePlacesAutocomplete.xib
GooglePlacesAutocomplete.swift
[code language=”obj-c”]
import UIKit
import Alamofire
enum PlaceType: Printable {
case All
case Geocode
case Address
case Establishment
case Regions
case Cities
var description : String {
switch self {
case .All: return ""
case .Geocode: return "geocode"
case .Address: return "address"
case .Establishment: return "establishment"
case .Regions: return "regions"
case .Cities: return "cities"
}
}
}
struct Place {
let id: String
let description: String
}
protocol GooglePlacesAutocompleteDelegate {
func placeSelected(place: Place)
func placeViewClosed()
}
// MARK: – GooglePlacesAutocomplete
class GooglePlacesAutocomplete: UINavigationController {
var gpaViewController: GooglePlacesAutocompleteContainer?
var placeDelegate: GooglePlacesAutocompleteDelegate? {
get { return gpaViewController?.delegate }
set { gpaViewController?.delegate = newValue }
}
convenience init(apiKey: String, placeType: PlaceType = .All) {
let gpaViewController = GooglePlacesAutocompleteContainer(
apiKey: apiKey,
placeType: placeType
)
self.init(rootViewController: gpaViewController)
self.gpaViewController = gpaViewController
let closeButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: "close")
gpaViewController.navigationItem.leftBarButtonItem = closeButton
gpaViewController.navigationItem.title = "Enter Address"
}
func close() {
placeDelegate?.placeViewClosed()
}
}
// MARK: – GooglePlaceSearchDisplayController
class GooglePlaceSearchDisplayController: UISearchDisplayController {
override func setActive(visible: Bool, animated: Bool) {
if active == visible { return }
searchContentsController.navigationController?.navigationBarHidden = true
super.setActive(visible, animated: animated)
searchContentsController.navigationController?.navigationBarHidden = false
if visible {
searchBar.becomeFirstResponder()
} else {
searchBar.resignFirstResponder()
}
}
}
// MARK: – GooglePlacesAutocompleteContainer
class GooglePlacesAutocompleteContainer: UIViewController {
var delegate: GooglePlacesAutocompleteDelegate?
var apiKey: String?
var places = [Place]()
var placeType: PlaceType = .All
convenience init(apiKey: String, placeType: PlaceType = .All) {
self.init(nibName: "GooglePlacesAutocomplete", bundle: nil)
self.apiKey = apiKey
self.placeType = placeType
}
override func viewDidLoad() {
super.viewDidLoad()
let tv: UITableView? = searchDisplayController?.searchResultsTableView
tv?.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
}
// MARK: – GooglePlacesAutocompleteContainer (UITableViewDataSource / UITableViewDelegate)
extension GooglePlacesAutocompleteContainer: UITableViewDataSource, UITableViewDelegate {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return places.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.searchDisplayController?.searchResultsTableView?.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
// Get the corresponding candy from our candies array
let place = self.places[indexPath.row]
// Configure the cell
cell.textLabel.text = place.description
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
delegate?.placeSelected(self.places[indexPath.row])
}
}
// MARK: – GooglePlacesAutocompleteContainer (UISearchDisplayDelegate)
extension GooglePlacesAutocompleteContainer: UISearchDisplayDelegate {
func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String!) -> Bool {
getPlaces(searchString)
return false
}
private func getPlaces(searchString: String) {
Alamofire.request(.GET,
"https://maps.googleapis.com/maps/api/place/autocomplete/json",
parameters: [
"input": searchString,
"type": "(\(placeType.description))",
"key": apiKey ?? ""
]).responseJSON { request, response, json, error in
if let response = json as? NSDictionary {
if let predictions = response["predictions"] as? Array<AnyObject> {
self.places = predictions.map { (prediction: AnyObject) -> Place in
return Place(
id: prediction["id"] as String,
description: prediction["description"] as String
)
}
}
}
self.searchDisplayController?.searchResultsTableView?.reloadData()
}
}
}
[/code]
I have learned this thing from Howard Wilson’s(watsonbox) Github Repository : watsonbox/ios_google_places_autocomplete
Happy coding 🙂
Apple
iOS 8 Map Kit Obj-C : Get Users Location
iOS 8 Map Kit Obj-C : Get Users Location
In your .plist Add a new row with the key name:
[code lang=”obj-c”]
NSLocationWhenInUseUsageDescription
[/code]
Or
[code lang=”obj-c”]
NSLocationAlwaysUsageDescription
[/code]
Define the header:
[code lang=”obj-c”]
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[/code]
Update your files with following code:
ViewController.h
[code lang=”obj-c”]
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
@interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
@property(nonatomic, retain) IBOutlet MKMapView *mapView;
@property(nonatomic, retain) CLLocationManager *locationManager;
[/code]
ViewController.m
[code lang=”obj-c”]
– (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(@"%@", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
– (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
– (NSString *)deviceLocation {
return [NSString stringWithFormat:@"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
[/code]
Helping, Learning, Coding 🙂
XML Parsing in Swift Language – iOS 10 – XMLParser
Code syntax is changed in version Swift 3. So, I have updated this article with Xcode 8 – iOS 10
Here is tutorial about how to parse the XML data in Swift Language – iOS 10 – XMLParser
Start with creating object of XMLParser
[code language=”obj-c”]
var parser = XMLParser(contentsOf: urlToSend)!
parser.delegate = self
[/code]
Delegate your class with XMLParserDelegate
[code language=”obj-c”]
class ViewController: UIViewController,XMLParserDelegate {
}
[/code]
Add Delegate methods
[code language=”obj-c”]
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
}
[/code]
Parse the XML with following method
[code language=”obj-c”]
parser.parse()
[/code]
Complete sample code:
[code language=”obj-c”]
import UIKit
class ViewController: UIViewController,XMLParserDelegate {
var strXMLData:String = ""
var currentElement:String = ""
var passData:Bool=false
var passName:Bool=false
var parser = XMLParser()
@IBOutlet var lblNameData : UILabel! = nil
override func viewDidLoad() {
super.viewDidLoad()
let url:String="http://api.androidhive.info/pizza/?format=xml"
let urlToSend: URL = URL(string: url)!
// Parse the XML
parser = XMLParser(contentsOf: urlToSend)!
parser.delegate = self
let success:Bool = parser.parse()
if success {
print("parse success!")
print(strXMLData)
lblNameData.text=strXMLData
} else {
print("parse failure!")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentElement=elementName;
if(elementName=="id" || elementName=="name" || elementName=="cost" || elementName=="description")
{
if(elementName=="name"){
passName=true;
}
passData=true;
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
currentElement="";
if(elementName=="id" || elementName=="name" || elementName=="cost" || elementName=="description")
{
if(elementName=="name"){
passName=false;
}
passData=false;
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
if(passName){
strXMLData=strXMLData+"\n\n"+string
}
if(passData)
{
print(string)
}
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print("failure error: ", parseError)
}
}
[/code]
Code Demo on My Github. Both Swift 2.2 and Swift 3 versions are available.
Helping, Learning, Coding 🙂
Create Simple Table (UITableView) in Swift Language iOS8
Here is simple tutorial to create table (UITableView) in Swift Language – iOS 8 – Xcode 6
Attach your UITableView IBOutlet to .swift file
[code language=”obj-c”]
@IBOutlet var tblSwift : UITableView = nil
[/code]
Delegate UITableViewDelegate and UITableViewDataSource to your Controller
[code language=”obj-c”]
class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource
{
…
}
[/code]
Don’t forgot to add the delegate methods otherwise you got error
[code language=”obj-c”]
class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource
{
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
…
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
…
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
…
}
}
[/code]
Register your cell
[code language=”obj-c”]
override func viewDidLoad() {
super.viewDidLoad()
self.tblSwift.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
// Do any additional setup after loading the view, typically from a nib.
}
[/code]
Following is sample of complete code
[code language=”obj-c”]
import UIKit
class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource
{
@IBOutlet var tblSwift : UITableView = nil
var items: String[] = ["This", "is" , "swift" , "language" , ":)"]
override func viewDidLoad() {
super.viewDidLoad()
self.tblSwift.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:UITableViewCell = self.tblSwift.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected item "+items[indexPath.row]) //or
println("You selected item \(items[indexPath.row])") //or
println("You selected cell #\(indexPath.row)!")
}
}
[/code]
Helping, Learning, Coding 🙂