SlideShare a Scribd company logo
1 of 336
1. After reviewing chapters 9, 10, and 11 of the Kotler and
Keller text, and using specific information derived from the
text, provide a brief comment about each of the following:
a. How an organization defines and characterizes its
product/service and brand relationships. Include a brief
analysis of how this product/service and brand relationship is
both positively and negatively affected by co-branding and
ingredient branding practices from a brand equity perspective
(consider information from pages 142 – 145 of the text). Please
use appropriate APA citation and attribution rules for all
information sources.
[insert the body of the response here]
b. How an organization can develop consumer experiences that
enhance the vague, abstract, and often complex characteristics
of services (consider information from pages 160 – 169 of the
text). Please use appropriate APA citation and attribution rules
for all information sources.
[insert the body of the response here]
c. Describe how consumer psychology is influenced by
discrepancies in reference prices, price-quality inferences, and
unexpected price-endings. Assess the impact of such
discrepancies on brand equity to include a statement regarding
the risks to the financial success of the organization’s products
and services (consider issues covered in pages 175 - 176 of the
text). Please use appropriate APA citation and attribution rules
for all information sources.
[insert the body of the response here]
2. After reading the companion article (Competing on the Eight
Dimensions of Quality ); provide a recommendation to a group
of executives regarding the importance of considering this
information (perhaps review the significance of auditing each
dimension alone and then in combination).Please use
appropriate APA citation and attribution rules for all
information sources.
[body of response]
3. After reading the companion article (Viewing Brands in
Multiple Dimensions); provide an executive summary for
executives regarding the significance to the firm of this
information; especially the information contained on page 44 of
the article. Please use appropriate APA citation and attribution
rules for all information sources.
[body of response]
The term briefly (or brief) suggests a limit of no more than 500
words per response.
References Cited: [use APA style and cite/reference all material
used in support of responses provided]
__MACOSX/._My Contact List
__MACOSX/My Contact List/._My Contact List
__MACOSX/My Contact List/._My Contact List.xcodeproj
__MACOSX/My Contact List/._.git
My Contact List/My Contact List/Constants.swift
//
// Constants.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import Foundation
struct Constants {
static let kSortField = "sortField"
static let kSortDirectionAscending =
"sortDirectionAscending"
}
__MACOSX/My Contact List/My Contact List/._Constants.swift
My Contact List/My Contact
List/LocationDemoViewController.swift
//
// LocationDemoViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
import CoreLocation
class LocationDemoViewController: UIViewController,
CLLocationManagerDelegate {
@IBOutlet weak var txtStreet: UITextField!
@IBOutlet weak var txtCity: UITextField!
@IBOutlet weak var txtState: UITextField!
@IBOutlet weak var lblLatitude: UILabel!
@IBOutlet weak var lblLongitude: UILabel!
@IBOutlet weak var lblLocationAccuracy: UILabel!
@IBOutlet weak var lblHeading: UILabel!
@IBOutlet weak var lblHeadingAccuracy: UILabel!
@IBOutlet weak var lblAltitude: UILabel!
@IBOutlet weak var lblAltitudeAccuracy: UILabel!
lazy var geoCoder = CLGeocoder()
var locationManager: CLLocationManager!
@objc func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to
resign the first responder status.
view.endEditing(true)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let tap: UITapGestureRecognizer =
UITapGestureRecognizer(target: self,
action:
#selector(self.dismissKeyboard))
view.addGestureRecognizer(tap)
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization() //ask
for permission to use location
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status:
CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
print("Permission granted")
}
else {
print("Permission NOT granted")
}
}
@IBAction func addressToCoordinates(_ sender: Any) {
let address = "(txtStreet.text!), (txtCity.text!),
(txtState.text!))"
geoCoder.geocodeAddressString(address) {(placemarks,
error) in
self.processAddressResponse(withPlacemarks:
placemarks, error: error)
}
}
private func processAddressResponse(withPlacemarks
placemarks: [CLPlacemark]?, error: Error?) {
if let error = error {
print("Geocode Error: (error)")
}
else {
var bestMatch: CLLocation?
if let placemarks = placemarks, placemarks.count > 0 {
bestMatch = placemarks.first?.location
}
if let coordinate = bestMatch?.coordinate {
lblLatitude.text = String(format: "%gu{00B0}",
coordinate.latitude)
lblLongitude.text = String(format: "%gu{00B0}",
coordinate.longitude)
}
else {
print("Didn't find any matching locations")
}
}
}
@IBAction func deviceCoordinates(_ sender: Any) {
locationManager.desiredAccuracy =
kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 100
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
}
override func viewDidDisappear(_ animated: Bool) {
locationManager.stopUpdatingLocation()
locationManager.stopUpdatingHeading()
}
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
let eventDate = location.timestamp
let howRecent = eventDate.timeIntervalSinceNow
if Double(howRecent) < 15.0 {
let coordinate = location.coordinate
lblLongitude.text = String(format: "%gu{00B0}",
coordinate.longitude)
lblLatitude.text = String(format: "%gu{00B0}",
coordinate.latitude)
lblLocationAccuracy.text = String(format: "%gm",
location.horizontalAccuracy)
lblAltitude.text = String(format: "%gm",
location.altitude)
lblAltitudeAccuracy.text = String(format: "%gm",
location.verticalAccuracy)
}
}
}
func locationManager(_ manager: CLLocationManager,
didUpdateHeading newHeading: CLHeading) {
if newHeading.headingAccuracy > 0 {
let theHeading = newHeading.trueHeading
var direction: String
switch theHeading {
case 225..<315:
direction = "W"
case 135..<225:
direction = "S"
case 45..<135:
direction = "E"
default:
direction = "N"
}
lblHeading.text = String(format: "%gu{00B0} (%@)",
theHeading, direction)
lblHeadingAccuracy.text = String(format:
"%gu{00B0}", newHeading.headingAccuracy)
}
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
let errorType = error._code == CLError.denied.rawValue ?
"Location Permission Denied" :
"Unknown Error"
let alertController = UIAlertController(title: "Error
Getting Location: (errorType)",
message: "Error Message:
(error.localizedDescription))",
preferredStyle: .alert)
let actionOK = UIAlertAction(title: "OK",
style: .default,
handler: nil)
alertController.addAction(actionOK)
present(alertController, animated: true, completion: nil)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact List/My Contact
List/._LocationDemoViewController.swift
__MACOSX/My Contact List/My Contact
List/._MyContactListModel.xcdatamodeld
My Contact List/My Contact List/MapViewController.swift
//
// MapViewController.swi ft
// My Contact List
//
// Created by Michael Eierman on 8/5/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
import MapKit
import CoreData
class MapViewController: UIViewController,
CLLocationManagerDelegate, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var sgmtMapType: UISegmentedControl!
var locationManager: CLLocationManager!
var contacts:[Contact] = []
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
// Do any additional setup after loading the view.
}
@IBAction func mapTypeChanged(_ sender: Any) {
switch sgmtMapType.selectedSegmentIndex {
case 0:
mapView.mapType = .standard
case 1:
mapView.mapType = .hybrid
case 2:
mapView.mapType = .satellite
default: break
}
}
override func viewWillAppear(_ animated: Bool) {
//Get contacts from Core Data
let appDelegate = UIApplication.shared.delegate as!
AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request =
NSFetchRequest<NSManagedObject>(entityName: "Contact")
var fetchedObjects:[NSManagedObject] = []
do {
fetchedObjects = try context.fetch(request)
} catch let error as NSError {
print("Could not fetch. (error), (error.userInfo)")
}
contacts = fetchedObjects as! [Contact]
//remove all annotations
self.mapView.removeAnnotations(self.mapView.annotations)
//go through all contacts
for contact in contacts { //as! [Contact] {
let address = "(contact.streetAddress!), (contact.city!)
(contact.state!)"
//geocoding
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) {(placemarks,
error) in
self.processAddressResponse(contact,
withPlacemarks: placemarks, error: error)
}
}
}
private func processAddressResponse(_ contact: Contact,
withPlacemarks placemarks: [CLPlacemark]?,
error: Error?) {
if let error = error {
print("Geocode Error: (error)")
}
else {
var bestMatch: CLLocation?
if let placemarks = placemarks, placemarks.count > 0 {
bestMatch = placemarks.first?.location
}
if let coordinate = bestMatch?.coordinate {
let mp = MapPoint(latitude: coordinate.latitude,
longitude: coordinate.longitude)
mp.title = contact.contactName
mp.subtitle = contact.streetAddress
mapView.addAnnotation(mp)
}
else {
print("Didn't find any matching locations")
}
}
}
@IBAction func findUser(_ sender: Any) {
mapView.showAnnotations(mapView.annotations,
animated: true)
// mapView.showsUserLocation = true
// mapView.setUserTrackingMode(.follow, animated: true)
}
func mapView(_ mapView: MKMapView, didUpdate
userLocation: MKUserLocation) {
var span = MKCoordinateSpan()
span.latitudeDelta = 0.05
span.longitudeDelta = 0.05
let viewRegion = MKCoordinateRegion(center:
userLocation.coordinate, span: span)
mapView.setRegion(viewRegion, animated: true)
// mapView.removeAnnotations(self.mapView.annotations)
let mp = MapPoint(latitude:
userLocation.coordinate.latitude,
longitude: userLocation.coordinate.longitude)
mp.title = "You"
mp.subtitle = "Are here"
mapView.addAnnotation(mp)
}
/*
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
mapView.setUserTrackingMode(.follow, animated: true)
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact List/My Contact
List/._MapViewController.swift
My Contact List/My Contact List/MapPoint.swift
//
// MapPoint.swift
// My Contact List
//
// Created by Michael Eierman on 8/7/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import Foundation
import MapKit
///This is Listing 13.10
class MapPoint: NSObject, MKAnnotation{
var title: String?
var subtitle: String?
var latitude: Double
var longitude: Double
var coordinate: CLLocationCoordinate2D {
return CLLocationCoordinate2D(latitude: latitude,
longitude: longitude)
}
init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
}
}
__MACOSX/My Contact List/My Contact List/._MapPoint.swift
__MACOSX/My Contact List/My Contact List/._Assets.xcassets
My Contact List/My Contact List/ContactsViewController.swift
//
// ContactsViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/5/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
import CoreData
class ContactsViewController: UIViewController,
UITextFieldDelegate, DateControllerDelegate {
var currentContact: Contact?
let appDelegate = UIApplication.shared.delegate as!
AppDelegate
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var txtName: UITextField!
@IBOutlet weak var txtAddress: UITextField!
@IBOutlet weak var txtCity: UITextField!
@IBOutlet weak var txtState: UITextField!
@IBOutlet weak var txtZip: UITextField!
@IBOutlet weak var txtCell: UITextField!
@IBOutlet weak var txtPhone: UITextField!
@IBOutlet weak var txtEmail: UITextField!
@IBOutlet weak var lblBirthdate: UILabel!
@IBOutlet weak var btnChange: UIButton!
@IBOutlet weak var sgmtEditMode: UISegmentedControl!
@IBAction func changeEditMode( _ sender: Any) {
let textFields: [UITextField] = [txtName, txtAddress,
txtCity, txtState, txtZip, txtPhone,
txtCell, txtEmail]
if sgmtEditMode.selectedSegmentIndex == 0 {
for textField in textFields {
textField.isEnabled = false
textField.borderStyle =
UITextField.BorderStyle.none
}
btnChange.isHidden = true
navigationItem.rightBarButtonItem = nil
}
else if sgmtEditMode.selectedSegmentIndex == 1{
for textField in textFields {
textField.isEnabled = true
textField.borderStyle =
UITextField.BorderStyle.roundedRect
}
btnChange.isHidden = false
navigationItem.rightBarButtonItem =
UIBarButtonItem(barButtonSystemItem: .save,
target: self,
action:
#selector(self.saveContact))
}
}
func textFieldShouldEndEditing(_ textField: UITextField) ->
Bool {
if currentContact == nil {
let context =
appDelegate.persistentContainer.viewContext
currentContact = Contact(context: context)
}
currentContact?.contactName = txtName.text
currentContact?.streetAddress = txtAddress.text
currentContact?.city = txtCity.text
currentContact?.state = txtState.text
currentContact?.zipCode = txtZip.text
currentContact?.cellNumber = txtCell.text
currentContact?.phoneNumber = txtPhone.text
currentContact?.email = txtEmail.text
return true
}
@objc func saveContact() {
appDelegate.saveContext()
sgmtEditMode.selectedSegmentIndex = 0
changeEditMode(self)
}
override func viewDidLoad() {
super.viewDidLoad()
if currentContact != nil {
txtName.text = currentContact!.contactName
txtAddress.text = currentContact!.streetAddress
txtCity.text = currentContact!.city
txtState.text = currentContact!.state
txtZip.text = currentContact!.zipCode
txtPhone.text = currentContact!.phoneNumber
txtCell.text = currentContact!.cellNumber
txtEmail.text = currentContact!.email
let formatter = DateFormatter()
formatter.dateStyle = .short
if currentContact!.birthday != nil {
lblBirthdate.text = formatter.string(from:
currentContact!.birthday!)
}
}
self.changeEditMode(self)
let textFields: [UITextField] = [txtName, txtAddress,
txtCity, txtState, txtZip,
txtPhone, txtCell, txtEmail]
for textfield in textFields {
textfield.addTarget(self,
action:
#selector(UITextFieldDelegate.textFieldShouldEndEditing(_:)),
for: UIControl.Event.editingDi dEnd)
}
}
func dateChanged(date: Date) {
if currentContact == nil {
let context =
appDelegate.persistentContainer.viewContext
currentContact = Contact(context: context)
}
currentContact?.birthday = date
let formatter = DateFormatter()
formatter.dateStyle = .short
lblBirthdate.text = formatter.string(from: date)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.registerKeyboardNotifications()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.unregisterKeyboardNotifications()
}
func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector:
#selector(ContactsViewController.keyboardDidShow(notificatio
n:)), name:
UIResponder.keyboardDidShowNotification, object:
nil)
NotificationCenter.default.addObserver(self, selector:
#selector(ContactsViewController.keyboardWillHide(notificatio
n:)), name:
UIResponder.keyboardWillHideNotification, object:
nil)
}
func unregisterKeyboardNotifications() {
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardDidShow(notification: NSNotification)
{
let userInfo: NSDictionary = notification.userInfo! as
NSDictionary
let keyboardInfo =
userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as!
NSValue
let keyboardSize = keyboardInfo.cgRectValue.size
// Get the existing contentInset for the scrollView and set
the bottom property to
//be the height of the keyboard
var contentInset = self.scrollView.contentInset
contentInset.bottom = keyboardSize.height
self.scrollView.contentInset = contentInset
self.scrollView.scrollIndicatorInsets = contentInset
}
@objc func keyboardWillHide(notification: NSNotification)
{
var contentInset = self.scrollView.contentInset
contentInset.bottom = 0
self.scrollView.contentInset = contentInset
self.scrollView.scrollIndicatorInsets = UIEdgeInsets.zero
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
if(segue.identifier == "segueContactDate"){
let dateController = segue.destination as!
DateViewController
dateController.delegate = self
}
}
}
__MACOSX/My Contact List/My Contact
List/._ContactsViewController.swift
__MACOSX/My Contact List/My Contact List/._Base.lproj
My Contact List/My Contact List/AppDelegate.swift
//
// AppDelegate.swift
// My Contact List
//
// Created by Michael Eierman on 8/2/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application
launch.
let settings = UserDefaults.standard
if settings.string(forKey: Constants.kSortField) == nil {
settings.set("city", forKey: Constants.kSortField)
}
if settings.string(forKey:
Constants.kSortDirectionAscending) == nil {
settings.set(true, forKey:
Constants.kSortDirectionAscending)
}
settings.synchronize()
NSLog("Sort field: %@", settings.string(forKey:
Constants.kSortField)!)
NSLog("Sort direction: (settings.bool(forKey:
Constants.kSortDirectionAscending))")
return true
}
func applicationWillResignActive(_ application:
UIApplication) {
// Sent when the application is about to move from active
to inactive state. This can occur for certain types of temporary
interruptions (such as an incoming phone call or SMS message)
or when the user quits the application and it begins the
transition to the background state.
// Use this method to pause ongoing tasks, disable timers,
and invalidate graphics rendering callbacks. Games should use
this method to pause the game.
}
func applicationDidEnterBackground(_ application:
UIApplication) {
// Use this method to release shared resources, save user
data, invalidate timers, and store enough application state
information to restore your application to its current state in
case it is terminated later.
// If your application supports background execution, this
method is called instead of applicationWillTerminate: when the
user quits.
}
func applicationWillEnterForeground(_ application:
UIApplication) {
// Called as part of the transition from the background to
the active state; here you can undo many of the changes made
on entering the background.
}
func applicationDidBecomeActive(_ application:
UIApplication) {
// Restart any tasks that were paused (or not yet started)
while the application was inactive. If the application was
previously in the background, optionally refresh the user
interface.
}
func applicationWillTerminate(_ application: UIApplication)
{
// Called when the application is about to terminate. Save
data if appropriate. See also applicationDidEnterBackground:.
}
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This
implementation
creates and returns a container, having loaded the store
for the
application to it. This property is optional since there are
legitimate
error conditions that could cause the creation of the store
to fail.
*/
let container = NSPersistentContainer(name:
"MyContactListModel")
container.loadPersistentStores(completionHandler: {
(storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle
the error appropriately.
// fatalError() causes the application to generate a
crash log and terminate. You should
// not use this function in a shipping application,
although it may be useful during
// development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be
created, or disallows writing.
* The persistent store is not accessible, due to
permissions or data protection when
* the device is locked.
* The device is out of space.
* The store could not be migrated to the current
model version.
Check the error message to determine what the
actual problem was.
*/
fatalError("Unresolved error (error),
(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle
the error appropriately.
// fatalError() causes the application to generate a
crash log and terminate. You should
// not use this function in a shipping application,
although it may be useful during
// development.
let nserror = error as NSError
fatalError("Unresolved error (nserror),
(nserror.userInfo)")
}
}
}
}
__MACOSX/My Contact List/My Contact
List/._AppDelegate.swift
My Contact List/My Contact
List/ContactsTableViewController.swift
//
// ContactsTableViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
import CoreData
class ContactsTableViewController: UITableViewController {
// let contacts = ["Jim", "John", "Dana", "Rosie", "Justin",
"Jeremy", "Sarah", "Matt", "Joe", "Donald", "Jeff"]
var contacts:[NSManagedObject] = []
let appDelegate = UIApplication.shared.delegate as!
AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.leftBarButtonItem =
self.editButtonItem
loadDataFromDatabase()
}
override func viewWillAppear(_ animated: Bool) {
loadDataFromDatabase()
tableView.reloadData()
}
func loadDataFromDatabase() {
let settings = UserDefaults.standard
let sortField = settings.string(forKey:
Constants.kSortField)
let sortAscending = settings.bool(forKey:
Constants.kSortDirectionAscending)
//Set up Core Data Context
let context = appDelegate.persistentContainer.viewContext
//Set up Request
let request =
NSFetchRequest<NSManagedObject>(entityName: "Contact")
//Specify sorting
let sortDescriptor = NSSortDescriptor(key: sortField,
ascending: sortAscending)
let sortDescriptorArray = [sortDescriptor]
//to sort by multiple fields, add more sort descriptors to
the array
request.sortDescriptors = sortDescriptorArray
do {
contacts = try context.fetch(request)
} catch let error as NSError {
print("Could not fetch. (error), (error.userInfo)")
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView)
-> Int {
return 1
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"ContactsCell", for: indexPath)
// Configure the cell...
let contact = contacts[indexPath.row] as? Contact
cell.textLabel?.text = contact?.contactName
cell.detailTextLabel?.text = contact?.city
cell.accessoryType = .detailDisclosureButton
return cell
}
override func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
let selectedContact = contacts[indexPath.row] as? Contact
let name = selectedContact!.contactName!
let actionHandler = { (action:UIAlertAction!) -> Void in
let storyboard = UIStoryboard(name: "Main", bundle:
nil)
let controller =
storyboard.instantiateViewController(withIdentifier:
"ContactController")
as? ContactsViewController
controller?.currentContact = selectedContact
self.navigationController?.pushViewController(controller!,
animated: true)
}
let alertController = UIAlertController(title: "Contact
selected",
message: "Selected row:
(indexPath.row) ((name))",
preferredStyle: .alert)
let actionCancel = UIAlertAction(title: "Cancel",
style: .cancel,
handler: nil)
let actionDetails = UIAlertAction(title: "Show Details",
style: .default,
handler: actionHandler)
alertController.addAction(actionCancel)
alertController.addAction(actionDetails)
present(alertController, animated: true, completion: nil)
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView,
canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be
editable.
return true
}
*/
override func tableView(_ tableView: UITableView,
commit editingStyle:
UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
let contact = contacts[indexPath.row] as? Contact
let context =
appDelegate.persistentContainer.viewContext
context.delete(contact!)
do {
try context.save()
}
catch {
fatalError("Error saving context: (error)")
}
loadDataFromDatabase()
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert
it into the array,
//and add a new row to the table view
}
}
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView,
moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table
view.
override func tableView(_ tableView: UITableView,
canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-
orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
if segue.identifier == "EditContact" {
let contactController = segue.destination as?
ContactsViewController
let selectedRow = self.tableView.indexPath(for: sender
as! UITableViewCell)?.row
let selectedContact = contacts[selectedRow!] as?
Contact
contactController?.currentContact = selectedContact!
}
}
}
__MACOSX/My Contact List/My Contact
List/._ContactsTableViewController.swift
My Contact List/My Contact List/DateViewController.swift
//
// DateViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
protocol DateControllerDelegate: class {
func dateChanged(date: Date)
}
class DateViewController: UIViewController {
weak var delegate: DateControllerDelegate?
@IBOutlet weak var dtpDate: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
let saveButton: UIBarButtonItem =
UIBarButtonItem(barButtonSystemItem:
UIBarButtonItem.SystemItem.save,
target: self,
action: #selector(saveDate))
self.navigationItem.rightBarButtonItem = saveButton
self.title = "Pick Birthdate"
}
@objc func saveDate(){
self.delegate?.dateChanged(date: dtpDate.date)
self.navigationController?.popViewController(animated:
true)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact List/My Contact
List/._DateViewController.swift
My Contact List/My Contact List/Info.plist
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleVersion
1
LSRequiresIPhoneOS
NSLocationWhenInUseUsageDescription
We need to know where we're at!
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
UIRequiredDeviceCapabilities
armv7
UIStatusBarTintParameters
UINavigationBar
Style
UIBarStyleDefault
Translucent
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
__MACOSX/My Contact List/My Contact List/._Info.plist
My Contact List/My Contact List/SettingsViewController.swift
//
// SettingsViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/5/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class SettingsViewController: UIViewController,
UIPickerViewDataSource, UIPickerViewDelegate {
@IBOutlet weak var swAscending: UISwitch!
@IBOutlet weak var pckSortField: UIPickerView!
let sortOrderItems: Array<String> = ["contactName", "city",
"birthday"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
pckSortField.dataSource = self;
pckSortField.delegate = self;
}
override func viewWillAppear(_ animated: Bool) {
//set the UI based on values in UserDefaults
let settings = UserDefaults.standard
swAscending.setOn(settings.bool(forKey:
Constants.kSortDirectionAscending), animated: true)
let sortField = settings.string(forKey:
Constants.kSortField)
var i = 0
for field in sortOrderItems {
if field == sortField {
pckSortField.selectRow(i, inComponent: 0, animated:
false)
}
i += 1
}
pckSortField.reloadComponent(0)
}
@IBAction func sortDirectionChanged(_ sender: Any) {
let settings = UserDefaults.standard
settings.set(swAscending.isOn, forKey:
Constants.kSortDirectionAscending)
settings.synchronize()
}
// MARK: UIPickerViewDelegate Methods
// Returns the number of 'columns' to display.
func numberOfComponents(in pickerView: UIPickerView) ->
Int {
return 1
}
// Returns the # of rows in the picker
func pickerView(_ pickerView: UIPickerView,
numberOfRowsInComponent component: Int) -> Int {
return sortOrderItems.count
}
//Sets the value that is shown for each row in the picker
func pickerView(_ pickerView: UIPickerView, titleForRow
row: Int, forComponent component: Int)
-> String? {
return sortOrderItems[row]
}
//If the user chooses from the pickerview, it calls this
function;
func pickerView(_ pickerView: UIPickerView, didSelectRow
row: Int, inComponent component: Int) {
let sortField = sortOrderItems[row]
let settings = UserDefaults.standard
settings.set(sortField, forKey: Constants.kSortField)
settings.synchronize()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact List/My Contact
List/._SettingsViewController.swift
My Contact List/My Contact List.xcodeproj/project.pbxproj
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1E31C16722F9CDBE0072F69E /* Constants.swift in Sources */
= {isa = PBXBuildFile; fileRef =
1E31C16622F9CDBE0072F69E /* Constants.swift */; };
1E31C18B22F9D0580072F69E /*
MyContactListModel.xcdatamodeld in Sources */ = {isa =
PBXBuildFile; fileRef = 1E31C18922F9D0580072F69E /*
MyContactListModel.xcdatamodeld */; };
1E31C18D22F9DC4C0072F69E /* DateViewController.swift in
Sources */ = {isa = PBXBuildFile; fileRef =
1E31C18C22F9DC4C0072F69E /* DateViewController.swift */;
};
1E31C18F22F9E52B0072F69E /*
ContactsTableViewController.swift in Sources */ = {isa =
PBXBuildFile; fileRef = 1E31C18E22F9E52B0072F69E /*
ContactsTableViewController.swift */; };
1E31C19122F9FEEB0072F69E /*
LocationDemoViewController.swift in Sources */ = {isa =
PBXBuildFile; fileRef = 1E31C19022F9FEEB0072F69E /*
LocationDemoViewController.swift */; };
1E31C19322FB2ECF0072F69E /* MapPoint.swift in Sources */
= {isa = PBXBuildFile; fileRef =
1E31C19222FB2ECF0072F69E /* MapPoint.swift */; };
1E34AC7B22F4A36C00342F01 /* AppDelegate.swift in
Sources */ = {isa = PBXBuildFile; fileRef =
1E34AC7A22F4A36C00342F01 /* AppDelegate.swift */; };
1E34AC8222F4A36C00342F01 /* Main.storyboard in Resources
*/ = {isa = PBXBuildFile; fileRef =
1E34AC8022F4A36C00342F01 /* Main.storyboard */; };
1E34AC8422F4A36E00342F01 /* Assets.xcassets in Resources
*/ = {isa = PBXBuildFile; fileRef =
1E34AC8322F4A36E00342F01 /* Assets.xcassets */; };
1E34AC8722F4A36E00342F01 /* LaunchScreen.storyboard in
Resources */ = {isa = PBXBuildFile; fileRef =
1E34AC8522F4A36E00342F01 /* LaunchScreen.storyboard */;
};
1E34AC8F22F8851A00342F01 /* ContactsViewController.swift
in Sources */ = {isa = PBXBuildFile; fileRef =
1E34AC8E22F8851A00342F01 /* ContactsViewController.swift
*/; };
1E34AC9122F8852700342F01 /* SettingsViewController.swift
in Sources */ = {isa = PBXBuildFile; fileRef =
1E34AC9022F8852700342F01 /* SettingsViewController.swift
*/; };
1E34AC9322F8853600342F01 /* MapViewController.swift in
Sources */ = {isa = PBXBuildFile; fileRef =
1E34AC9222F8853600342F01 /* MapViewController.swift */;
};
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1E31C16622F9CDBE0072F69E /* Constants.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path
= Constants.swift; sourceTree = "<group>"; };
1E31C18A22F9D0580072F69E /*
MyContactListModel.xcdatamodel */ = {isa =
PBXFileReference; lastKnownFileType = wrapper.xcdatamodel;
path = MyContactListModel.xcdatamodel; sourceTree =
"<group>"; };
1E31C18C22F9DC4C0072F69E /* DateViewController.swift */
= {isa = PBXFileReference; lastKnownFileType =
sourcecode.swift; path = DateViewController.swift; sourceTree
= "<group>"; };
1E31C18E22F9E52B0072F69E /*
ContactsTableViewController.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path
= ContactsTableViewController.swift; sourceTree = "<group>";
};
1E31C19022F9FEEB0072F69E /*
LocationDemoViewController.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path
= LocationDemoViewController.swift; sourceTree = "<group>";
};
1E31C19222FB2ECF0072F69E /* MapPoint.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path
= MapPoint.swift; sourceTree = "<group>"; };
1E34AC7722F4A36C00342F01 /* My Contact List.app */ = {isa
= PBXFileReference; explicitFileType = wrapper.application;
includeInIndex = 0; path = "My Contact List.app"; sourceTree =
BUILT_PRODUCTS_DIR; };
1E34AC7A22F4A36C00342F01 /* AppDelegate.swift */ = {isa
= PBXFileReference; lastKnownFileType = sourcecode.swift;
path = AppDelegate.swift; sourceTree = "<group>"; };
1E34AC8122F4A36C00342F01 /* Base */ = {isa =
PBXFileReference; lastKnownFileType = file.storyboard; name
= Base; path = Base.lproj/Main.storyboard; sourceTree =
"<group>"; };
1E34AC8322F4A36E00342F01 /* Assets.xcassets */ = {isa =
PBXFileReference; lastKnownFileType = folder.assetcatalog;
path = Assets.xcassets; sourceTree = "<group>"; };
1E34AC8622F4A36E00342F01 /* Base */ = {isa =
PBXFileReference; lastKnownFileType = file.storyboard; name
= Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree
= "<group>"; };
1E34AC8822F4A36E00342F01 /* Info.plist */ = {isa =
PBXFileReference; lastKnownFileType = text.plist.xml; path =
Info.plist; sourceTree = "<group>"; };
1E34AC8E22F8851A00342F01 /* ContactsViewController.swift
*/ = {isa = PBXFileReference; lastKnownFileType =
sourcecode.swift; path = ContactsViewController.swift;
sourceTree = "<group>"; };
1E34AC9022F8852700342F01 /* SettingsViewController.sw ift
*/ = {isa = PBXFileReference; lastKnownFileType =
sourcecode.swift; path = SettingsViewController.swift;
sourceTree = "<group>"; };
1E34AC9222F8853600342F01 /* MapViewController.swift */ =
{isa = PBXFileReference; lastKnownFileType =
sourcecode.swift; path = MapViewController.swift; sourceTree
= "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1E34AC7422F4A36C00342F01 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1E34AC6E22F4A36C00342F01 = {
isa = PBXGroup;
children = (
1E34AC7922F4A36C00342F01 /* My Contact List */,
1E34AC7822F4A36C00342F01 /* Products */,
);
sourceTree = "<group>";
};
1E34AC7822F4A36C00342F01 /* Products */ = {
isa = PBXGroup;
children = (
1E34AC7722F4A36C00342F01 /* My Contact List.app */,
);
name = Products;
sourceTree = "<group>";
};
1E34AC7922F4A36C00342F01 /* My Contact List */ = {
isa = PBXGroup;
children = (
1E34AC7A22F4A36C00342F01 /* AppDelegate.swift */,
1E34AC8022F4A36C00342F01 /* Main.storyboard */,
1E34AC8322F4A36E00342F01 /* Assets.xcassets */,
1E34AC8522F4A36E00342F01 /* LaunchScreen.storyboard */,
1E34AC8822F4A36E00342F01 /* Info.plist */,
1E34AC8E22F8851A00342F01 /* ContactsViewController.swift
*/,
1E34AC9022F8852700342F01 /* SettingsViewController.swift
*/,
1E34AC9222F8853600342F01 /* MapViewController.swift */,
1E31C16622F9CDBE0072F69E /* Constants.swift */,
1E31C18922F9D0580072F69E /*
MyContactListModel.xcdatamodeld */,
1E31C18C22F9DC4C0072F69E /* DateViewController.swift */,
1E31C18E22F9E52B0072F69E /*
ContactsTableViewController.swift */,
1E31C19022F9FEEB0072F69E /*
LocationDemoViewController.swift */,
1E31C19222FB2ECF0072F69E /* MapPoint.swift */,
);
path = "My Contact List";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1E34AC7622F4A36C00342F01 /* My Contact List */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1E34AC8B22F4A36E00342F01 /*
Build configuration list for PBXNativeTarget "My Contact List"
*/;
buildPhases = (
1E34AC7322F4A36C00342F01 /* Sources */,
1E34AC7422F4A36C00342F01 /* Frameworks */,
1E34AC7522F4A36C00342F01 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "My Contact List";
productName = "My Contact List";
productReference = 1E34AC7722F4A36C00342F01 /* My
Contact List.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
1E34AC6F22F4A36C00342F01 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1030;
LastUpgradeCheck = 1030;
ORGANIZATIONNAME = "Learning Mobile Apps";
TargetAttributes = {
1E34AC7622F4A36C00342F01 = {
CreatedOnToolsVersion = 10.3;
};
};
};
buildConfigurationList = 1E34AC7222F4A36C00342F01 /*
Build configuration list for PBXProject "My Contact List" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 1E34AC6E22F4A36C00342F01;
productRefGroup = 1E34AC7822F4A36C00342F01 /* Products
*/;
projectDirPath = "";
projectRoot = "";
targets = (
1E34AC7622F4A36C00342F01 /* My Contact List */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
1E34AC7522F4A36C00342F01 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1E34AC8722F4A36E00342F01 /* LaunchScreen.storyboard in
Resources */,
1E34AC8422F4A36E00342F01 /* Assets.xcassets in Resources
*/,
1E34AC8222F4A36C00342F01 /* Main.storyboard in Resources
*/,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1E34AC7322F4A36C00342F01 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1E31C16722F9CDBE0072F69E /* Constants.swift in Sources
*/,
1E34AC9322F8853600342F01 /* MapViewController.swift in
Sources */,
1E31C18D22F9DC4C0072F69E /* DateViewController.swift in
Sources */,
1E31C18B22F9D0580072F69E /*
MyContactListModel.xcdatamodeld in Sources */,
1E31C19122F9FEEB0072F69E /*
LocationDemoViewController.swift in Sources */,
1E34AC8F22F8851A00342F01 /* ContactsViewController.swift
in Sources */,
1E34AC7B22F4A36C00342F01 /* AppDelegate.swift in
Sources */,
1E31C19322FB2ECF0072F69E /* MapPoint.swift in Sources */,
1E31C18F22F9E52B0072F69E /*
ContactsTableViewController.swift in Sources */,
1E34AC9122F8852700342F01 /* SettingsViewController.swift
in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
1E34AC8022F4A36C00342F01 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
1E34AC8122F4A36C00342F01 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
1E34AC8522F4A36E00342F01 /* LaunchScreen.storyboard */ =
{
isa = PBXVariantGroup;
children = (
1E34AC8622F4A36E00342F01 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1E34AC8922F4A36E00342F01 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION =
YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING =
YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS
= YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION =
YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY =
YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS =
YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
1E34AC8A22F4A36E00342F01 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION =
YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING =
YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS
= YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION =
YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY =
YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS =
YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
1E34AC8C22F4A36E00342F01 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "My Contact List/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER =
"com.company.versionthree.My-Contact-List";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
1E34AC8D22F4A36E00342F01 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "My Contact List/Info.plis t";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER =
"com.company.versionthree.My-Contact-List";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1E34AC7222F4A36C00342F01 /* Build configuration list for
PBXProject "My Contact List" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1E34AC8922F4A36E00342F01 /* Debug */,
1E34AC8A22F4A36E00342F01 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1E34AC8B22F4A36E00342F01 /* Build configuration list for
PBXNativeTarget "My Contact List" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1E34AC8C22F4A36E00342F01 /* Debug */,
1E34AC8D22F4A36E00342F01 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
1E31C18922F9D0580072F69E /*
MyContactListModel.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
1E31C18A22F9D0580072F69E /*
MyContactListModel.xcdatamodel */,
);
currentVersion = 1E31C18A22F9D0580072F69E /*
MyContactListModel.xcdatamodel */;
path = MyContactListModel.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = 1E34AC6F22F4A36C00342F01 /* Project object
*/;
}
__MACOSX/My Contact List/My Contact
List.xcodeproj/._project.pbxproj
__MACOSX/My Contact List/My Contact
List.xcodeproj/._xcuserdata
__MACOSX/My Contact List/My Contact
List.xcodeproj/._project.xcworkspace
My Contact List/.git/config
[core]
bare = false
repositoryformatversion = 0
filemode = true
ignorecase = true
precomposeunicode = true
logallrefupdates = true
__MACOSX/My Contact List/.git/._config
__MACOSX/My Contact List/.git/._objects
My Contact List/.git/HEAD
ref: refs/heads/master
__MACOSX/My Contact List/.git/._HEAD
__MACOSX/My Contact List/.git/._info
My Contact List/.git/description
Unnamed repository; edit this file 'description' to name the
repository.
__MACOSX/My Contact List/.git/._description
__MACOSX/My Contact List/.git/._hooks
__MACOSX/My Contact List/.git/._refs
My Contact List/.git/index
__MACOSX/My Contact List/.git/._index
__MACOSX/My Contact List/My Contact
List/MyContactListModel.xcdatamodeld/._MyContactListModel
.xcdatamodel
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/._sample-881-globe.imageset
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/._AppIcon.appiconset
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/._second.imageset
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/._first.imageset
My Contact List/My Contact List/Assets.xcassets/Contents.json
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/._Contents.json
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/._sample-834-bolt.imageset
My Contact List/My Contact
List/Base.lproj/LaunchScreen.storyboard
__MACOSX/My Contact List/My Contact
List/Base.lproj/._LaunchScreen.storyboard
My Contact List/My Contact List/Base.lproj/Main.storyboard
__MACOSX/My Contact List/My Contact
List/Base.lproj/._Main.storyboard
__MACOSX/My Contact List/My Contact
List.xcodeproj/xcuserdata/._eierman.xcuserdatad
My Contact List/My Contact
List.xcodeproj/project.xcworkspace/contents.xcworkspacedata
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/._contents.xcworkspacedata
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/._xcuserdata
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/._xcshareddata
__MACOSX/My Contact List/.git/objects/._51
__MACOSX/My Contact List/.git/objects/._93
__MACOSX/My Contact List/.git/objects/._94
__MACOSX/My Contact List/.git/objects/._b2
__MACOSX/My Contact List/.git/objects/._da
__MACOSX/My Contact List/.git/objects/._bd
__MACOSX/My Contact List/.git/objects/._d1
__MACOSX/My Contact List/.git/objects/._c0
__MACOSX/My Contact List/.git/objects/._pack
__MACOSX/My Contact List/.git/objects/._11
__MACOSX/My Contact List/.git/objects/._74
__MACOSX/My Contact List/.git/objects/._44
__MACOSX/My Contact List/.git/objects/._info
__MACOSX/My Contact List/.git/objects/._a9
__MACOSX/My Contact List/.git/objects/._f9
__MACOSX/My Contact List/.git/objects/._48
__MACOSX/My Contact List/.git/objects/._1e
__MACOSX/My Contact List/.git/objects/._78
__MACOSX/My Contact List/.git/objects/._7f
My Contact List/.git/info/exclude
.DS_Store
UserInterfaceState.xcuserstate
__MACOSX/My Contact List/.git/info/._exclude
My Contact List/.git/hooks/README.sample
#!/bin/sh
#
# Place appropriately named executable hook scripts into this
directory
# to intercept various actions that git takes. See `git help
hooks` for
# more information.
__MACOSX/My Contact List/.git/hooks/._README.sample
__MACOSX/My Contact List/.git/refs/._heads
__MACOSX/My Contact List/.git/refs/._tags
My Contact List/My Contact
List/MyContactListModel.xcdatamodeld/MyContactListModel.x
cdatamodel/contents
__MACOSX/My Contact List/My Contact
List/MyContactListModel.xcdatamodeld/MyContactListModel.x
cdatamodel/._contents
My Contact List/My Contact List/Assets.xcassets/sa mple-881-
globe.imageset/sample-401-globe.png
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/sample-881-globe.imageset/._sample-401-
globe.png
My Contact List/My Contact List/Assets.xcassets/sample-881-
globe.imageset/[email protected]
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/sample-881-
globe.imageset/[email protected]
My Contact List/My Contact List/Assets.xcassets/sample-881-
globe.imageset/Contents.json
{
"images" : [
{
"idiom" : "universal",
"filename" : "sample-401-globe.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/sample-881-globe.imageset/._Contents.json
My Contact List/My Contact
List/Assets.xcassets/AppIcon.appiconset/Contents.json
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/AppIcon.appiconset/._Contents.json
My Contact List/My Contact
List/Assets.xcassets/second.imageset/second.pdf
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/second.imageset/._second.pdf
My Contact List/My Contact
List/Assets.xcassets/second.imageset/Contents.json
{
"images" : [
{
"idiom" : "universal",
"filename" : "second.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/second.imageset/._Contents.json
My Contact List/My Contact
List/Assets.xcassets/first.imageset/Contents.json
{
"images" : [
{
"idiom" : "universal",
"filename" : "first.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/first.imageset/._Contents.json
My Contact List/My Contact
List/Assets.xcassets/first.imageset/first.pdf
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/first.imageset/._first.pdf
My Contact List/My Contact List/Assets.xcassets/sample-834-
bolt.imageset/[email protected]
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/sample-834-bolt.imageset/[email protected]
My Contact List/My Contact List/Assets.xcassets/sample-834-
bolt.imageset/Contents.json
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact List/My Contact
List/Assets.xcassets/sample-834-bolt.imageset/._Contents.json
__MACOSX/My Contact List/My Contact
List.xcodeproj/xcuserdata/eierman.xcuserdatad/._xcdebugger
__MACOSX/My Contact List/My Contact
List.xcodeproj/xcuserdata/eierman.xcuserdatad/._xcschemes
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcuserdata/._eierman.xcus e
rdatad
My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspac
eChecks.plist
IDEDidComputeMac32BitWarning
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcshareddata/._IDEWorksp
aceChecks.plist
My Contact
List/.git/objects/51/a3522d1a8251d3583edae3501e30270623b4e
9
My Contact
List/.git/objects/51/a3522d1a8251d3583edae3501e30270623b4e
9
blob 725�//
// ContactsViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/5/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class ContactsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact
List/.git/objects/51/._a3522d1a8251d3583edae3501e30270623b
4e9
My Contact
List/.git/objects/93/d02855d732ed54e9a873ea163c5b0931fd3b2
8
My Contact
List/.git/objects/93/d02855d732ed54e9a873ea163c5b0931fd3b2
8
blob 302�<?xml version="1.0" encoding="UTF-8"
standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel"
documentVersion="1.0" lastSavedToolsVersion="14492.1"
systemVersion="18G87" minimumToolsVersion="Automatic"
sourceLanguage="Swift"
userDefinedModelVersionIdentifier="">
<elements/>
</model>
__MACOSX/My Contact
List/.git/objects/93/._d02855d732ed54e9a873ea163c5b0931fd3b
28
My Contact
List/.git/objects/94/12200eae4ad930a3bda72bb3665ad9b123436
f
My Contact
List/.git/objects/94/12200eae4ad930a3bda72bb3665ad9b123436
f
blob 316�{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact
List/.git/objects/94/._12200eae4ad930a3bda72bb3665ad9b1234
36f
My Contact
List/.git/objects/b2/85dfbdc51b879e840fc0555565f2e481d6c8fe
My Contact
List/.git/objects/b2/85dfbdc51b879e840fc0555565f2e481d6c8fe
blob 715�//
// MapViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/5/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class MapViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact
List/.git/objects/b2/._85dfbdc51b879e840fc0555565f2e481d6c8
fe
My Contact
List/.git/objects/da/4a164c918651cdd1e11dca5cc62c333f097601
My Contact
List/.git/objects/da/4a164c918651cdd1e11dca5cc62c333f097601
blob 62�{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact
List/.git/objects/da/._4a164c918651cdd1e11dca5cc62c333f0976
01
My Contact
List/.git/objects/bd/634d80717757250c9b639ee2bb5417c8185c1
b
My Contact
List/.git/objects/bd/634d80717757250c9b639ee2bb5417c8185c1
b
blob 174�//
// MapPoint.swift
// My Contact List
//
// Created by Michael Eierman on 8/7/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import Foundation
__MACOSX/My Contact
List/.git/objects/bd/._634d80717757250c9b639ee2bb5417c8185
c1b
My Contact
List/.git/objects/d1/6f0eca20c54005e834e7339cc4838a2c904c46
My Contact
List/.git/objects/d1/6f0eca20c54005e834e7339cc4838a2c904c46
blob 725�//
// SettingsViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/5/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class SettingsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact
List/.git/objects/d1/._6f0eca20c54005e834e7339cc4838a2c904c
46
My Contact
List/.git/objects/c0/aa5890be1fe9b6fcc02f93173455ecf442e757
My Contact
List/.git/objects/c0/aa5890be1fe9b6fcc02f93173455ecf442e757
blob 175�//
// Constants.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import Foundation
__MACOSX/My Contact
List/.git/objects/c0/._aa5890be1fe9b6fcc02f93173455ecf442e75
7
My Contact
List/.git/objects/11/12069926cb82235d70c5ca1be944c6f427b2d
8
My Contact
List/.git/objects/11/12069926cb82235d70c5ca1be944c6f427b2d
8
blob 253�{
"images" : [
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact
List/.git/objects/11/._12069926cb82235d70c5ca1be944c6f427b2
d8
My Contact
List/.git/objects/74/bb798c463179d207542c2c0554f5aecf6962d1
My Contact
List/.git/objects/74/bb798c463179d207542c2c0554f5aecf6962d1
blob 717�//
// DateViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class DateViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact
List/.git/objects/74/._bb798c463179d207542c2c0554f5aecf6962
d1
My Contact
List/.git/objects/44/7805c2535443ad8c4487730db74c1667ee634
1
My Contact
List/.git/objects/44/7805c2535443ad8c4487730db74c1667ee634
1
blob 2990�//
// ContactsTableViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class ContactsTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection
between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button
in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem =
self.editButtonItem
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView)
-> Int {
// #warning Incomplete implementation, return the number
of sections
return 0
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number
of rows
return 0
}
/*
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"reuseIdentifier", for: indexPath)
// Configure the cell...
return cell
}
*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView,
canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be
editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit
editingStyle: UITableViewCell.EditingStyle, forRowAt
indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert
it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView,
moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table
view.
override func tableView(_ tableView: UITableView,
canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-
orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact
List/.git/objects/44/._7805c2535443ad8c4487730db74c1667e e6
341
My Contact
List/.git/objects/a9/5798642c33b00826cad4dc9c2d9496a639b86
7
My Contact
List/.git/objects/a9/5798642c33b00826cad4dc9c2d9496a639b86
7
blob 733�//
// LocationDemoViewController.swift
// My Contact List
//
// Created by Michael Eierman on 8/6/19.
// Copyright © 2019 Learning Mobile Apps. All rights
reserved.
//
import UIKit
class LocationDemoViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to
do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
__MACOSX/My Contact
List/.git/objects/a9/._5798642c33b00826cad4dc9c2d9496a639b
867
My Contact
List/.git/objects/f9/2f7cb6f4a02aaeb25 34504bea9569b4983af2a
My Contact
List/.git/objects/f9/2f7cb6f4a02aaeb2534504bea9569b4983af2a
blob 315�{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact
List/.git/objects/f9/._2f7cb6f4a02aaeb2534504bea9569b4983af2
a
My Contact
List/.git/objects/48/c3d8a19a1cfa5de320310c63de76f8c81a7c34
My Contact
List/.git/objects/48/c3d8a19a1cfa5de320310c63de76f8c81a7c34
__MACOSX/My Contact
List/.git/objects/48/._c3d8a19a1cfa5de320310c63de76f8c81a7c
34
My Contact
List/.git/objects/1e/0d01adc6f978d6275e73583222c77d493d5b7
7
My Contact
List/.git/objects/1e/0d01adc6f978d6275e73583222c77d493d5b7
7
__MACOSX/My Contact
List/.git/objects/1e/._0d01adc6f978d6275e73583222c77d493d5b
77
My Contact
List/.git/objects/78/1aca185052a2d2bf29c3616dd99368c4b7e08
8
My Contact
List/.git/objects/78/1aca185052a2d2bf29c3616dd99368c4b7e08
8
blob 359�{
"images" : [
{
"idiom" : "universal",
"filename" : "sample-401-globe.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
__MACOSX/My Contact
List/.git/objects/78/._1aca185052a2d2bf29c3616dd99368c4b7e0
88
My Contact
List/.git/objects/7f/5e4906c3aee1b2c91fa1f684694edb8d21cc4b
My Contact
List/.git/objects/7f/5e4906c3aee1b2c91fa1f684694edb8d21cc4b
__MACOSX/My Contact
List/.git/objects/7f/._5e4906c3aee1b2c91fa1f684694edb8d21cc4
b
My Contact List/My Contact
List.xcodeproj/xcuserdata/fredoseitutu.xcuserdatad/xcschemes/x
cschememanagement.plist
SchemeUserState
My Contact List.xcscheme_^#shared#^_
orderHint
0
My Contact List/My Contact
List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcdebugger/Brea
kpoints_v2.xcbkptlist
__MACOSX/My Contact List/My Contact
List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcdebugger/._Br
eakpoints_v2.xcbkptlist
My Contact List/My Contact
List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcschemes/xcsc
hememanagement.plist
SchemeUserState
My Contact List.xcscheme_^#shared#^_
orderHint
0
__MACOSX/My Contact List/My Contact
List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcschemes/._xcs
chememanagement.plist
My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcuserdata/fredoseitutu.xcu
serdatad/UserInterfaceState.xcuserstate
My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd
atad/.dat.nosync01d8.b0Tmr0
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd
atad/._.dat.nosync01d8.b0Tmr0
My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd
atad/UserInterfaceState.xcuserstate
__MACOSX/My Contact List/My Contact
List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd
atad/._UserInterfaceState.xcuserstate
Pro_Lab 12
1. Add a control to allow the user to change the accuracy setting
for the sensor, and notice how the output changes when moving
about using different settings.
2. The app now has database access code in several view
controllers. To support a cleaner design, add a database access
class that controls all access to Core Data and provides useful
methods and properties to the rest of the app.
3. Turn off the user’s permission to access location for the App
(in the Simulator, go to Settings > Privacy > Location). Run the
app again and observe what happens. Is this appropriate
behavior? How could it be improved?
4. What would happen if the code in Listing 13.10 was placed in
viewDidLoad instead of viewWillAppear? (Check
MapPoint.swift)
5. Change the text displayed on the pin to include the City for
the contact.
6. Change the cell layout to use the other two styles.
7. Expand the settings screen to allow for specifying two sort
fields. Then have the sorting be done by first one and then the
other field.
8. Choose different fields from the Contact class to display in
the table.
9. Change the display in the table to look like this instead: Main
label: Superman from Metropolis. Detail Label: Born on: April
18, 1938.
10. Change the app so when the user taps the + button to add a
new Contact, the Contact screen is put into edit mode and the
cursor placed in the first text field.
lni
David A. Garvin Competing
on the
eight dimensions
of quahty
U.S. managers know that they have to
improve the quality of their products hecause, alas,
U.S. consumers have told them so. A survey in 1981 re-
ported that nearly 50% of U.S. consumers helieved that
the quality of U.S. products had dropped during the
previous five years; more recent surveys have found
that a quarter of consumers are "not at all" confident
that U.S. industry can he depended on to deliver reli-
ahle products. Many companies have tried to upgrade
their quality, adopting programs that have heen staples
of the quality movement for a generation: cost of qual-
ity calculations, interfunctional teams, reliahility engi-
neering, or statistical quality control. Few companies,
however, have leamed to compete on quality. Why?
U.S. consumers doubt that
U.S. companies can
deliver quality.
Part of the prohlem, of course, is that un-
til Japanese and European competition intensified, not
many companies seriously tried to make quality pro-
grams work even as they implemented them. But even
if companies had implemented the traditional princi-
ples of quality control more rigorously, it is douhtful
that U.S. consumers would be satisfied today. In my
David A. Garvin is an associate professor
of business administration at the Harvard Business School .
He has published numerous articles on quahty in HBR and
other iouinals and is the recipient of McKinsey Awards for
best HBR article in 1982 and 1983. This article draws from
his book. Managing Quality, to be pubhshed by Free Press.
view, most of those principles were narrow in scope;
they were designed as purely defensive measures to
preempt failures or eliminate "defects." What man-
agers need now is an aggressive strategy to gain and hold
markets, with high quality as a competitive linchpin.
Quality control
To get a hetter grasp of the defensive
character of traditional quality control, we should un-
derstand what the quality movement in the United
States has achieved so far. How much expense on qual-
ity was tolerahle? How much "quality" was enough?
In 1951, Joseph Juran tackled these questions in the
first edition of his Quahty Control Handbook, a publi-
cation that became the quality movement's bible. Juran
observed that quality could be understood in terms of
avoidable and unavoidable costs: the former resulted
from defects and product failures like scrapped materi -
als or labor hours required for rework, repair, and com-
plaint processing; the latter were associated with pre-
vention, i.e., inspection, sampling, sorting, and other
quahty control initiatives. Juran regarded failure costs
as "gold in the mine" because they could be reduced
sharply by investing in quality improvement. He esti-
mated that avoidable quality losses typically ranged
from $500 to $ 1,000 per productive operator per year -
big money back in the 1950s.
Rcadingjuran's hook, executives inferred
roughly how much to invest in quality improvement:
expenditures on prevention were justified if they were
lower than the costs of product failure. A corollary
principle was that decisions made early in the produc-
tion chain (e.g., when engineers first sketched out a
product's design) have implications for the level of
102 Harvard Business Review November-December 1987
"Ispoke to my attorney today, Wendell, and I'm thinking of
putting you intopiay."
quality costs incurred later, hoth in the factory and the
field.
In 1956, Armand Feigenbaum took
Juran's ideas a step further by proposing "total quality
control" (TQC). Companies would never make high-
quality products, he argued, if the manufacturing de-
partment were forced to pursue quality in isolation.
TQC called for "interfunctional teams" from market-
ing, engineering, purchasing, and manufacturing.
These teams would share responsihility for all phases
of design and manufacturing and would disband only
when they had placed a product in the hands of a satis-
fied customer-who remained satisfied.
Feigenbaum noted that all new prod-
ucts moved through three stages of activity: design con-
trol, incoming material control, and product or shop-
floor control. This was a step in the right direction. But
Feigenhaum did not really consider how quality was
first of all a strategic question for any business; how,
for instance, quality might govern the development of
a design and the choice of features or options. Rather,
design control meant for Feigenbaum mainly prepro-
duction assessments of a new design's manufacturabil-
ity, or that projected manufacturing techniques should
be debugged through pilot runs. Materials control in-
cluded vendor evaluations and incoming inspection
procedures.
In TQC, quality was a kind of burden to
be shared-no single department shouldered all the re-
sponsibility. Top management was ultimately account-
able for the effectiveness of the system; Feigenbaum,
like Juran, proposed careful reporting of the costs of
quality to senior executives in order to
ensure their commitment. The two also
stressed statistical approaches to qual-
ity, including process control charts that
set limits to acceptable variations in
key variables affecting a product's pro-
duction. Tbey endorsed sampling proce-
dures that allowed managers to draw
inferences about the quality of entire
batches of products from the condition
of items in a small, randomly selected
sample.
Despite their attention to
these techniques, furan, Feigenbaum,
and other experts like W. Edwards Dem-
ing were trying to get managers to see
beyond purely statistical controls on
quality. Meanwhile, another branch of
the quality movement emerged, relying
even more heavily on probability theory
and statistics. This was "reliability en-
gineering," which originated in the aero-
space and electronics industries.
In 1950, only one-third of the
U.S. Navy's electronic devices worked
properly A subsequent study by the Rand Corporation
estimated that every vacuum tube the military used
had to be backed by nine others in warehouses or on
order. Reliability engineering addressed these problems
by adapting the laws of probability to the challenge of
predicting equipment stress.
Reliability engineering measures led to;
Techniques for reducing failure rates
while products were still in the design
stage.
Failure mode and effect analysis, which
systematically reviewed how altema-
tive designs could fail.
Individual component analysis, which
computed the failure probability of key
components and aimed to eliminate or
strengthen the weakest links.
Derating, which required that parts be
used below their specified stress levels.
Redundancy, which called for a parallel
system to back up an important compo-
nent or subsystem in case it failed.
Naturally, an effective reliability pro-
gram required managers to monitor field failures close-
ly to give company engineers the information needed
to plan new designs. Effective field failure reporting
Quality dimensions 103
also demanded the development of systems of data col -
lection, including return of failed parts to the labora-
tory for testing and analysis.
Now, the proponents of all these ap-
proaches to quality control might well have denied
that their views of quality were purely defensive. But
what else was implied by the solutions they stressed-
material controls, outgoing batch inspections, stress
tests? Perhaps the best way to see the implications of
their logic is in traditional quality control's most ex-
treme form, a program called "Zero Defects." No other
program defined quality so stringently as an absence of
failures-and no wonder, since it emerged from the de-
fense industries where the product was a missile whose
flawless operation was, for obvious reasons, imperative.
In 1961, the Martin Company was build-
ing Pershing missiles for the U.S. Army. The design of
the missile was sound, but Martin found that it could
maintain high quality only through a massive program
of inspection. It decided to offer workers incentives to
lower the defect rate, and in December 1961, delivered
a Pershing missile to Cape Canaveral with "zero dis-
crepancies." Buoyed by this success, Martin's general
manager in Orlando, Florida accepted a challenge, is-
sued by the U.S. Army's missile command, to deliver
the first field Pershing one month ahead of schedule.
But he went even further. He promised that the missile
would be perfect, with no hardware problems or docu-
ment errors, and that all equipment would be fully op-
erational 10 days after delivery (the norm was 90 days
or more).
Quality means
pleasing consumers,
not just protecting them
from annoyances.
Tvo months of feverish activity fol-
lowed; Martin asked all employees to contribute to
building the missile exactly right the first time since
there would be virtually no time for the usual inspec-
tions. Management worked hard to maintain enthusi-
asm on the plant floor. In February 1962, Martin deliv-
ered on time a perfect missile that was fully operational
in less than 24 hours.
This experience was eye-opening for
both Martin and the rest of the aerospace industry After
careful review, management concluded that, in effect,
its own changed attitude had assured the project's suc-
cess. In the words of one close observer: "The one time
management demanded perfection, it happened!"'
Martin management thereafter told employees that
the only acceptable quality standard was "zero de-
fects." It instilled this principle in the work force
through training, special events, and by posting quality
results. It set goals for workers and put great effort into
giving each worker positive criticism. Formal tech-
niques for problem solving, however, remained lim-
ited. For the most part, the program focused on
motivation-on changing the attitudes of employees.
Strategic quality
management
On the whole, U.S. corporations did not
keep pace with quality control innovations the way a
number of overseas competitors did. Particularly after
World War II, U.S. corporations expanded rapidly and
many became complacent. Managers knew that con-
sumers wouldn't drive a VW Beetle, indestructible as it
was, if they could afford a fancier car-even if this
meant more visits to the repair shop.
But if U.S. car manufacturers had gotten
their products to outlast Beetles, U.S. quality managers
still would not have been prepared for Toyota Corollas
- o r Sony televisions. Indeed, there was nothing in the
principles of quality control to disabuse them of the
idea that quality was merely something that could
hurt a company if ignored; that added quality was the
designer's business-a matter, perhaps, of chrome and
push buttons.
The beginnings of strategic quality
management cannot be dated precisely because no sin-
gle book or article marks its inception. But even more
than in consumer electronics and cars, the volatile
market in semiconductors provides a telling example
of change. In March 1980, Richard W. Anderson, gen-
eral manager of Hewlett-Packard's Data Systems Divi-
sion, reported that after testing 300,000 16K RAM
chips from three U.S. and three Japanese manufactur-
ers, Hewlett-Packard had discovered wide disparities
in quality. At incoming inspection, the Japanese chips
had a failure rate of zero; the comparable rate for the
three U.S. manufacturers was between 11 and 19 fail-
ures per 1,000. After 1,000 hours of use, the failure rate
of the Japanese chips was between 1 and 2 per 1,000;
usable U.S. chips failed up to 27 times per thousand.
Several U.S. semiconductor companies
reacted to the news impulsively, complaining that the
Japanese were sending only their best components to
1 lames EHalpin,
Zero Defects
(New York:
McGraw-Hill, 19661, p. 15.
104 Harvard Business Review November-December 1987
the all-important U.S. market. Others disputed the
basic data. The most perceptive market analysts, how -
ever, noted how differences in quahty coineided with
the rapid ascendancy of Japanese chip manufacturers.
In a few years the Japanese had gone from a standing
start to significant market shares in both the 16K and
64K chip markets. Their message-intentional or n o t -
was that quality could be a potent strategic weapon.
U.S. semiconductor manufacturers got
the message. In 16K chips the quality gap soon closed.
And in industries as diverse as machine tools and ra-
dial tires, each of which had seen its position erode in
the face of Japanese competition, there has been a new
seriousness about quality too. But how to translate
seriousness into action? Managers who are now deter-
mined to compete on quality have been thrown back
on the old questions: How much quality is enough?
What does it take to look at quality from the custom-
er's vantage point? These are still hard questions today.
Some consumer preferences
should be treated as absolute
performance standards.
To achieve quality gains, I believe, man-
agers need a new way of thinking, a conceptual bridge
to the consumer's vantage point. Obviously, market
studies acquire a new importance in this context, as
does a careful review of competitors' products. One
thing is certain: high quality means pleasing consum-
ers, not just protecting them from armoyances. Product
designers, in tum, should shift their attention from
prices at the time of purchase to life cycle costs that in-
clude expenditures on service and maintenance-the
customer's total costs. Even consumer complaints play
a new role hecause they provide a valuable source of
product infonnation.
But managers have to take a more pre-
liminary step-a crucial one, however obvious it may
appear. They must first develop a clear vocahulary with
which to discuss quality as strategy. They must break
down the word quality into manageable parts. Only
then can they define the quality niches in which to
compete.
I propose eight critical dimensions or
categories of quality that can serve as a framework for
strategic analysis: performance, features, reliability,
conformance, durability, serviceabihty, aesthetics, and
perceived quality- Some of these are always mutually
reinforcing; some are not. A product or service can
rank high on one dimension of quality and low on an-
other-indeed, an improvement in one may be achieved
only at the expense of another. It is precisely this inter-
play that makes strategic quality management possi-
ble; the challenge to managers is to compete on select-
ed dimensions.
1 Performance
Of course, perfonnance refers to a prod-
uct's primary operating characteristics. For an auto-
mobile, performance would include traits like acceler-
ation, handling, cruising speed, and comfort; for a
television set, performance means sound and picture
clarity, color, and the abihty to receive distant stations.
In service businesses - say, fast food and airlines-
performanee often means prompt service.
Because this dimension of quality in-
volves measurable attributes, brands can usually be
ranked objectively on individual aspects of perfor-
mance. Overall performance rankings, however, are
more difficult to develop, especially when they involve
benefits that not every consumer needs. A power shov-
el with a capacity of 100 cubic yards per hour will "out-
perform" one with a capacity of 10 cubic yards per
hour. Suppose, however, that the two shovels possessed
the identical capacity-60 cubic yards per h o u r - b u t
achieved it differently: one with a 1-cubic-yard bucket
operating at 60 cyeles per hour, the other with a 2-
cubic-yard bucket operating at 30 cycles per hour. The
capacities of the shovels would then be the same, but
the shovel with the larger bucket could handle mas-
sive boulders while the shovel with the smaller bucket
eould perform precision work. The "superior per-
former" depends entirely on the task.
Some cosmetics wearers judge quality
by a product's resistance to smudging; others, with
more sensitive skin, assess it by how well it leaves skin
ini tat ion-free. A 100-watt light bulb provides greater
eandlepower than a 60-watt bulb, yet few customers
would regard the difference as a measure of quality.
The bulbs simply belong to different performanee
classes. So the question of whether performanee differ-
ences are quality differences may depend on circum-
stantial preferences-but preferences based on func-
tional requirements, not taste.
Some performance standards are based
on subjective preferences, but the preferences are so
universal that they have the force of an objective stan-
dard. The quietness of an automobile's ride is usually
viewed as a direct reflection of its quality. Some people
like a dimmer room, but who wants a noisy car?
2 This framework firs I appeared,
in a preliminary form,
in my ariiele
"Whal Dues'Product Quality' Really Mean?"
Slaiin Management Review, Fall 19S4.
Quality dimensions 105
2 Features
Similar thinking can he applied to fea-
tures, a second dimension of quality that is often a sec-
ondary aspect of performance. Features are the "bells
and whistles" of products and services, those charac-
teristics that supplement their basic functioning. Ex-
amples include free drinks on a plane, permanent-press
cycles on a washing machine, and automatic tuners on
a color television set. The line separating primary
performance characteristics from secondary features is
often difficult to draw. What is crucial, again, is that
features involve objective and measurable attributes;
objective individual needs, not prejudices, affect their
translation into quality differences.
To many customers, of course, superior
quality is less a reflection of the availability of particu-
lar features than of the total number of options avail-
able. Often, choice is quality: buyers may wish to cus-
tomize or personalize tbeir purchases. Fidelity Invest-
ments and other mutual fund operators bave pursued
this more "flexible" approach. By offering their clients
a wide range of funds covering such diverse fields as
health care, technology, and energy-and by then en-
couraging clients to sbift savings among these-tbey
bave virtually tailored investment portfolios.
Employing the latest in flexible manu-
facturing tecbnology, Allen-Bradley customizes starter
motors for its buyers without having to price its prod-
ucts prohibitively. Eine furniture stores offer their cus-
tomers countless variations in fabric and color. Sucb
strategies impose heavy demands on operating manag-
ers; tbey are an aspect of quality likely to grow in im-
portance witb the perfection of flexible manufacturing
tecbnology.
3 Reliability
This dimension reflects tbe probability
of a product malfunctioning or failing within a speci-
fied time period. Among tbe most common measures
of reliability are the mean time to first failure, tbe
mean time between failures, and the failure rate per
unit time. Because these measures require a product to
be in use for a specified period, they are more relevant
to durable goods than to products and services tbat are
consumed instantly.
Reliability normally becomes more im-
portant to consumers as downtime and maintenance
become more expensive. Farmers, for example, are es-
pecially sensitive to downtime during the short harvest
season. Reliable equipment can mean tbe difference
between a good year and spoiled crops. But consumers
in other markets are more attuned than ever to prod-
uct reliability too. Computers and copying machines
certainly compete on tbis basis. And recent market
research sbows that, especially for young women, reli-
ability has become an automobile's most desired attri-
bute. Nor is the govemment, our biggest single con-
sumer, immune. After seeing its expenditures for
major weapons repair jump from $ 7.4 billion in fiscal
year 1980 to $ 14.9 billion in fiscal year 1985, the
Department of Defense has begun cracking down on
contractors whose weapons fail frequently in tbe field.
4 Confonnance
A related dimension of quality is con-
formance, or the degree to wbich a product's design
and operating cbaracteristics meet establisbed stan-
dards. Tbis dimension owes tbe most to the traditional
approaches to quality pioneered by experts like Juran.
All products and services involve speci-
fications of some sort. When new designs or models
are developed, dimensions are set for parts and purity
standards for materials. Tbese specifications are nor -
mally expressed as a target or "center"; deviance from
the center is permitted within a specified range. Be-
cause tbis approach to conformance equates good qual-
ity with operating inside a tolerance band, there is lit-
tle interest in wbether specifications have been met
exactly. Eor the most part, dispersion witbin specifica-
tion limits is ignored.
One drawback of this approach is the
problem of "tolerance stack-up": when two or more
parts are to be fit together, tbe size of their tolerances
often determines bow well they will match. Should
one part fall at a lower limit of its specification, and a
matching part at its upper limit, a tight fit is unlikely.
Even if tbe parts are rated acceptable initially, the link
between them is likely to wear more quickly than one
made from parts whose dimensions have been cen-
tered more exactly.
To address this problem, a more imagi-
native approach to conformance bas emerged. It is
closely associated with Japanese manufacturers and
the work of Genichi Taguchi, a prizewinning Japanese
statistician. Tagucbi begins with tbe idea of "loss func-
tion," a measure of losses from the time a product is
shipped. (These losses include warranty costs, nome-
peating customers, and otber problems resulting from
performance failure.) Tagucbi then compares sucb
losses to two altemative approacbes to quality: on the
one hand, simple confonnance to specifications, and
on tbe other, a measure of tbe degree to whicb parts or
products diverge from tbe ideal target or center.
He demonstrates that "tolerance stack-
up" will be worse-more costly-wben the dimensions
iO6 Harvard Business Review November-December 1987
Exhibit Two approaches to conformance
In the following graphs, shaded areas under the
curves indicate items whose measurements meet
specifications. White areas indicate items not
meeting specifications.
Production process 1
Target Specification
limit
t.45
Iri production process 1 (favored by Taguchi), items dis-
tribute closely around the target, although some items
fall outside specifications.
Production process 2
Target Specification
limit
1.45
in production process 2 (favored in traditional ' '
approaches), items ah distribute within specifications,
but not tightly around the target.
Sourcfl: L.P. Sullivan, "Reducing Variability: A New Approach
to
Duality." Quality Progress. July T984, p. 16.
of parts are more distant from the center than when
they cluster around it, even if some parts fall outside
the tolerance band entirely. According to Taguchi's ap-
proach, production process 1 in the Exhibit is hetter
even though some items fall heyond specification lim-
its. Traditional approaches favor production process 2.
The challenge for quality managers is obvious.
Incidentally, the two most common
measures of failure in conformance-for Taguchi and
everyone else-are defect rates in the factory and, once
a product is in the hands of the customer, the incidence
of service calls. But these measures neglect other devi-
ations from standard, like misspelled lahels or shoddy
construction, that do not lead to service or repair. In
service husinesses, measures of conformance normally
focus on accuracy and timeliness and include counts of
processing errors, unanticipated delays, and other fre-
quent mistakes.
5 Durability
A measure of product life, durability has
both economic and technical dimensions. Technically,
durability can be defined as the amount of use one gets
from a product before it deteriorates. After so many
hours of use, the filament of a light bulb bums up and
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell

More Related Content

Similar to 1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell

Introduction to the integral framework
Introduction to the integral frameworkIntroduction to the integral framework
Introduction to the integral frameworkKarthik Subramanian
 
Hands-On Lab: Improve large network visibility and operational efficiency wit...
Hands-On Lab: Improve large network visibility and operational efficiency wit...Hands-On Lab: Improve large network visibility and operational efficiency wit...
Hands-On Lab: Improve large network visibility and operational efficiency wit...CA Technologies
 
Android apps development
Android apps developmentAndroid apps development
Android apps developmentMonir Zzaman
 
React Hooks Best Practices in 2022.pptx
React Hooks Best Practices in 2022.pptxReact Hooks Best Practices in 2022.pptx
React Hooks Best Practices in 2022.pptxBOSC Tech Labs
 
Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)Fabio Biondi
 
Leverage StandardSetController in Apex and Visualforce
Leverage StandardSetController in Apex and VisualforceLeverage StandardSetController in Apex and Visualforce
Leverage StandardSetController in Apex and VisualforceSalesforce Developers
 
Maintaining sanity in a large redux app
Maintaining sanity in a large redux appMaintaining sanity in a large redux app
Maintaining sanity in a large redux appNitish Kumar
 
Overview of MVC Framework - by software outsourcing company india
Overview of MVC Framework - by software outsourcing company indiaOverview of MVC Framework - by software outsourcing company india
Overview of MVC Framework - by software outsourcing company indiaJignesh Aakoliya
 
Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperVinay Kumar
 
introduction to Angularjs basics
introduction to Angularjs basicsintroduction to Angularjs basics
introduction to Angularjs basicsRavindra K
 
User and group security migration
User and group security migrationUser and group security migration
User and group security migrationAmit Sharma
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4Naga Muruga
 
Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Lou Sacco
 
Enterprise State Management with NGRX/platform
Enterprise State Management with NGRX/platformEnterprise State Management with NGRX/platform
Enterprise State Management with NGRX/platformIlia Idakiev
 
The Workforce Dimensions API (2).pdf
The Workforce Dimensions API (2).pdfThe Workforce Dimensions API (2).pdf
The Workforce Dimensions API (2).pdfRaajRpb1
 

Similar to 1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell (20)

Introduction to the integral framework
Introduction to the integral frameworkIntroduction to the integral framework
Introduction to the integral framework
 
Hands-On Lab: Improve large network visibility and operational efficiency wit...
Hands-On Lab: Improve large network visibility and operational efficiency wit...Hands-On Lab: Improve large network visibility and operational efficiency wit...
Hands-On Lab: Improve large network visibility and operational efficiency wit...
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
Let's react - Meetup
Let's react - MeetupLet's react - Meetup
Let's react - Meetup
 
Android apps development
Android apps developmentAndroid apps development
Android apps development
 
React Hooks Best Practices in 2022.pptx
React Hooks Best Practices in 2022.pptxReact Hooks Best Practices in 2022.pptx
React Hooks Best Practices in 2022.pptx
 
Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)
 
Leverage StandardSetController in Apex and Visualforce
Leverage StandardSetController in Apex and VisualforceLeverage StandardSetController in Apex and Visualforce
Leverage StandardSetController in Apex and Visualforce
 
Maintaining sanity in a large redux app
Maintaining sanity in a large redux appMaintaining sanity in a large redux app
Maintaining sanity in a large redux app
 
Overview of MVC Framework - by software outsourcing company india
Overview of MVC Framework - by software outsourcing company indiaOverview of MVC Framework - by software outsourcing company india
Overview of MVC Framework - by software outsourcing company india
 
Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paper
 
Test
TestTest
Test
 
introduction to Angularjs basics
introduction to Angularjs basicsintroduction to Angularjs basics
introduction to Angularjs basics
 
What is sap security
What is sap securityWhat is sap security
What is sap security
 
User and group security migration
User and group security migrationUser and group security migration
User and group security migration
 
Hello Android
Hello AndroidHello Android
Hello Android
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4
 
Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014
 
Enterprise State Management with NGRX/platform
Enterprise State Management with NGRX/platformEnterprise State Management with NGRX/platform
Enterprise State Management with NGRX/platform
 
The Workforce Dimensions API (2).pdf
The Workforce Dimensions API (2).pdfThe Workforce Dimensions API (2).pdf
The Workforce Dimensions API (2).pdf
 

More from MartineMccracken314

1. Jack is the principal.  Mary is Jacks agent.  Mary enters into
1. Jack is the principal.  Mary is Jacks agent.  Mary enters into1. Jack is the principal.  Mary is Jacks agent.  Mary enters into
1. Jack is the principal.  Mary is Jacks agent.  Mary enters intoMartineMccracken314
 
1. IntroversionScore 11 pts.4 - 22 pts.Feedback Some peop
1. IntroversionScore  11 pts.4 - 22 pts.Feedback Some peop1. IntroversionScore  11 pts.4 - 22 pts.Feedback Some peop
1. IntroversionScore 11 pts.4 - 22 pts.Feedback Some peopMartineMccracken314
 
1. International financial investors are moving funds from Talona
1. International financial investors are moving funds from Talona 1. International financial investors are moving funds from Talona
1. International financial investors are moving funds from Talona MartineMccracken314
 
1. Interventionstreatment· The viral pinkeye does not need any
1. Interventionstreatment· The viral pinkeye does not need any 1. Interventionstreatment· The viral pinkeye does not need any
1. Interventionstreatment· The viral pinkeye does not need any MartineMccracken314
 
1. Introduction and background information about solvatochromism u
1. Introduction and background information about solvatochromism u1. Introduction and background information about solvatochromism u
1. Introduction and background information about solvatochromism uMartineMccracken314
 
1. Integrity, the basic principle of healthcare leadership.Conta
1. Integrity, the basic principle of healthcare leadership.Conta1. Integrity, the basic principle of healthcare leadership.Conta
1. Integrity, the basic principle of healthcare leadership.ContaMartineMccracken314
 
1. Information organized and placed in a logical sequence (10 po
1. Information organized and placed in a logical sequence (10 po1. Information organized and placed in a logical sequence (10 po
1. Information organized and placed in a logical sequence (10 poMartineMccracken314
 
1. In our grant application, we included the following interventio
1. In our grant application, we included the following interventio1. In our grant application, we included the following interventio
1. In our grant application, we included the following interventioMartineMccracken314
 
1. I believe that the protagonist is Nel because she is the one th
1. I believe that the protagonist is Nel because she is the one th1. I believe that the protagonist is Nel because she is the one th
1. I believe that the protagonist is Nel because she is the one thMartineMccracken314
 
1. If the profit from the sale of x units of a product is P =
1. If the profit from the sale of x units of a product is P = 1. If the profit from the sale of x units of a product is P =
1. If the profit from the sale of x units of a product is P = MartineMccracken314
 
1. How does CO2 and other greenhouse gases promote global warmin
1. How does CO2 and other greenhouse gases promote global warmin1. How does CO2 and other greenhouse gases promote global warmin
1. How does CO2 and other greenhouse gases promote global warminMartineMccracken314
 
1. How do you think communication and the role of training address
1. How do you think communication and the role of training address1. How do you think communication and the role of training address
1. How do you think communication and the role of training addressMartineMccracken314
 
1. How brain meets its requirement for its energy in terms of well
1. How brain meets its requirement for its energy in terms of well1. How brain meets its requirement for its energy in terms of well
1. How brain meets its requirement for its energy in terms of wellMartineMccracken314
 
1. Give an introduction to contemporary Chinese art (Talk a little
1. Give an introduction to contemporary Chinese art (Talk a little1. Give an introduction to contemporary Chinese art (Talk a little
1. Give an introduction to contemporary Chinese art (Talk a littleMartineMccracken314
 
1. For this reaction essay is a brief written reaction to the read
1. For this reaction essay is a brief written reaction to the read1. For this reaction essay is a brief written reaction to the read
1. For this reaction essay is a brief written reaction to the readMartineMccracken314
 
1. Find something to negotiate in your personal or professional li
1. Find something to negotiate in your personal or professional li1. Find something to negotiate in your personal or professional li
1. Find something to negotiate in your personal or professional liMartineMccracken314
 
1. FAMILYMy 57 year old mother died after a short illness
1. FAMILYMy 57 year old mother died after a short illness 1. FAMILYMy 57 year old mother died after a short illness
1. FAMILYMy 57 year old mother died after a short illness MartineMccracken314
 
1. Explain the four characteristics of B-DNA structure Differenti
1. Explain the four characteristics of B-DNA structure Differenti1. Explain the four characteristics of B-DNA structure Differenti
1. Explain the four characteristics of B-DNA structure DifferentiMartineMccracken314
 
1. examine three of the upstream impacts of mining. Which of these
1. examine three of the upstream impacts of mining. Which of these1. examine three of the upstream impacts of mining. Which of these
1. examine three of the upstream impacts of mining. Which of theseMartineMccracken314
 
1. Examine Hofstedes model of national culture. Are all four dime
1. Examine Hofstedes model of national culture. Are all four dime1. Examine Hofstedes model of national culture. Are all four dime
1. Examine Hofstedes model of national culture. Are all four dimeMartineMccracken314
 

More from MartineMccracken314 (20)

1. Jack is the principal.  Mary is Jacks agent.  Mary enters into
1. Jack is the principal.  Mary is Jacks agent.  Mary enters into1. Jack is the principal.  Mary is Jacks agent.  Mary enters into
1. Jack is the principal.  Mary is Jacks agent.  Mary enters into
 
1. IntroversionScore 11 pts.4 - 22 pts.Feedback Some peop
1. IntroversionScore  11 pts.4 - 22 pts.Feedback Some peop1. IntroversionScore  11 pts.4 - 22 pts.Feedback Some peop
1. IntroversionScore 11 pts.4 - 22 pts.Feedback Some peop
 
1. International financial investors are moving funds from Talona
1. International financial investors are moving funds from Talona 1. International financial investors are moving funds from Talona
1. International financial investors are moving funds from Talona
 
1. Interventionstreatment· The viral pinkeye does not need any
1. Interventionstreatment· The viral pinkeye does not need any 1. Interventionstreatment· The viral pinkeye does not need any
1. Interventionstreatment· The viral pinkeye does not need any
 
1. Introduction and background information about solvatochromism u
1. Introduction and background information about solvatochromism u1. Introduction and background information about solvatochromism u
1. Introduction and background information about solvatochromism u
 
1. Integrity, the basic principle of healthcare leadership.Conta
1. Integrity, the basic principle of healthcare leadership.Conta1. Integrity, the basic principle of healthcare leadership.Conta
1. Integrity, the basic principle of healthcare leadership.Conta
 
1. Information organized and placed in a logical sequence (10 po
1. Information organized and placed in a logical sequence (10 po1. Information organized and placed in a logical sequence (10 po
1. Information organized and placed in a logical sequence (10 po
 
1. In our grant application, we included the following interventio
1. In our grant application, we included the following interventio1. In our grant application, we included the following interventio
1. In our grant application, we included the following interventio
 
1. I believe that the protagonist is Nel because she is the one th
1. I believe that the protagonist is Nel because she is the one th1. I believe that the protagonist is Nel because she is the one th
1. I believe that the protagonist is Nel because she is the one th
 
1. If the profit from the sale of x units of a product is P =
1. If the profit from the sale of x units of a product is P = 1. If the profit from the sale of x units of a product is P =
1. If the profit from the sale of x units of a product is P =
 
1. How does CO2 and other greenhouse gases promote global warmin
1. How does CO2 and other greenhouse gases promote global warmin1. How does CO2 and other greenhouse gases promote global warmin
1. How does CO2 and other greenhouse gases promote global warmin
 
1. How do you think communication and the role of training address
1. How do you think communication and the role of training address1. How do you think communication and the role of training address
1. How do you think communication and the role of training address
 
1. How brain meets its requirement for its energy in terms of well
1. How brain meets its requirement for its energy in terms of well1. How brain meets its requirement for its energy in terms of well
1. How brain meets its requirement for its energy in terms of well
 
1. Give an introduction to contemporary Chinese art (Talk a little
1. Give an introduction to contemporary Chinese art (Talk a little1. Give an introduction to contemporary Chinese art (Talk a little
1. Give an introduction to contemporary Chinese art (Talk a little
 
1. For this reaction essay is a brief written reaction to the read
1. For this reaction essay is a brief written reaction to the read1. For this reaction essay is a brief written reaction to the read
1. For this reaction essay is a brief written reaction to the read
 
1. Find something to negotiate in your personal or professional li
1. Find something to negotiate in your personal or professional li1. Find something to negotiate in your personal or professional li
1. Find something to negotiate in your personal or professional li
 
1. FAMILYMy 57 year old mother died after a short illness
1. FAMILYMy 57 year old mother died after a short illness 1. FAMILYMy 57 year old mother died after a short illness
1. FAMILYMy 57 year old mother died after a short illness
 
1. Explain the four characteristics of B-DNA structure Differenti
1. Explain the four characteristics of B-DNA structure Differenti1. Explain the four characteristics of B-DNA structure Differenti
1. Explain the four characteristics of B-DNA structure Differenti
 
1. examine three of the upstream impacts of mining. Which of these
1. examine three of the upstream impacts of mining. Which of these1. examine three of the upstream impacts of mining. Which of these
1. examine three of the upstream impacts of mining. Which of these
 
1. Examine Hofstedes model of national culture. Are all four dime
1. Examine Hofstedes model of national culture. Are all four dime1. Examine Hofstedes model of national culture. Are all four dime
1. Examine Hofstedes model of national culture. Are all four dime
 

Recently uploaded

EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxEPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxRaymartEstabillo3
 
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxMULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxAnupkumar Sharma
 
Roles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceRoles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceSamikshaHamane
 
Quarter 4 Peace-education.pptx Catch Up Friday
Quarter 4 Peace-education.pptx Catch Up FridayQuarter 4 Peace-education.pptx Catch Up Friday
Quarter 4 Peace-education.pptx Catch Up FridayMakMakNepo
 
Hierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of managementHierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of managementmkooblal
 
Solving Puzzles Benefits Everyone (English).pptx
Solving Puzzles Benefits Everyone (English).pptxSolving Puzzles Benefits Everyone (English).pptx
Solving Puzzles Benefits Everyone (English).pptxOH TEIK BIN
 
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...Nguyen Thanh Tu Collection
 
Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Celine George
 
ROOT CAUSE ANALYSIS PowerPoint Presentation
ROOT CAUSE ANALYSIS PowerPoint PresentationROOT CAUSE ANALYSIS PowerPoint Presentation
ROOT CAUSE ANALYSIS PowerPoint PresentationAadityaSharma884161
 
Framing an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdf
Framing an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdfFraming an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdf
Framing an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdfUjwalaBharambe
 
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...JhezDiaz1
 
Alper Gobel In Media Res Media Component
Alper Gobel In Media Res Media ComponentAlper Gobel In Media Res Media Component
Alper Gobel In Media Res Media ComponentInMediaRes1
 
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPTECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPTiammrhaywood
 
Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Jisc
 
Gas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxGas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxDr.Ibrahim Hassaan
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for BeginnersSabitha Banu
 
Atmosphere science 7 quarter 4 .........
Atmosphere science 7 quarter 4 .........Atmosphere science 7 quarter 4 .........
Atmosphere science 7 quarter 4 .........LeaCamillePacle
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designMIPLM
 

Recently uploaded (20)

EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxEPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
 
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdfTataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
 
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxMULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
 
Roles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceRoles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in Pharmacovigilance
 
Quarter 4 Peace-education.pptx Catch Up Friday
Quarter 4 Peace-education.pptx Catch Up FridayQuarter 4 Peace-education.pptx Catch Up Friday
Quarter 4 Peace-education.pptx Catch Up Friday
 
Hierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of managementHierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of management
 
Solving Puzzles Benefits Everyone (English).pptx
Solving Puzzles Benefits Everyone (English).pptxSolving Puzzles Benefits Everyone (English).pptx
Solving Puzzles Benefits Everyone (English).pptx
 
9953330565 Low Rate Call Girls In Rohini Delhi NCR
9953330565 Low Rate Call Girls In Rohini  Delhi NCR9953330565 Low Rate Call Girls In Rohini  Delhi NCR
9953330565 Low Rate Call Girls In Rohini Delhi NCR
 
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
 
Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17
 
ROOT CAUSE ANALYSIS PowerPoint Presentation
ROOT CAUSE ANALYSIS PowerPoint PresentationROOT CAUSE ANALYSIS PowerPoint Presentation
ROOT CAUSE ANALYSIS PowerPoint Presentation
 
Framing an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdf
Framing an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdfFraming an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdf
Framing an Appropriate Research Question 6b9b26d93da94caf993c038d9efcdedb.pdf
 
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
 
Alper Gobel In Media Res Media Component
Alper Gobel In Media Res Media ComponentAlper Gobel In Media Res Media Component
Alper Gobel In Media Res Media Component
 
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPTECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
 
Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...
 
Gas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxGas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptx
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for Beginners
 
Atmosphere science 7 quarter 4 .........
Atmosphere science 7 quarter 4 .........Atmosphere science 7 quarter 4 .........
Atmosphere science 7 quarter 4 .........
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-design
 

1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell

  • 1. 1. After reviewing chapters 9, 10, and 11 of the Kotler and Keller text, and using specific information derived from the text, provide a brief comment about each of the following: a. How an organization defines and characterizes its product/service and brand relationships. Include a brief analysis of how this product/service and brand relationship is both positively and negatively affected by co-branding and ingredient branding practices from a brand equity perspective (consider information from pages 142 – 145 of the text). Please use appropriate APA citation and attribution rules for all information sources. [insert the body of the response here] b. How an organization can develop consumer experiences that enhance the vague, abstract, and often complex characteristics of services (consider information from pages 160 – 169 of the text). Please use appropriate APA citation and attribution rules for all information sources. [insert the body of the response here] c. Describe how consumer psychology is influenced by discrepancies in reference prices, price-quality inferences, and unexpected price-endings. Assess the impact of such discrepancies on brand equity to include a statement regarding the risks to the financial success of the organization’s products and services (consider issues covered in pages 175 - 176 of the text). Please use appropriate APA citation and attribution rules for all information sources. [insert the body of the response here] 2. After reading the companion article (Competing on the Eight Dimensions of Quality ); provide a recommendation to a group
  • 2. of executives regarding the importance of considering this information (perhaps review the significance of auditing each dimension alone and then in combination).Please use appropriate APA citation and attribution rules for all information sources. [body of response] 3. After reading the companion article (Viewing Brands in Multiple Dimensions); provide an executive summary for executives regarding the significance to the firm of this information; especially the information contained on page 44 of the article. Please use appropriate APA citation and attribution rules for all information sources. [body of response] The term briefly (or brief) suggests a limit of no more than 500 words per response. References Cited: [use APA style and cite/reference all material used in support of responses provided] __MACOSX/._My Contact List __MACOSX/My Contact List/._My Contact List __MACOSX/My Contact List/._My Contact List.xcodeproj __MACOSX/My Contact List/._.git My Contact List/My Contact List/Constants.swift // // Constants.swift
  • 3. // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import Foundation struct Constants { static let kSortField = "sortField" static let kSortDirectionAscending = "sortDirectionAscending" } __MACOSX/My Contact List/My Contact List/._Constants.swift My Contact List/My Contact List/LocationDemoViewController.swift // // LocationDemoViewController.swift // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit import CoreLocation class LocationDemoViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var txtStreet: UITextField! @IBOutlet weak var txtCity: UITextField!
  • 4. @IBOutlet weak var txtState: UITextField! @IBOutlet weak var lblLatitude: UILabel! @IBOutlet weak var lblLongitude: UILabel! @IBOutlet weak var lblLocationAccuracy: UILabel! @IBOutlet weak var lblHeading: UILabel! @IBOutlet weak var lblHeadingAccuracy: UILabel! @IBOutlet weak var lblAltitude: UILabel! @IBOutlet weak var lblAltitudeAccuracy: UILabel! lazy var geoCoder = CLGeocoder() var locationManager: CLLocationManager! @objc func dismissKeyboard() { //Causes the view (or one of its embedded text fields) to resign the first responder status. view.endEditing(true) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard)) view.addGestureRecognizer(tap) locationManager = CLLocationManager() locationManager.delegate = self locationManager.requestWhenInUseAuthorization() //ask for permission to use location } func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if status == .authorizedWhenInUse {
  • 5. print("Permission granted") } else { print("Permission NOT granted") } } @IBAction func addressToCoordinates(_ sender: Any) { let address = "(txtStreet.text!), (txtCity.text!), (txtState.text!))" geoCoder.geocodeAddressString(address) {(placemarks, error) in self.processAddressResponse(withPlacemarks: placemarks, error: error) } } private func processAddressResponse(withPlacemarks placemarks: [CLPlacemark]?, error: Error?) { if let error = error { print("Geocode Error: (error)") } else { var bestMatch: CLLocation? if let placemarks = placemarks, placemarks.count > 0 { bestMatch = placemarks.first?.location } if let coordinate = bestMatch?.coordinate { lblLatitude.text = String(format: "%gu{00B0}", coordinate.latitude) lblLongitude.text = String(format: "%gu{00B0}", coordinate.longitude) } else { print("Didn't find any matching locations") }
  • 6. } } @IBAction func deviceCoordinates(_ sender: Any) { locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters locationManager.distanceFilter = 100 locationManager.startUpdatingLocation() locationManager.startUpdatingHeading() } override func viewDidDisappear(_ animated: Bool) { locationManager.stopUpdatingLocation() locationManager.stopUpdatingHeading() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.last { let eventDate = location.timestamp let howRecent = eventDate.timeIntervalSinceNow if Double(howRecent) < 15.0 { let coordinate = location.coordinate lblLongitude.text = String(format: "%gu{00B0}", coordinate.longitude) lblLatitude.text = String(format: "%gu{00B0}", coordinate.latitude) lblLocationAccuracy.text = String(format: "%gm", location.horizontalAccuracy) lblAltitude.text = String(format: "%gm", location.altitude) lblAltitudeAccuracy.text = String(format: "%gm", location.verticalAccuracy) } } }
  • 7. func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { if newHeading.headingAccuracy > 0 { let theHeading = newHeading.trueHeading var direction: String switch theHeading { case 225..<315: direction = "W" case 135..<225: direction = "S" case 45..<135: direction = "E" default: direction = "N" } lblHeading.text = String(format: "%gu{00B0} (%@)", theHeading, direction) lblHeadingAccuracy.text = String(format: "%gu{00B0}", newHeading.headingAccuracy) } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { let errorType = error._code == CLError.denied.rawValue ? "Location Permission Denied" : "Unknown Error" let alertController = UIAlertController(title: "Error Getting Location: (errorType)", message: "Error Message: (error.localizedDescription))", preferredStyle: .alert) let actionOK = UIAlertAction(title: "OK", style: .default, handler: nil)
  • 8. alertController.addAction(actionOK) present(alertController, animated: true, completion: nil) } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/My Contact List/._LocationDemoViewController.swift __MACOSX/My Contact List/My Contact List/._MyContactListModel.xcdatamodeld My Contact List/My Contact List/MapViewController.swift // // MapViewController.swi ft // My Contact List // // Created by Michael Eierman on 8/5/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. //
  • 9. import UIKit import MapKit import CoreData class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate { @IBOutlet weak var mapView: MKMapView! @IBOutlet weak var sgmtMapType: UISegmentedControl! var locationManager: CLLocationManager! var contacts:[Contact] = [] override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self locationManager = CLLocationManager() locationManager.delegate = self locationManager.requestWhenInUseAuthorization() // Do any additional setup after loading the view. } @IBAction func mapTypeChanged(_ sender: Any) { switch sgmtMapType.selectedSegmentIndex { case 0: mapView.mapType = .standard case 1: mapView.mapType = .hybrid case 2: mapView.mapType = .satellite default: break } } override func viewWillAppear(_ animated: Bool) { //Get contacts from Core Data
  • 10. let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer.viewContext let request = NSFetchRequest<NSManagedObject>(entityName: "Contact") var fetchedObjects:[NSManagedObject] = [] do { fetchedObjects = try context.fetch(request) } catch let error as NSError { print("Could not fetch. (error), (error.userInfo)") } contacts = fetchedObjects as! [Contact] //remove all annotations self.mapView.removeAnnotations(self.mapView.annotations) //go through all contacts for contact in contacts { //as! [Contact] { let address = "(contact.streetAddress!), (contact.city!) (contact.state!)" //geocoding let geoCoder = CLGeocoder() geoCoder.geocodeAddressString(address) {(placemarks, error) in self.processAddressResponse(contact, withPlacemarks: placemarks, error: error) } } } private func processAddressResponse(_ contact: Contact, withPlacemarks placemarks: [CLPlacemark]?, error: Error?) { if let error = error { print("Geocode Error: (error)") } else {
  • 11. var bestMatch: CLLocation? if let placemarks = placemarks, placemarks.count > 0 { bestMatch = placemarks.first?.location } if let coordinate = bestMatch?.coordinate { let mp = MapPoint(latitude: coordinate.latitude, longitude: coordinate.longitude) mp.title = contact.contactName mp.subtitle = contact.streetAddress mapView.addAnnotation(mp) } else { print("Didn't find any matching locations") } } } @IBAction func findUser(_ sender: Any) { mapView.showAnnotations(mapView.annotations, animated: true) // mapView.showsUserLocation = true // mapView.setUserTrackingMode(.follow, animated: true) } func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { var span = MKCoordinateSpan() span.latitudeDelta = 0.05 span.longitudeDelta = 0.05 let viewRegion = MKCoordinateRegion(center: userLocation.coordinate, span: span) mapView.setRegion(viewRegion, animated: true)
  • 12. // mapView.removeAnnotations(self.mapView.annotations) let mp = MapPoint(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude) mp.title = "You" mp.subtitle = "Are here" mapView.addAnnotation(mp) } /* override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) mapView.setUserTrackingMode(.follow, animated: true) } */ /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/My Contact
  • 13. List/._MapViewController.swift My Contact List/My Contact List/MapPoint.swift // // MapPoint.swift // My Contact List // // Created by Michael Eierman on 8/7/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import Foundation import MapKit ///This is Listing 13.10 class MapPoint: NSObject, MKAnnotation{ var title: String? var subtitle: String? var latitude: Double var longitude: Double var coordinate: CLLocationCoordinate2D { return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } init(latitude: Double, longitude: Double) { self.latitude = latitude self.longitude = longitude } } __MACOSX/My Contact List/My Contact List/._MapPoint.swift
  • 14. __MACOSX/My Contact List/My Contact List/._Assets.xcassets My Contact List/My Contact List/ContactsViewController.swift // // ContactsViewController.swift // My Contact List // // Created by Michael Eierman on 8/5/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit import CoreData class ContactsViewController: UIViewController, UITextFieldDelegate, DateControllerDelegate { var currentContact: Contact? let appDelegate = UIApplication.shared.delegate as! AppDelegate @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var txtName: UITextField! @IBOutlet weak var txtAddress: UITextField! @IBOutlet weak var txtCity: UITextField! @IBOutlet weak var txtState: UITextField! @IBOutlet weak var txtZip: UITextField! @IBOutlet weak var txtCell: UITextField! @IBOutlet weak var txtPhone: UITextField! @IBOutlet weak var txtEmail: UITextField! @IBOutlet weak var lblBirthdate: UILabel! @IBOutlet weak var btnChange: UIButton! @IBOutlet weak var sgmtEditMode: UISegmentedControl!
  • 15. @IBAction func changeEditMode( _ sender: Any) { let textFields: [UITextField] = [txtName, txtAddress, txtCity, txtState, txtZip, txtPhone, txtCell, txtEmail] if sgmtEditMode.selectedSegmentIndex == 0 { for textField in textFields { textField.isEnabled = false textField.borderStyle = UITextField.BorderStyle.none } btnChange.isHidden = true navigationItem.rightBarButtonItem = nil } else if sgmtEditMode.selectedSegmentIndex == 1{ for textField in textFields { textField.isEnabled = true textField.borderStyle = UITextField.BorderStyle.roundedRect } btnChange.isHidden = false navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(self.saveContact)) } } func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { if currentContact == nil { let context = appDelegate.persistentContainer.viewContext currentContact = Contact(context: context) } currentContact?.contactName = txtName.text
  • 16. currentContact?.streetAddress = txtAddress.text currentContact?.city = txtCity.text currentContact?.state = txtState.text currentContact?.zipCode = txtZip.text currentContact?.cellNumber = txtCell.text currentContact?.phoneNumber = txtPhone.text currentContact?.email = txtEmail.text return true } @objc func saveContact() { appDelegate.saveContext() sgmtEditMode.selectedSegmentIndex = 0 changeEditMode(self) } override func viewDidLoad() { super.viewDidLoad() if currentContact != nil { txtName.text = currentContact!.contactName txtAddress.text = currentContact!.streetAddress txtCity.text = currentContact!.city txtState.text = currentContact!.state txtZip.text = currentContact!.zipCode txtPhone.text = currentContact!.phoneNumber txtCell.text = currentContact!.cellNumber txtEmail.text = currentContact!.email let formatter = DateFormatter() formatter.dateStyle = .short if currentContact!.birthday != nil { lblBirthdate.text = formatter.string(from: currentContact!.birthday!) } }
  • 17. self.changeEditMode(self) let textFields: [UITextField] = [txtName, txtAddress, txtCity, txtState, txtZip, txtPhone, txtCell, txtEmail] for textfield in textFields { textfield.addTarget(self, action: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:)), for: UIControl.Event.editingDi dEnd) } } func dateChanged(date: Date) { if currentContact == nil { let context = appDelegate.persistentContainer.viewContext currentContact = Contact(context: context) } currentContact?.birthday = date let formatter = DateFormatter() formatter.dateStyle = .short lblBirthdate.text = formatter.string(from: date) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.registerKeyboardNotifications() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.unregisterKeyboardNotifications() } func registerKeyboardNotifications() {
  • 18. NotificationCenter.default.addObserver(self, selector: #selector(ContactsViewController.keyboardDidShow(notificatio n:)), name: UIResponder.keyboardDidShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(ContactsViewController.keyboardWillHide(notificatio n:)), name: UIResponder.keyboardWillHideNotification, object: nil) } func unregisterKeyboardNotifications() { NotificationCenter.default.removeObserver(self) } @objc func keyboardDidShow(notification: NSNotification) { let userInfo: NSDictionary = notification.userInfo! as NSDictionary let keyboardInfo = userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue let keyboardSize = keyboardInfo.cgRectValue.size // Get the existing contentInset for the scrollView and set the bottom property to //be the height of the keyboard var contentInset = self.scrollView.contentInset contentInset.bottom = keyboardSize.height self.scrollView.contentInset = contentInset self.scrollView.scrollIndicatorInsets = contentInset }
  • 19. @objc func keyboardWillHide(notification: NSNotification) { var contentInset = self.scrollView.contentInset contentInset.bottom = 0 self.scrollView.contentInset = contentInset self.scrollView.scrollIndicatorInsets = UIEdgeInsets.zero } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if(segue.identifier == "segueContactDate"){ let dateController = segue.destination as! DateViewController dateController.delegate = self } } } __MACOSX/My Contact List/My Contact List/._ContactsViewController.swift __MACOSX/My Contact List/My Contact List/._Base.lproj
  • 20. My Contact List/My Contact List/AppDelegate.swift // // AppDelegate.swift // My Contact List // // Created by Michael Eierman on 8/2/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit import CoreData @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. let settings = UserDefaults.standard if settings.string(forKey: Constants.kSortField) == nil { settings.set("city", forKey: Constants.kSortField) } if settings.string(forKey: Constants.kSortDirectionAscending) == nil { settings.set(true, forKey: Constants.kSortDirectionAscending) } settings.synchronize() NSLog("Sort field: %@", settings.string(forKey:
  • 21. Constants.kSortField)!) NSLog("Sort direction: (settings.bool(forKey: Constants.kSortDirectionAscending))") return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. }
  • 22. func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } lazy var persistentContainer: NSPersistentContainer = { /* The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. */ let container = NSPersistentContainer(name: "MyContactListModel") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should // not use this function in a shipping application,
  • 23. although it may be useful during // development. /* Typical reasons for an error here include: * The parent directory does not exist, cannot be created, or disallows writing. * The persistent store is not accessible, due to permissions or data protection when * the device is locked. * The device is out of space. * The store could not be migrated to the current model version. Check the error message to determine what the actual problem was. */ fatalError("Unresolved error (error), (error.userInfo)") } }) return container }() // MARK: - Core Data Saving support func saveContext () { let context = persistentContainer.viewContext if context.hasChanges { do { try context.save() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should // not use this function in a shipping application,
  • 24. although it may be useful during // development. let nserror = error as NSError fatalError("Unresolved error (nserror), (nserror.userInfo)") } } } } __MACOSX/My Contact List/My Contact List/._AppDelegate.swift My Contact List/My Contact List/ContactsTableViewController.swift // // ContactsTableViewController.swift // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit import CoreData class ContactsTableViewController: UITableViewController { // let contacts = ["Jim", "John", "Dana", "Rosie", "Justin", "Jeremy", "Sarah", "Matt", "Joe", "Donald", "Jeff"] var contacts:[NSManagedObject] = []
  • 25. let appDelegate = UIApplication.shared.delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() self.navigationItem.leftBarButtonItem = self.editButtonItem loadDataFromDatabase() } override func viewWillAppear(_ animated: Bool) { loadDataFromDatabase() tableView.reloadData() } func loadDataFromDatabase() { let settings = UserDefaults.standard let sortField = settings.string(forKey: Constants.kSortField) let sortAscending = settings.bool(forKey: Constants.kSortDirectionAscending) //Set up Core Data Context let context = appDelegate.persistentContainer.viewContext //Set up Request let request = NSFetchRequest<NSManagedObject>(entityName: "Contact") //Specify sorting let sortDescriptor = NSSortDescriptor(key: sortField, ascending: sortAscending) let sortDescriptorArray = [sortDescriptor] //to sort by multiple fields, add more sort descriptors to the array request.sortDescriptors = sortDescriptorArray do { contacts = try context.fetch(request) } catch let error as NSError {
  • 26. print("Could not fetch. (error), (error.userInfo)") } } // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return contacts.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ContactsCell", for: indexPath) // Configure the cell... let contact = contacts[indexPath.row] as? Contact cell.textLabel?.text = contact?.contactName cell.detailTextLabel?.text = contact?.city cell.accessoryType = .detailDisclosureButton return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let selectedContact = contacts[indexPath.row] as? Contact let name = selectedContact!.contactName! let actionHandler = { (action:UIAlertAction!) -> Void in let storyboard = UIStoryboard(name: "Main", bundle:
  • 27. nil) let controller = storyboard.instantiateViewController(withIdentifier: "ContactController") as? ContactsViewController controller?.currentContact = selectedContact self.navigationController?.pushViewController(controller!, animated: true) } let alertController = UIAlertController(title: "Contact selected", message: "Selected row: (indexPath.row) ((name))", preferredStyle: .alert) let actionCancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) let actionDetails = UIAlertAction(title: "Show Details", style: .default, handler: actionHandler) alertController.addAction(actionCancel) alertController.addAction(actionDetails) present(alertController, animated: true, completion: nil) } /* // Override to support conditional editing of the table view. override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true }
  • 28. */ override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { // Delete the row from the data source let contact = contacts[indexPath.row] as? Contact let context = appDelegate.persistentContainer.viewContext context.delete(contact!) do { try context.save() } catch { fatalError("Error saving context: (error)") } loadDataFromDatabase() tableView.deleteRows(at: [indexPath], with: .fade) } else if editingStyle == .insert { // Create a new instance of the appropriate class, insert it into the array, //and add a new row to the table view } } /* // Override to support rearranging the table view. override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { } */ /*
  • 29. // Override to support conditional rearranging of the table view. override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the item to be re- orderable. return true } */ /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "EditContact" { let contactController = segue.destination as? ContactsViewController let selectedRow = self.tableView.indexPath(for: sender as! UITableViewCell)?.row let selectedContact = contacts[selectedRow!] as? Contact contactController?.currentContact = selectedContact! } } }
  • 30. __MACOSX/My Contact List/My Contact List/._ContactsTableViewController.swift My Contact List/My Contact List/DateViewController.swift // // DateViewController.swift // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit protocol DateControllerDelegate: class { func dateChanged(date: Date) } class DateViewController: UIViewController { weak var delegate: DateControllerDelegate? @IBOutlet weak var dtpDate: UIDatePicker! override func viewDidLoad() { super.viewDidLoad() let saveButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.save, target: self, action: #selector(saveDate)) self.navigationItem.rightBarButtonItem = saveButton self.title = "Pick Birthdate"
  • 31. } @objc func saveDate(){ self.delegate?.dateChanged(date: dtpDate.date) self.navigationController?.popViewController(animated: true) } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/My Contact List/._DateViewController.swift My Contact List/My Contact List/Info.plist CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER)
  • 32. CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleVersion 1 LSRequiresIPhoneOS NSLocationWhenInUseUsageDescription We need to know where we're at! UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UIStatusBarTintParameters UINavigationBar Style UIBarStyleDefault Translucent UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft
  • 33. UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight __MACOSX/My Contact List/My Contact List/._Info.plist My Contact List/My Contact List/SettingsViewController.swift // // SettingsViewController.swift // My Contact List // // Created by Michael Eierman on 8/5/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class SettingsViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { @IBOutlet weak var swAscending: UISwitch! @IBOutlet weak var pckSortField: UIPickerView! let sortOrderItems: Array<String> = ["contactName", "city", "birthday"]
  • 34. override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. pckSortField.dataSource = self; pckSortField.delegate = self; } override func viewWillAppear(_ animated: Bool) { //set the UI based on values in UserDefaults let settings = UserDefaults.standard swAscending.setOn(settings.bool(forKey: Constants.kSortDirectionAscending), animated: true) let sortField = settings.string(forKey: Constants.kSortField) var i = 0 for field in sortOrderItems { if field == sortField { pckSortField.selectRow(i, inComponent: 0, animated: false) } i += 1 } pckSortField.reloadComponent(0) } @IBAction func sortDirectionChanged(_ sender: Any) { let settings = UserDefaults.standard settings.set(swAscending.isOn, forKey: Constants.kSortDirectionAscending) settings.synchronize() } // MARK: UIPickerViewDelegate Methods
  • 35. // Returns the number of 'columns' to display. func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } // Returns the # of rows in the picker func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return sortOrderItems.count } //Sets the value that is shown for each row in the picker func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return sortOrderItems[row] } //If the user chooses from the pickerview, it calls this function; func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { let sortField = sortOrderItems[row] let settings = UserDefaults.standard settings.set(sortField, forKey: Constants.kSortField) settings.synchronize() } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  • 36. // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/My Contact List/._SettingsViewController.swift My Contact List/My Contact List.xcodeproj/project.pbxproj // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 1E31C16722F9CDBE0072F69E /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E31C16622F9CDBE0072F69E /* Constants.swift */; }; 1E31C18B22F9D0580072F69E /* MyContactListModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1E31C18922F9D0580072F69E /* MyContactListModel.xcdatamodeld */; }; 1E31C18D22F9DC4C0072F69E /* DateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E31C18C22F9DC4C0072F69E /* DateViewController.swift */; }; 1E31C18F22F9E52B0072F69E /* ContactsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E31C18E22F9E52B0072F69E /* ContactsTableViewController.swift */; };
  • 37. 1E31C19122F9FEEB0072F69E /* LocationDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E31C19022F9FEEB0072F69E /* LocationDemoViewController.swift */; }; 1E31C19322FB2ECF0072F69E /* MapPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E31C19222FB2ECF0072F69E /* MapPoint.swift */; }; 1E34AC7B22F4A36C00342F01 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E34AC7A22F4A36C00342F01 /* AppDelegate.swift */; }; 1E34AC8222F4A36C00342F01 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1E34AC8022F4A36C00342F01 /* Main.storyboard */; }; 1E34AC8422F4A36E00342F01 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1E34AC8322F4A36E00342F01 /* Assets.xcassets */; }; 1E34AC8722F4A36E00342F01 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1E34AC8522F4A36E00342F01 /* LaunchScreen.storyboard */; }; 1E34AC8F22F8851A00342F01 /* ContactsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E34AC8E22F8851A00342F01 /* ContactsViewController.swift */; }; 1E34AC9122F8852700342F01 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E34AC9022F8852700342F01 /* SettingsViewController.swift */; }; 1E34AC9322F8853600342F01 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E34AC9222F8853600342F01 /* MapViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1E31C16622F9CDBE0072F69E /* Constants.swift */ = {isa =
  • 38. PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; }; 1E31C18A22F9D0580072F69E /* MyContactListModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MyContactListModel.xcdatamodel; sourceTree = "<group>"; }; 1E31C18C22F9DC4C0072F69E /* DateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateViewController.swift; sourceTree = "<group>"; }; 1E31C18E22F9E52B0072F69E /* ContactsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsTableViewController.swift; sourceTree = "<group>"; }; 1E31C19022F9FEEB0072F69E /* LocationDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationDemoViewController.swift; sourceTree = "<group>"; }; 1E31C19222FB2ECF0072F69E /* MapPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapPoint.swift; sourceTree = "<group>"; }; 1E34AC7722F4A36C00342F01 /* My Contact List.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "My Contact List.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 1E34AC7A22F4A36C00342F01 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 1E34AC8122F4A36C00342F01 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 1E34AC8322F4A36E00342F01 /* Assets.xcassets */ = {isa =
  • 39. PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 1E34AC8622F4A36E00342F01 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 1E34AC8822F4A36E00342F01 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 1E34AC8E22F8851A00342F01 /* ContactsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsViewController.swift; sourceTree = "<group>"; }; 1E34AC9022F8852700342F01 /* SettingsViewController.sw ift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; }; 1E34AC9222F8853600342F01 /* MapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 1E34AC7422F4A36C00342F01 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 1E34AC6E22F4A36C00342F01 = { isa = PBXGroup;
  • 40. children = ( 1E34AC7922F4A36C00342F01 /* My Contact List */, 1E34AC7822F4A36C00342F01 /* Products */, ); sourceTree = "<group>"; }; 1E34AC7822F4A36C00342F01 /* Products */ = { isa = PBXGroup; children = ( 1E34AC7722F4A36C00342F01 /* My Contact List.app */, ); name = Products; sourceTree = "<group>"; }; 1E34AC7922F4A36C00342F01 /* My Contact List */ = { isa = PBXGroup; children = ( 1E34AC7A22F4A36C00342F01 /* AppDelegate.swift */, 1E34AC8022F4A36C00342F01 /* Main.storyboard */, 1E34AC8322F4A36E00342F01 /* Assets.xcassets */, 1E34AC8522F4A36E00342F01 /* LaunchScreen.storyboard */, 1E34AC8822F4A36E00342F01 /* Info.plist */, 1E34AC8E22F8851A00342F01 /* ContactsViewController.swift */, 1E34AC9022F8852700342F01 /* SettingsViewController.swift */, 1E34AC9222F8853600342F01 /* MapViewController.swift */, 1E31C16622F9CDBE0072F69E /* Constants.swift */, 1E31C18922F9D0580072F69E /* MyContactListModel.xcdatamodeld */, 1E31C18C22F9DC4C0072F69E /* DateViewController.swift */, 1E31C18E22F9E52B0072F69E /* ContactsTableViewController.swift */, 1E31C19022F9FEEB0072F69E /* LocationDemoViewController.swift */, 1E31C19222FB2ECF0072F69E /* MapPoint.swift */,
  • 41. ); path = "My Contact List"; sourceTree = "<group>"; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 1E34AC7622F4A36C00342F01 /* My Contact List */ = { isa = PBXNativeTarget; buildConfigurationList = 1E34AC8B22F4A36E00342F01 /* Build configuration list for PBXNativeTarget "My Contact List" */; buildPhases = ( 1E34AC7322F4A36C00342F01 /* Sources */, 1E34AC7422F4A36C00342F01 /* Frameworks */, 1E34AC7522F4A36C00342F01 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "My Contact List"; productName = "My Contact List"; productReference = 1E34AC7722F4A36C00342F01 /* My Contact List.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 1E34AC6F22F4A36C00342F01 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1030; LastUpgradeCheck = 1030; ORGANIZATIONNAME = "Learning Mobile Apps";
  • 42. TargetAttributes = { 1E34AC7622F4A36C00342F01 = { CreatedOnToolsVersion = 10.3; }; }; }; buildConfigurationList = 1E34AC7222F4A36C00342F01 /* Build configuration list for PBXProject "My Contact List" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 1E34AC6E22F4A36C00342F01; productRefGroup = 1E34AC7822F4A36C00342F01 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 1E34AC7622F4A36C00342F01 /* My Contact List */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 1E34AC7522F4A36C00342F01 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 1E34AC8722F4A36E00342F01 /* LaunchScreen.storyboard in Resources */, 1E34AC8422F4A36E00342F01 /* Assets.xcassets in Resources */, 1E34AC8222F4A36C00342F01 /* Main.storyboard in Resources
  • 43. */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 1E34AC7322F4A36C00342F01 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 1E31C16722F9CDBE0072F69E /* Constants.swift in Sources */, 1E34AC9322F8853600342F01 /* MapViewController.swift in Sources */, 1E31C18D22F9DC4C0072F69E /* DateViewController.swift in Sources */, 1E31C18B22F9D0580072F69E /* MyContactListModel.xcdatamodeld in Sources */, 1E31C19122F9FEEB0072F69E /* LocationDemoViewController.swift in Sources */, 1E34AC8F22F8851A00342F01 /* ContactsViewController.swift in Sources */, 1E34AC7B22F4A36C00342F01 /* AppDelegate.swift in Sources */, 1E31C19322FB2ECF0072F69E /* MapPoint.swift in Sources */, 1E31C18F22F9E52B0072F69E /* ContactsTableViewController.swift in Sources */, 1E34AC9122F8852700342F01 /* SettingsViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */
  • 44. 1E34AC8022F4A36C00342F01 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 1E34AC8122F4A36C00342F01 /* Base */, ); name = Main.storyboard; sourceTree = "<group>"; }; 1E34AC8522F4A36E00342F01 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 1E34AC8622F4A36E00342F01 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = "<group>"; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1E34AC8922F4A36E00342F01 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES;
  • 45. CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  • 46. GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 1E34AC8A22F4A36E00342F01 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
  • 47. CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O";
  • 48. VALIDATE_PRODUCT = YES; }; name = Release; }; 1E34AC8C22F4A36E00342F01 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "My Contact List/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = "com.company.versionthree.My-Contact-List"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 1E34AC8D22F4A36E00342F01 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "My Contact List/Info.plis t"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = "com.company.versionthree.My-Contact-List";
  • 49. PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1E34AC7222F4A36C00342F01 /* Build configuration list for PBXProject "My Contact List" */ = { isa = XCConfigurationList; buildConfigurations = ( 1E34AC8922F4A36E00342F01 /* Debug */, 1E34AC8A22F4A36E00342F01 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1E34AC8B22F4A36E00342F01 /* Build configuration list for PBXNativeTarget "My Contact List" */ = { isa = XCConfigurationList; buildConfigurations = ( 1E34AC8C22F4A36E00342F01 /* Debug */, 1E34AC8D22F4A36E00342F01 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ 1E31C18922F9D0580072F69E /* MyContactListModel.xcdatamodeld */ = { isa = XCVersionGroup; children = (
  • 50. 1E31C18A22F9D0580072F69E /* MyContactListModel.xcdatamodel */, ); currentVersion = 1E31C18A22F9D0580072F69E /* MyContactListModel.xcdatamodel */; path = MyContactListModel.xcdatamodeld; sourceTree = "<group>"; versionGroupType = wrapper.xcdatamodel; }; /* End XCVersionGroup section */ }; rootObject = 1E34AC6F22F4A36C00342F01 /* Project object */; } __MACOSX/My Contact List/My Contact List.xcodeproj/._project.pbxproj __MACOSX/My Contact List/My Contact List.xcodeproj/._xcuserdata __MACOSX/My Contact List/My Contact List.xcodeproj/._project.xcworkspace My Contact List/.git/config [core] bare = false repositoryformatversion = 0 filemode = true ignorecase = true precomposeunicode = true logallrefupdates = true __MACOSX/My Contact List/.git/._config
  • 51. __MACOSX/My Contact List/.git/._objects My Contact List/.git/HEAD ref: refs/heads/master __MACOSX/My Contact List/.git/._HEAD __MACOSX/My Contact List/.git/._info My Contact List/.git/description Unnamed repository; edit this file 'description' to name the repository. __MACOSX/My Contact List/.git/._description __MACOSX/My Contact List/.git/._hooks __MACOSX/My Contact List/.git/._refs My Contact List/.git/index __MACOSX/My Contact List/.git/._index __MACOSX/My Contact List/My Contact List/MyContactListModel.xcdatamodeld/._MyContactListModel .xcdatamodel __MACOSX/My Contact List/My Contact List/Assets.xcassets/._sample-881-globe.imageset __MACOSX/My Contact List/My Contact List/Assets.xcassets/._AppIcon.appiconset
  • 52. __MACOSX/My Contact List/My Contact List/Assets.xcassets/._second.imageset __MACOSX/My Contact List/My Contact List/Assets.xcassets/._first.imageset My Contact List/My Contact List/Assets.xcassets/Contents.json { "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/My Contact List/Assets.xcassets/._Contents.json __MACOSX/My Contact List/My Contact List/Assets.xcassets/._sample-834-bolt.imageset My Contact List/My Contact List/Base.lproj/LaunchScreen.storyboard __MACOSX/My Contact List/My Contact List/Base.lproj/._LaunchScreen.storyboard My Contact List/My Contact List/Base.lproj/Main.storyboard __MACOSX/My Contact List/My Contact List/Base.lproj/._Main.storyboard __MACOSX/My Contact List/My Contact List.xcodeproj/xcuserdata/._eierman.xcuserdatad
  • 53. My Contact List/My Contact List.xcodeproj/project.xcworkspace/contents.xcworkspacedata __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/._contents.xcworkspacedata __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/._xcuserdata __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/._xcshareddata __MACOSX/My Contact List/.git/objects/._51 __MACOSX/My Contact List/.git/objects/._93 __MACOSX/My Contact List/.git/objects/._94 __MACOSX/My Contact List/.git/objects/._b2 __MACOSX/My Contact List/.git/objects/._da __MACOSX/My Contact List/.git/objects/._bd __MACOSX/My Contact List/.git/objects/._d1 __MACOSX/My Contact List/.git/objects/._c0 __MACOSX/My Contact List/.git/objects/._pack __MACOSX/My Contact List/.git/objects/._11 __MACOSX/My Contact List/.git/objects/._74 __MACOSX/My Contact List/.git/objects/._44
  • 54. __MACOSX/My Contact List/.git/objects/._info __MACOSX/My Contact List/.git/objects/._a9 __MACOSX/My Contact List/.git/objects/._f9 __MACOSX/My Contact List/.git/objects/._48 __MACOSX/My Contact List/.git/objects/._1e __MACOSX/My Contact List/.git/objects/._78 __MACOSX/My Contact List/.git/objects/._7f My Contact List/.git/info/exclude .DS_Store UserInterfaceState.xcuserstate __MACOSX/My Contact List/.git/info/._exclude My Contact List/.git/hooks/README.sample #!/bin/sh # # Place appropriately named executable hook scripts into this directory # to intercept various actions that git takes. See `git help hooks` for # more information. __MACOSX/My Contact List/.git/hooks/._README.sample __MACOSX/My Contact List/.git/refs/._heads __MACOSX/My Contact List/.git/refs/._tags
  • 55. My Contact List/My Contact List/MyContactListModel.xcdatamodeld/MyContactListModel.x cdatamodel/contents __MACOSX/My Contact List/My Contact List/MyContactListModel.xcdatamodeld/MyContactListModel.x cdatamodel/._contents My Contact List/My Contact List/Assets.xcassets/sa mple-881- globe.imageset/sample-401-globe.png __MACOSX/My Contact List/My Contact List/Assets.xcassets/sample-881-globe.imageset/._sample-401- globe.png My Contact List/My Contact List/Assets.xcassets/sample-881- globe.imageset/[email protected] __MACOSX/My Contact List/My Contact List/Assets.xcassets/sample-881- globe.imageset/[email protected] My Contact List/My Contact List/Assets.xcassets/sample-881- globe.imageset/Contents.json { "images" : [ { "idiom" : "universal", "filename" : "sample-401-globe.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "[email protected]",
  • 56. "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/My Contact List/Assets.xcassets/sample-881-globe.imageset/._Contents.json My Contact List/My Contact List/Assets.xcassets/AppIcon.appiconset/Contents.json { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, {
  • 57. "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "idiom" : "ipad",
  • 58. "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" }, { "idiom" : "ios-marketing", "size" : "1024x1024",
  • 59. "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/My Contact List/Assets.xcassets/AppIcon.appiconset/._Contents.json My Contact List/My Contact List/Assets.xcassets/second.imageset/second.pdf __MACOSX/My Contact List/My Contact List/Assets.xcassets/second.imageset/._second.pdf My Contact List/My Contact List/Assets.xcassets/second.imageset/Contents.json { "images" : [ { "idiom" : "universal", "filename" : "second.pdf" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/My Contact
  • 60. List/Assets.xcassets/second.imageset/._Contents.json My Contact List/My Contact List/Assets.xcassets/first.imageset/Contents.json { "images" : [ { "idiom" : "universal", "filename" : "first.pdf" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/My Contact List/Assets.xcassets/first.imageset/._Contents.json My Contact List/My Contact List/Assets.xcassets/first.imageset/first.pdf __MACOSX/My Contact List/My Contact List/Assets.xcassets/first.imageset/._first.pdf My Contact List/My Contact List/Assets.xcassets/sample-834- bolt.imageset/[email protected] __MACOSX/My Contact List/My Contact List/Assets.xcassets/sample-834-bolt.imageset/[email protected] My Contact List/My Contact List/Assets.xcassets/sample-834- bolt.imageset/Contents.json
  • 61. { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "[email protected]", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/My Contact List/Assets.xcassets/sample-834-bolt.imageset/._Contents.json __MACOSX/My Contact List/My Contact List.xcodeproj/xcuserdata/eierman.xcuserdatad/._xcdebugger __MACOSX/My Contact List/My Contact List.xcodeproj/xcuserdata/eierman.xcuserdatad/._xcschemes __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcuserdata/._eierman.xcus e rdatad My Contact List/My Contact
  • 62. List.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspac eChecks.plist IDEDidComputeMac32BitWarning __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcshareddata/._IDEWorksp aceChecks.plist My Contact List/.git/objects/51/a3522d1a8251d3583edae3501e30270623b4e 9 My Contact List/.git/objects/51/a3522d1a8251d3583edae3501e30270623b4e 9 blob 725�// // ContactsViewController.swift // My Contact List // // Created by Michael Eierman on 8/5/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class ContactsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view.
  • 63. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/.git/objects/51/._a3522d1a8251d3583edae3501e30270623b 4e9 My Contact List/.git/objects/93/d02855d732ed54e9a873ea163c5b0931fd3b2 8 My Contact List/.git/objects/93/d02855d732ed54e9a873ea163c5b0931fd3b2 8 blob 302�<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14492.1" systemVersion="18G87" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> <elements/>
  • 64. </model> __MACOSX/My Contact List/.git/objects/93/._d02855d732ed54e9a873ea163c5b0931fd3b 28 My Contact List/.git/objects/94/12200eae4ad930a3bda72bb3665ad9b123436 f My Contact List/.git/objects/94/12200eae4ad930a3bda72bb3665ad9b123436 f blob 316�{ "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "[email protected]", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/.git/objects/94/._12200eae4ad930a3bda72bb3665ad9b1234
  • 65. 36f My Contact List/.git/objects/b2/85dfbdc51b879e840fc0555565f2e481d6c8fe My Contact List/.git/objects/b2/85dfbdc51b879e840fc0555565f2e481d6c8fe blob 715�// // MapViewController.swift // My Contact List // // Created by Michael Eierman on 8/5/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class MapViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. }
  • 66. */ } __MACOSX/My Contact List/.git/objects/b2/._85dfbdc51b879e840fc0555565f2e481d6c8 fe My Contact List/.git/objects/da/4a164c918651cdd1e11dca5cc62c333f097601 My Contact List/.git/objects/da/4a164c918651cdd1e11dca5cc62c333f097601 blob 62�{ "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/.git/objects/da/._4a164c918651cdd1e11dca5cc62c333f0976 01 My Contact List/.git/objects/bd/634d80717757250c9b639ee2bb5417c8185c1 b My Contact List/.git/objects/bd/634d80717757250c9b639ee2bb5417c8185c1 b blob 174�// // MapPoint.swift // My Contact List // // Created by Michael Eierman on 8/7/19. // Copyright © 2019 Learning Mobile Apps. All rights
  • 67. reserved. // import Foundation __MACOSX/My Contact List/.git/objects/bd/._634d80717757250c9b639ee2bb5417c8185 c1b My Contact List/.git/objects/d1/6f0eca20c54005e834e7339cc4838a2c904c46 My Contact List/.git/objects/d1/6f0eca20c54005e834e7339cc4838a2c904c46 blob 725�// // SettingsViewController.swift // My Contact List // // Created by Michael Eierman on 8/5/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class SettingsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } /* // MARK: - Navigation
  • 68. // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/.git/objects/d1/._6f0eca20c54005e834e7339cc4838a2c904c 46 My Contact List/.git/objects/c0/aa5890be1fe9b6fcc02f93173455ecf442e757 My Contact List/.git/objects/c0/aa5890be1fe9b6fcc02f93173455ecf442e757 blob 175�// // Constants.swift // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import Foundation __MACOSX/My Contact List/.git/objects/c0/._aa5890be1fe9b6fcc02f93173455ecf442e75 7
  • 69. My Contact List/.git/objects/11/12069926cb82235d70c5ca1be944c6f427b2d 8 My Contact List/.git/objects/11/12069926cb82235d70c5ca1be944c6f427b2d 8 blob 253�{ "images" : [ { "idiom" : "universal", "filename" : "[email protected]", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/.git/objects/11/._12069926cb82235d70c5ca1be944c6f427b2 d8 My Contact List/.git/objects/74/bb798c463179d207542c2c0554f5aecf6962d1 My Contact List/.git/objects/74/bb798c463179d207542c2c0554f5aecf6962d1 blob 717�// // DateViewController.swift // My Contact List
  • 70. // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class DateViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/.git/objects/74/._bb798c463179d207542c2c0554f5aecf6962 d1
  • 71. My Contact List/.git/objects/44/7805c2535443ad8c4487730db74c1667ee634 1 My Contact List/.git/objects/44/7805c2535443ad8c4487730db74c1667ee634 1 blob 2990�// // ContactsTableViewController.swift // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class ContactsTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem } // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int {
  • 72. // #warning Incomplete implementation, return the number of sections return 0 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return 0 } /* override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) // Configure the cell... return cell } */ /* // Override to support conditional editing of the table view. override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } */ /* // Override to support editing the table view.
  • 73. override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { // Delete the row from the data source tableView.deleteRows(at: [indexPath], with: .fade) } else if editingStyle == .insert { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } */ /* // Override to support rearranging the table view. override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { } */ /* // Override to support conditional rearranging of the table view. override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the item to be re- orderable. return true } */ /* // MARK: - Navigation // In a storyboard-based application, you will often want to
  • 74. do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/.git/objects/44/._7805c2535443ad8c4487730db74c1667e e6 341 My Contact List/.git/objects/a9/5798642c33b00826cad4dc9c2d9496a639b86 7 My Contact List/.git/objects/a9/5798642c33b00826cad4dc9c2d9496a639b86 7 blob 733�// // LocationDemoViewController.swift // My Contact List // // Created by Michael Eierman on 8/6/19. // Copyright © 2019 Learning Mobile Apps. All rights reserved. // import UIKit class LocationDemoViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad()
  • 75. // Do any additional setup after loading the view. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } __MACOSX/My Contact List/.git/objects/a9/._5798642c33b00826cad4dc9c2d9496a639b 867 My Contact List/.git/objects/f9/2f7cb6f4a02aaeb25 34504bea9569b4983af2a My Contact List/.git/objects/f9/2f7cb6f4a02aaeb2534504bea9569b4983af2a blob 315�{ "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal",
  • 76. "filename" : "[email protected]", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/.git/objects/f9/._2f7cb6f4a02aaeb2534504bea9569b4983af2 a My Contact List/.git/objects/48/c3d8a19a1cfa5de320310c63de76f8c81a7c34 My Contact List/.git/objects/48/c3d8a19a1cfa5de320310c63de76f8c81a7c34 __MACOSX/My Contact List/.git/objects/48/._c3d8a19a1cfa5de320310c63de76f8c81a7c 34 My Contact List/.git/objects/1e/0d01adc6f978d6275e73583222c77d493d5b7 7 My Contact List/.git/objects/1e/0d01adc6f978d6275e73583222c77d493d5b7 7 __MACOSX/My Contact List/.git/objects/1e/._0d01adc6f978d6275e73583222c77d493d5b
  • 77. 77 My Contact List/.git/objects/78/1aca185052a2d2bf29c3616dd99368c4b7e08 8 My Contact List/.git/objects/78/1aca185052a2d2bf29c3616dd99368c4b7e08 8 blob 359�{ "images" : [ { "idiom" : "universal", "filename" : "sample-401-globe.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "[email protected]", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } __MACOSX/My Contact List/.git/objects/78/._1aca185052a2d2bf29c3616dd99368c4b7e0 88 My Contact
  • 78. List/.git/objects/7f/5e4906c3aee1b2c91fa1f684694edb8d21cc4b My Contact List/.git/objects/7f/5e4906c3aee1b2c91fa1f684694edb8d21cc4b __MACOSX/My Contact List/.git/objects/7f/._5e4906c3aee1b2c91fa1f684694edb8d21cc4 b My Contact List/My Contact List.xcodeproj/xcuserdata/fredoseitutu.xcuserdatad/xcschemes/x cschememanagement.plist SchemeUserState My Contact List.xcscheme_^#shared#^_ orderHint 0 My Contact List/My Contact List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcdebugger/Brea kpoints_v2.xcbkptlist __MACOSX/My Contact List/My Contact List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcdebugger/._Br eakpoints_v2.xcbkptlist My Contact List/My Contact List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcschemes/xcsc hememanagement.plist
  • 79. SchemeUserState My Contact List.xcscheme_^#shared#^_ orderHint 0 __MACOSX/My Contact List/My Contact List.xcodeproj/xcuserdata/eierman.xcuserdatad/xcschemes/._xcs chememanagement.plist My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcuserdata/fredoseitutu.xcu serdatad/UserInterfaceState.xcuserstate My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd atad/.dat.nosync01d8.b0Tmr0 __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd atad/._.dat.nosync01d8.b0Tmr0 My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd atad/UserInterfaceState.xcuserstate __MACOSX/My Contact List/My Contact List.xcodeproj/project.xcworkspace/xcuserdata/eierman.xcuserd atad/._UserInterfaceState.xcuserstate
  • 80. Pro_Lab 12 1. Add a control to allow the user to change the accuracy setting for the sensor, and notice how the output changes when moving about using different settings. 2. The app now has database access code in several view controllers. To support a cleaner design, add a database access class that controls all access to Core Data and provides useful methods and properties to the rest of the app. 3. Turn off the user’s permission to access location for the App (in the Simulator, go to Settings > Privacy > Location). Run the app again and observe what happens. Is this appropriate behavior? How could it be improved? 4. What would happen if the code in Listing 13.10 was placed in viewDidLoad instead of viewWillAppear? (Check MapPoint.swift) 5. Change the text displayed on the pin to include the City for the contact. 6. Change the cell layout to use the other two styles. 7. Expand the settings screen to allow for specifying two sort fields. Then have the sorting be done by first one and then the other field. 8. Choose different fields from the Contact class to display in the table. 9. Change the display in the table to look like this instead: Main label: Superman from Metropolis. Detail Label: Born on: April 18, 1938. 10. Change the app so when the user taps the + button to add a new Contact, the Contact screen is put into edit mode and the cursor placed in the first text field.
  • 81. lni David A. Garvin Competing on the eight dimensions of quahty U.S. managers know that they have to improve the quality of their products hecause, alas, U.S. consumers have told them so. A survey in 1981 re- ported that nearly 50% of U.S. consumers helieved that the quality of U.S. products had dropped during the previous five years; more recent surveys have found that a quarter of consumers are "not at all" confident that U.S. industry can he depended on to deliver reli- ahle products. Many companies have tried to upgrade their quality, adopting programs that have heen staples of the quality movement for a generation: cost of qual- ity calculations, interfunctional teams, reliahility engi- neering, or statistical quality control. Few companies, however, have leamed to compete on quality. Why? U.S. consumers doubt that U.S. companies can deliver quality. Part of the prohlem, of course, is that un- til Japanese and European competition intensified, not many companies seriously tried to make quality pro- grams work even as they implemented them. But even if companies had implemented the traditional princi- ples of quality control more rigorously, it is douhtful that U.S. consumers would be satisfied today. In my
  • 82. David A. Garvin is an associate professor of business administration at the Harvard Business School . He has published numerous articles on quahty in HBR and other iouinals and is the recipient of McKinsey Awards for best HBR article in 1982 and 1983. This article draws from his book. Managing Quality, to be pubhshed by Free Press. view, most of those principles were narrow in scope; they were designed as purely defensive measures to preempt failures or eliminate "defects." What man- agers need now is an aggressive strategy to gain and hold markets, with high quality as a competitive linchpin. Quality control To get a hetter grasp of the defensive character of traditional quality control, we should un- derstand what the quality movement in the United States has achieved so far. How much expense on qual- ity was tolerahle? How much "quality" was enough? In 1951, Joseph Juran tackled these questions in the first edition of his Quahty Control Handbook, a publi- cation that became the quality movement's bible. Juran observed that quality could be understood in terms of avoidable and unavoidable costs: the former resulted from defects and product failures like scrapped materi - als or labor hours required for rework, repair, and com- plaint processing; the latter were associated with pre- vention, i.e., inspection, sampling, sorting, and other quahty control initiatives. Juran regarded failure costs as "gold in the mine" because they could be reduced sharply by investing in quality improvement. He esti- mated that avoidable quality losses typically ranged from $500 to $ 1,000 per productive operator per year - big money back in the 1950s.
  • 83. Rcadingjuran's hook, executives inferred roughly how much to invest in quality improvement: expenditures on prevention were justified if they were lower than the costs of product failure. A corollary principle was that decisions made early in the produc- tion chain (e.g., when engineers first sketched out a product's design) have implications for the level of 102 Harvard Business Review November-December 1987 "Ispoke to my attorney today, Wendell, and I'm thinking of putting you intopiay." quality costs incurred later, hoth in the factory and the field. In 1956, Armand Feigenbaum took Juran's ideas a step further by proposing "total quality control" (TQC). Companies would never make high- quality products, he argued, if the manufacturing de- partment were forced to pursue quality in isolation. TQC called for "interfunctional teams" from market- ing, engineering, purchasing, and manufacturing. These teams would share responsihility for all phases of design and manufacturing and would disband only when they had placed a product in the hands of a satis- fied customer-who remained satisfied. Feigenbaum noted that all new prod- ucts moved through three stages of activity: design con- trol, incoming material control, and product or shop- floor control. This was a step in the right direction. But Feigenhaum did not really consider how quality was
  • 84. first of all a strategic question for any business; how, for instance, quality might govern the development of a design and the choice of features or options. Rather, design control meant for Feigenbaum mainly prepro- duction assessments of a new design's manufacturabil- ity, or that projected manufacturing techniques should be debugged through pilot runs. Materials control in- cluded vendor evaluations and incoming inspection procedures. In TQC, quality was a kind of burden to be shared-no single department shouldered all the re- sponsibility. Top management was ultimately account- able for the effectiveness of the system; Feigenbaum, like Juran, proposed careful reporting of the costs of quality to senior executives in order to ensure their commitment. The two also stressed statistical approaches to qual- ity, including process control charts that set limits to acceptable variations in key variables affecting a product's pro- duction. Tbey endorsed sampling proce- dures that allowed managers to draw inferences about the quality of entire batches of products from the condition of items in a small, randomly selected sample. Despite their attention to these techniques, furan, Feigenbaum, and other experts like W. Edwards Dem- ing were trying to get managers to see beyond purely statistical controls on quality. Meanwhile, another branch of the quality movement emerged, relying
  • 85. even more heavily on probability theory and statistics. This was "reliability en- gineering," which originated in the aero- space and electronics industries. In 1950, only one-third of the U.S. Navy's electronic devices worked properly A subsequent study by the Rand Corporation estimated that every vacuum tube the military used had to be backed by nine others in warehouses or on order. Reliability engineering addressed these problems by adapting the laws of probability to the challenge of predicting equipment stress. Reliability engineering measures led to; Techniques for reducing failure rates while products were still in the design stage. Failure mode and effect analysis, which systematically reviewed how altema- tive designs could fail. Individual component analysis, which computed the failure probability of key components and aimed to eliminate or strengthen the weakest links. Derating, which required that parts be used below their specified stress levels. Redundancy, which called for a parallel system to back up an important compo- nent or subsystem in case it failed.
  • 86. Naturally, an effective reliability pro- gram required managers to monitor field failures close- ly to give company engineers the information needed to plan new designs. Effective field failure reporting Quality dimensions 103 also demanded the development of systems of data col - lection, including return of failed parts to the labora- tory for testing and analysis. Now, the proponents of all these ap- proaches to quality control might well have denied that their views of quality were purely defensive. But what else was implied by the solutions they stressed- material controls, outgoing batch inspections, stress tests? Perhaps the best way to see the implications of their logic is in traditional quality control's most ex- treme form, a program called "Zero Defects." No other program defined quality so stringently as an absence of failures-and no wonder, since it emerged from the de- fense industries where the product was a missile whose flawless operation was, for obvious reasons, imperative. In 1961, the Martin Company was build- ing Pershing missiles for the U.S. Army. The design of the missile was sound, but Martin found that it could maintain high quality only through a massive program of inspection. It decided to offer workers incentives to lower the defect rate, and in December 1961, delivered a Pershing missile to Cape Canaveral with "zero dis- crepancies." Buoyed by this success, Martin's general manager in Orlando, Florida accepted a challenge, is-
  • 87. sued by the U.S. Army's missile command, to deliver the first field Pershing one month ahead of schedule. But he went even further. He promised that the missile would be perfect, with no hardware problems or docu- ment errors, and that all equipment would be fully op- erational 10 days after delivery (the norm was 90 days or more). Quality means pleasing consumers, not just protecting them from annoyances. Tvo months of feverish activity fol- lowed; Martin asked all employees to contribute to building the missile exactly right the first time since there would be virtually no time for the usual inspec- tions. Management worked hard to maintain enthusi- asm on the plant floor. In February 1962, Martin deliv- ered on time a perfect missile that was fully operational in less than 24 hours. This experience was eye-opening for both Martin and the rest of the aerospace industry After careful review, management concluded that, in effect, its own changed attitude had assured the project's suc- cess. In the words of one close observer: "The one time management demanded perfection, it happened!"' Martin management thereafter told employees that the only acceptable quality standard was "zero de- fects." It instilled this principle in the work force through training, special events, and by posting quality results. It set goals for workers and put great effort into giving each worker positive criticism. Formal tech-
  • 88. niques for problem solving, however, remained lim- ited. For the most part, the program focused on motivation-on changing the attitudes of employees. Strategic quality management On the whole, U.S. corporations did not keep pace with quality control innovations the way a number of overseas competitors did. Particularly after World War II, U.S. corporations expanded rapidly and many became complacent. Managers knew that con- sumers wouldn't drive a VW Beetle, indestructible as it was, if they could afford a fancier car-even if this meant more visits to the repair shop. But if U.S. car manufacturers had gotten their products to outlast Beetles, U.S. quality managers still would not have been prepared for Toyota Corollas - o r Sony televisions. Indeed, there was nothing in the principles of quality control to disabuse them of the idea that quality was merely something that could hurt a company if ignored; that added quality was the designer's business-a matter, perhaps, of chrome and push buttons. The beginnings of strategic quality management cannot be dated precisely because no sin- gle book or article marks its inception. But even more than in consumer electronics and cars, the volatile market in semiconductors provides a telling example of change. In March 1980, Richard W. Anderson, gen- eral manager of Hewlett-Packard's Data Systems Divi- sion, reported that after testing 300,000 16K RAM chips from three U.S. and three Japanese manufactur- ers, Hewlett-Packard had discovered wide disparities
  • 89. in quality. At incoming inspection, the Japanese chips had a failure rate of zero; the comparable rate for the three U.S. manufacturers was between 11 and 19 fail- ures per 1,000. After 1,000 hours of use, the failure rate of the Japanese chips was between 1 and 2 per 1,000; usable U.S. chips failed up to 27 times per thousand. Several U.S. semiconductor companies reacted to the news impulsively, complaining that the Japanese were sending only their best components to 1 lames EHalpin, Zero Defects (New York: McGraw-Hill, 19661, p. 15. 104 Harvard Business Review November-December 1987 the all-important U.S. market. Others disputed the basic data. The most perceptive market analysts, how - ever, noted how differences in quahty coineided with the rapid ascendancy of Japanese chip manufacturers. In a few years the Japanese had gone from a standing start to significant market shares in both the 16K and 64K chip markets. Their message-intentional or n o t - was that quality could be a potent strategic weapon. U.S. semiconductor manufacturers got the message. In 16K chips the quality gap soon closed. And in industries as diverse as machine tools and ra- dial tires, each of which had seen its position erode in the face of Japanese competition, there has been a new seriousness about quality too. But how to translate seriousness into action? Managers who are now deter-
  • 90. mined to compete on quality have been thrown back on the old questions: How much quality is enough? What does it take to look at quality from the custom- er's vantage point? These are still hard questions today. Some consumer preferences should be treated as absolute performance standards. To achieve quality gains, I believe, man- agers need a new way of thinking, a conceptual bridge to the consumer's vantage point. Obviously, market studies acquire a new importance in this context, as does a careful review of competitors' products. One thing is certain: high quality means pleasing consum- ers, not just protecting them from armoyances. Product designers, in tum, should shift their attention from prices at the time of purchase to life cycle costs that in- clude expenditures on service and maintenance-the customer's total costs. Even consumer complaints play a new role hecause they provide a valuable source of product infonnation. But managers have to take a more pre- liminary step-a crucial one, however obvious it may appear. They must first develop a clear vocahulary with which to discuss quality as strategy. They must break down the word quality into manageable parts. Only then can they define the quality niches in which to compete. I propose eight critical dimensions or categories of quality that can serve as a framework for strategic analysis: performance, features, reliability, conformance, durability, serviceabihty, aesthetics, and
  • 91. perceived quality- Some of these are always mutually reinforcing; some are not. A product or service can rank high on one dimension of quality and low on an- other-indeed, an improvement in one may be achieved only at the expense of another. It is precisely this inter- play that makes strategic quality management possi- ble; the challenge to managers is to compete on select- ed dimensions. 1 Performance Of course, perfonnance refers to a prod- uct's primary operating characteristics. For an auto- mobile, performance would include traits like acceler- ation, handling, cruising speed, and comfort; for a television set, performance means sound and picture clarity, color, and the abihty to receive distant stations. In service businesses - say, fast food and airlines- performanee often means prompt service. Because this dimension of quality in- volves measurable attributes, brands can usually be ranked objectively on individual aspects of perfor- mance. Overall performance rankings, however, are more difficult to develop, especially when they involve benefits that not every consumer needs. A power shov- el with a capacity of 100 cubic yards per hour will "out- perform" one with a capacity of 10 cubic yards per hour. Suppose, however, that the two shovels possessed the identical capacity-60 cubic yards per h o u r - b u t achieved it differently: one with a 1-cubic-yard bucket operating at 60 cyeles per hour, the other with a 2- cubic-yard bucket operating at 30 cycles per hour. The capacities of the shovels would then be the same, but the shovel with the larger bucket could handle mas-
  • 92. sive boulders while the shovel with the smaller bucket eould perform precision work. The "superior per- former" depends entirely on the task. Some cosmetics wearers judge quality by a product's resistance to smudging; others, with more sensitive skin, assess it by how well it leaves skin ini tat ion-free. A 100-watt light bulb provides greater eandlepower than a 60-watt bulb, yet few customers would regard the difference as a measure of quality. The bulbs simply belong to different performanee classes. So the question of whether performanee differ- ences are quality differences may depend on circum- stantial preferences-but preferences based on func- tional requirements, not taste. Some performance standards are based on subjective preferences, but the preferences are so universal that they have the force of an objective stan- dard. The quietness of an automobile's ride is usually viewed as a direct reflection of its quality. Some people like a dimmer room, but who wants a noisy car? 2 This framework firs I appeared, in a preliminary form, in my ariiele "Whal Dues'Product Quality' Really Mean?" Slaiin Management Review, Fall 19S4. Quality dimensions 105 2 Features
  • 93. Similar thinking can he applied to fea- tures, a second dimension of quality that is often a sec- ondary aspect of performance. Features are the "bells and whistles" of products and services, those charac- teristics that supplement their basic functioning. Ex- amples include free drinks on a plane, permanent-press cycles on a washing machine, and automatic tuners on a color television set. The line separating primary performance characteristics from secondary features is often difficult to draw. What is crucial, again, is that features involve objective and measurable attributes; objective individual needs, not prejudices, affect their translation into quality differences. To many customers, of course, superior quality is less a reflection of the availability of particu- lar features than of the total number of options avail- able. Often, choice is quality: buyers may wish to cus- tomize or personalize tbeir purchases. Fidelity Invest- ments and other mutual fund operators bave pursued this more "flexible" approach. By offering their clients a wide range of funds covering such diverse fields as health care, technology, and energy-and by then en- couraging clients to sbift savings among these-tbey bave virtually tailored investment portfolios. Employing the latest in flexible manu- facturing tecbnology, Allen-Bradley customizes starter motors for its buyers without having to price its prod- ucts prohibitively. Eine furniture stores offer their cus- tomers countless variations in fabric and color. Sucb strategies impose heavy demands on operating manag- ers; tbey are an aspect of quality likely to grow in im- portance witb the perfection of flexible manufacturing tecbnology.
  • 94. 3 Reliability This dimension reflects tbe probability of a product malfunctioning or failing within a speci- fied time period. Among tbe most common measures of reliability are the mean time to first failure, tbe mean time between failures, and the failure rate per unit time. Because these measures require a product to be in use for a specified period, they are more relevant to durable goods than to products and services tbat are consumed instantly. Reliability normally becomes more im- portant to consumers as downtime and maintenance become more expensive. Farmers, for example, are es- pecially sensitive to downtime during the short harvest season. Reliable equipment can mean tbe difference between a good year and spoiled crops. But consumers in other markets are more attuned than ever to prod- uct reliability too. Computers and copying machines certainly compete on tbis basis. And recent market research sbows that, especially for young women, reli- ability has become an automobile's most desired attri- bute. Nor is the govemment, our biggest single con- sumer, immune. After seeing its expenditures for major weapons repair jump from $ 7.4 billion in fiscal year 1980 to $ 14.9 billion in fiscal year 1985, the Department of Defense has begun cracking down on contractors whose weapons fail frequently in tbe field. 4 Confonnance A related dimension of quality is con- formance, or the degree to wbich a product's design and operating cbaracteristics meet establisbed stan-
  • 95. dards. Tbis dimension owes tbe most to the traditional approaches to quality pioneered by experts like Juran. All products and services involve speci- fications of some sort. When new designs or models are developed, dimensions are set for parts and purity standards for materials. Tbese specifications are nor - mally expressed as a target or "center"; deviance from the center is permitted within a specified range. Be- cause tbis approach to conformance equates good qual- ity with operating inside a tolerance band, there is lit- tle interest in wbether specifications have been met exactly. Eor the most part, dispersion witbin specifica- tion limits is ignored. One drawback of this approach is the problem of "tolerance stack-up": when two or more parts are to be fit together, tbe size of their tolerances often determines bow well they will match. Should one part fall at a lower limit of its specification, and a matching part at its upper limit, a tight fit is unlikely. Even if tbe parts are rated acceptable initially, the link between them is likely to wear more quickly than one made from parts whose dimensions have been cen- tered more exactly. To address this problem, a more imagi- native approach to conformance bas emerged. It is closely associated with Japanese manufacturers and the work of Genichi Taguchi, a prizewinning Japanese statistician. Tagucbi begins with tbe idea of "loss func- tion," a measure of losses from the time a product is shipped. (These losses include warranty costs, nome- peating customers, and otber problems resulting from performance failure.) Tagucbi then compares sucb losses to two altemative approacbes to quality: on the
  • 96. one hand, simple confonnance to specifications, and on tbe other, a measure of tbe degree to whicb parts or products diverge from tbe ideal target or center. He demonstrates that "tolerance stack- up" will be worse-more costly-wben the dimensions iO6 Harvard Business Review November-December 1987 Exhibit Two approaches to conformance In the following graphs, shaded areas under the curves indicate items whose measurements meet specifications. White areas indicate items not meeting specifications. Production process 1 Target Specification limit t.45 Iri production process 1 (favored by Taguchi), items dis- tribute closely around the target, although some items fall outside specifications. Production process 2 Target Specification limit 1.45
  • 97. in production process 2 (favored in traditional ' ' approaches), items ah distribute within specifications, but not tightly around the target. Sourcfl: L.P. Sullivan, "Reducing Variability: A New Approach to Duality." Quality Progress. July T984, p. 16. of parts are more distant from the center than when they cluster around it, even if some parts fall outside the tolerance band entirely. According to Taguchi's ap- proach, production process 1 in the Exhibit is hetter even though some items fall heyond specification lim- its. Traditional approaches favor production process 2. The challenge for quality managers is obvious. Incidentally, the two most common measures of failure in conformance-for Taguchi and everyone else-are defect rates in the factory and, once a product is in the hands of the customer, the incidence of service calls. But these measures neglect other devi- ations from standard, like misspelled lahels or shoddy construction, that do not lead to service or repair. In service husinesses, measures of conformance normally focus on accuracy and timeliness and include counts of processing errors, unanticipated delays, and other fre- quent mistakes. 5 Durability A measure of product life, durability has both economic and technical dimensions. Technically, durability can be defined as the amount of use one gets from a product before it deteriorates. After so many hours of use, the filament of a light bulb bums up and