Recent Posts

Pages: 1 ... 8 9 [10]
91
Book 2: Learn to Code in Swift / "Buggy" video clips at the end of the chapters
« Last post by lundzern on January 24, 2016, 08:14:17 AM »
I'm just at chapter 4 in the book but the video at the end of this chapter is full of glitches.

At some points in the video, the image on the screen is distorted every 3 seconds which more or less renders the video useless. This is annoying because the videos are really useful (when they work).
I like to view the video before reading the chapter, that helps me avoid stupid mistakes when reading through the chapter afterwards.

Has anyone else notices this? I'm on a 27" iMac.

A little off topic but there are two other issues I have noticed so far; the first one is with the book not being able to have a two-page view. Is this normal? I contacted Apple support which were not able to help me sort this out. Any of the other books in my iBooks library can display two pages at the same time, just not this book.

Also, when downloading the sample code I found that the Swift Demo in chapter 3 already contained all the code that we are supposed to enter during that chapter. I found that a little confusing. In fact, it contained even more code then what is taught in chapter 3.

Thanks for any help :)
92
FAQs / How To Test if Running on iOS, watchOS or tvOS
« Last post by kjmcneish on January 19, 2016, 07:31:29 PM »
You can use the following conditional compilation statements along with the os() function to determine if your app is running on iOS, watchOS, or tvOS.

In Swift:

Code: [Select]
#if os(iOS)
           
#elseif os(watchOS)
           
#elseif os(tvOS)
           
#endif

In Objective-C:

Code: [Select]
#ifdef TARGET_OS_IOS
   
#elif TARGET_OS_WATCHOS
   
#elif TARGET_OS_TV
   
#endif

All the best!
Kevin McNeish
Author of Learn to Code in Swift: https://itunes.apple.com/us/book/learn-to-code-in-swift/id942956811?mt=11
Check out our Robot Tic-Tac-Toe app: https://itunes.apple.com/us/app/robot-tic-tac-toe/id990638517?mt=8
93
Book 3: Mastering Xcode and Swift / Re: mmBiz, Relationships & other musings.
« Last post by Carlos_Lema on January 19, 2016, 05:09:49 PM »
Thanks Kevin!

Hope all is well in the sunny side of the world.

Here we go, I am sure it is something super obvious, but I just can't see it. best, \\ carlos
94
When creating a universal app that runs on multiple platforms such as iOS, watchOS, and tvOS you should reuse as much of your app's code as possible, including Core Data.

However, there are some specific steps you need to take to access a single Data Model from multiple projects, to avoid the infamous error "Unable to load class named 'X' for entity 'X'. Class not found, using default NSManagedObject instead."

Here are the main steps:

1. Add the Data Model to the project that contains your Core Data code.

2. If you have separated each of your app's (iOS, watchOS, tvOS) user interface into a separate project (I recommend you do), you need to add a reference to the Data Model in each project's Compile Sources in the Project Editor.

3. In the Data Model, select each entity, go to the Data Model Inspector and make sure the Module setting is blank.

4. In each generated entity class file, add the @objc attribute. For example:

Code: [Select]
import Foundation
import CoreData

@objc(SettingsEntity)
public class SettingsEntity: NSManagedObject {
}

Now you can access the entities from any of your Xcode projects!

All the best!
Kevin McNeish
Author of Learn to Code in Swift: https://itunes.apple.com/us/book/learn-to-code-in-swift/id942956811?mt=11
Check out our Robot Tic-Tac-Toe app: https://itunes.apple.com/us/app/robot-tic-tac-toe/id990638517?mt=8
95
Book 3: Mastering Xcode and Swift / Re: mmBiz, Relationships & other musings.
« Last post by kjmcneish on January 19, 2016, 01:07:25 PM »
Carlos,

Can you send compress and send me a copy of your project (you can attach it your reply) so I can better answer your questions?

All the best!
Kevin
96
Book 3: Mastering Xcode and Swift / mmBiz, Relationships & other musings.
« Last post by Carlos_Lema on January 18, 2016, 09:01:44 AM »
Hi Kevin,

Thanks for Mastering Xcode 7 & Swift and your written clarity. I am new to Swift & iOS but not new to programming or app Dev -- AngularJS, Cordova, jQuery, HTML, PHP, SQL, noSQL, JSON, ActionScript.

After going through most of the Book's examples, I am trying to implement a basic "ToDo List" based on iDeliverMobileCD & ToDoListDemo. I got it to work, but I don't think the code below is correct. I am using the Master List template. mmBizObj, ABizObj, DataModel and EntitiesBizControllers are somewhat "set."

Conceptually, the app loads and displays a List from an array that comes from the DB via mmBizObj CoreData's wrapper. When I select a MasterView row it loads the DetailView with only the Task Array associated with this entity only -- is this correct? Feels very RDBMS.

Relationships with mmBizObj & CoreData is not getting through plus I have several questions and a bunch of concepts that I would welcome some clarification.

Q1. When do the ListEntity's "tasks" NSSet gets populated? or does ListEntity remain clueless and it simply trickles up the chain? isn't this like a SQL join?

// Concepts:
Q2. All CRUD functions only take place in the Entity Business Controller, yes? this separation of responsibility is it considered MVVM?

Q3. Can the mmBiZObj be in the backgroundContext? -- I understand that CRUD must happen in the same Context to avoid confusing CoreData.

Q4. I know am getting ahead of myself, ReactiveCocoa/RxReactive sounds seductive, could mmBiZObj peacefully coexist? I couldn't find your POV article on ReactiveCocoa.

Q5. Ohh yeah, can I use mmBiZObj or a variation of thereof in a production app?


// SET UP

ListEntity
    @NSManaged var listName: String
    @NSManaged var tasks: NSSet?

TaskEntity
    @NSManaged var taskName: String
    @NSManaged var taskStatus: NSNumber
    @NSManaged var list: ListEntity

// ZE BIZCONTROLLERS:
class List<T: ListEntity>: ABusinessObject<T> {
   
    // the List
     var listEntity: Array<T>!
   
    override init() {
        super.init()
    }
   
    func getAllListEntities() -> Array<T> {
       self.listEntity = self.getAllEntities()
        return self.listEntity
    }
   
   
    // MARK: - CD
    // TODO: - CRUD
    func addItemToList(desc: String) -> ListEntity {
       
        // Create New Entity & Populate
        let newListEntity = self.createEntity()
            newListEntity.listName = desc

        // Save to array
        self.listEntity.append(newListEntity)
       
        // Seve to Database
        self.saveEntities()
       
    return newListEntity
    }
   
    // Remove the object at index
    func removeObjectAtIndexPath(indexPath: NSIndexPath) {
        self.listEntity.removeAtIndex(indexPath.row)
        self.saveEntities() // why is not
    }
   
    // Remove Entity
    override func deleteEntity(entity: T) {
        self.deleteEntity(entity)
//        super.deleteEntity(entity)
        self.saveEntities()
    }
   
   
}


class Task<T: TaskEntity>: ABusinessObject<T> {
   
    // Tasks
    var taskEntity: Array<T>!
   
    // MARK: - CD
    // TODO: - CRUD
    func addItemToTask(taskName: String, status: Bool, list: ListEntity?) -> TaskEntity {
       
        // Create entity & Populate
        let newTaskEntity = self.createEntity()
            newTaskEntity.taskName = taskName
            newTaskEntity.taskStatus = status
            newTaskEntity.list = list
       
        // Insert into array... Crash, unwrapping an Optional value??
        self.taskEntity.append(newTaskEntity)

        // Seve to dB
        self.saveEntities()
       
        // return Array
        return newTaskEntity
    }
   
    // Get all items for this List
    func getTasksforList(listEntity: ListEntity) -> Array<T> {
        let predicate = NSPredicate(format: "list = %@", listEntity)
        return self.getEntitiesMatchingPredicate(predicate)
    }
   
   
    func getAllTaskEntities() -> Array<T> {
        self.taskEntity = self.getAllEntities()
        return self.taskEntity
    }

}


// ZE VIEWS

// Master View:
class MasterViewController: UITableViewController {

    var detailViewController: DetailViewController? = nil
   
    // The List's Business Controller
    var list = List()

    // Managed Object
    var listEntity: ListEntity!
       
    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.leftBarButtonItem = self.editButtonItem()
       
        self.list.getAllListEntities()
       
        // Add btn.
        let addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "insertNewObject:")
        self.navigationItem.rightBarButtonItem = addButton
       
        // 6+/iPad UI
        if let split = self.splitViewController {
            let controllers = split.viewControllers
            self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }

    override func viewWillAppear(animated: Bool) {
        self.clearsSelectionOnViewWillAppear = self.splitViewController!.collapsed
        super.viewWillAppear(animated)
    }
   
    // MARK: - Insert func
    func insertNewObject(sender: AnyObject) {
       
        self.list.addItemToList("Absolutely") // Manual insert
       
        // find where to insert the new row
        let indexPath = NSIndexPath(forRow: (self.list.listEntity.count-1), inSection: 0)
       
        // show UI insertion
        self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
    }

    // MARK: - Segues
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDetail" {
       
            // which row did you select?
            if let indexPath = self.tableView.indexPathForSelectedRow {
                let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
                controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
                controller.navigationItem.leftItemsSupplementBackButton = true
               
                // Pass the Selected Entity
                controller.selectedListEntity = self.list.listEntity[indexPath.row]
            }
        }
    }

    // MARK: - Table View
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.list.listEntity.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
            cell.textLabel?.text = self.list.listEntity[indexPath.row].listName
        return cell
    }

    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
           
            // why remove again?
            self.list.removeObjectAtIndexPath(indexPath)

            // delete Entity, why again??? -- Crash. invalid #rows
//            self.list.deleteEntity(self.list.listEntity[indexPath.row])
           
            // UI show removal -- Crash. invalid #rows
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

           
        } 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.
        }
    }


}


// Detail View
class DetailViewController: UIViewController {

    @IBOutlet weak var detailDescriptionLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!
   
    // Ze List
    var selectedListEntity: ListEntity!

    // Business controller
    var task = Task()
   
    override func viewDidLoad() {
        super.viewDidLoad()
       
//        self.configureView()

        // Share the List & Task Context
        self.task.managedObjectContext = self.selectedListEntity.managedObjectContext!
       
        // Get only this List Task Entities
        self.task.getTasksforList(selectedListEntity)
    }
   
   
    @IBAction func addTask(sender: AnyObject) {
       
        // Add to the DB
        self.task.addItemToTask("Another Manual Insert", status: false, list: selectedListEntity)
       
        // Where to Insert Row
        let indexPath = NSIndexPath(forRow: (self.task.taskEntity.count-1), inSection: 0)
       
//         insert UI
        self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
       
        // Array into an NSSet...???
//        self.selectedListEntity.tasks = self.task.taskEntity
    }

    // TODO: - Clean up
    var detailItem: AnyObject? {
        didSet {
            // Update the view.
            self.configureView()
        }
    }

    func configureView() {
        // Update the user interface for the detail item.
        if let detail = self.detailItem {
            if let label = self.detailDescriptionLabel {
                label.text = detail.description
            }
        }
    }

    // MARK: - Table View
     func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
   
     func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        // Might be empty
        if let tasks = self.task.taskEntity {
            return tasks.count
        }
        return 0
    }
   
     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("taskCell", forIndexPath: indexPath)
            cell.textLabel?.text = self.task.taskEntity[indexPath.row].taskName
        return cell
    }
   

}
97
Me, too.  Exactly the same problem, and restarting Xcode fixed it.  Many thanks!

Paul
98
Book 2: Learn to Code in Swift / Re: TuplesDemo has 2 errors
« Last post by kjmcneish on December 19, 2015, 01:18:04 AM »
Steven,

Sorry for the delay! The forum is supposed to send me a message when a new post is added, but it didn't. Anyway, try it again now...it should work fine.

Thanks,
Kevin
99
Book 2: Learn to Code in Swift / Re: TuplesDemo has 2 errors
« Last post by shx on December 07, 2015, 10:07:45 AM »
Still not working.

Please let me know if it is just me or the code has to be fixed.

Thanks
Steven
100
Book 2: Learn to Code in Swift / Re: Not in book Can you help
« Last post by kjmcneish on December 04, 2015, 09:25:25 PM »
You can just call the method directly from viewDidLoad:

Code: [Select]
override func viewDidLoad() {
        super.viewDidLoad()
       
       self.TurnOnLabel(self.Label)
}

P.S. Typically, method names should be camel cased (turnOnLabel rather than TurnOnLabel)

All the best!
Kevin
Pages: 1 ... 8 9 [10]