I am new to Objective C and Swift. I have created a SampleTest project in Swift.. While creating a ViewController.xib we need to give the reference class in identity inspector which is contain in right side pane in xcode.
ViewController denotes the ViewController.swift module and Here what it denotes _TtC10SampleTest14ViewController in class field.
_TtC10SampleTest14ViewController is the mangled name of your ViewController, swift using Name Mangling .
1. Read more about name mangling in this article
2.
Check the related answer also
Related
I have a table data and images to assets folder.
I need to bind image by name from assets to TableCell
How can I do it?
I've found old solutions for MVVMCross.Binding 5.7.0 with MvxImageViewLoader, but when I added it to solutions I got references duplicate.
I realized that I can use converter for that, but I want to try avoid converter usage.
Also I can use ffimageloading package, but I didn't find any solution for it.
There is more simple that I've thought.
Only 3 steps:
The first one:
set custom class for UIImageView
The second one:
Create an outlet for UIImageView. Pay attention to type.
And
The third one:
bind URL
have you tried that in your cell?
_imageLoader = new MvxImageViewLoader(() => ImageView)
{
DefaultImagePath = "res:" + NSBundle.MainBundle.PathForResource(imageName, "png")
};
Searched entire Internet but couldn’t find the modern solution for my problem.
I want to use NSObjectController in pair with Core Data through Cocoa Bindings and struggle to set it up properly. Worth noting that I’m using latest version of Xcode and Swift.
What I’ve done:
For testing purposes I’ve done the following:
Created an macOS app with “Use Core Data” option selected (the app is not document based);
Dragged 2 NSTextFields into the Storyboard Dragged NSObjectController to the view controller scene;
Added Employee Entity to Core Data model with 2 attributes “name” and “surname”;
Done everything from the answer in How do I bind my Array Controller to my core data model?
Set NSObjectController to entity mode and typed in “Employee”,
Prepares Content selected, Use Lazy Fetching selected so all three options checked;
Binded the NSObjectController’s Managed Object Context in bindings inspector to the View Controller’s managedObjectContext;
Binded NSTextFields as follows: Value - Object Controller, Controller key - selection, Model Key Path - name (for 1st text field) and surname (for 2nd).
That’s it.
First set of questions: What I did wrong and how to fix it if it’s not completely wrong approach?
I’ve read in some post on stackoverflow that doing it that way allows automatic saving and fetching from Core Data model. That’s why I assumed it should work.
So here is a Second set of questions:
Is it true?
If it is then why text fields are not filled when view is displayed?
If it is not then how to achieve it if possible (trying to write as less code as possible)?
Third question: If I used approach that is completely wrong would someone help me to connect Core Data and NSObjectController using Cocoa bindings and show me the way of doing so with as less code written as possible using the right approach?
Taking into account that there no fresh posts about this topic in the wilds I think the right answer could help a lot of people that are developing a macOS app.
Thanks in advance!
I think your basic approach is correct, although it is important to understand that you need a real object, an instance, in order for it to work.
Creating a NSManagedObject subclass is generally desirable, and is almost always done in a real project, so you can define and use properties. You can do it easily nowadays by selecting the data model in Xcode's Project Navigator and clicking in the menu: Editor > Create NSManagedObject Subclass…. Technically it is not necessary, and in a demo or proof-of-concept, you often muddle through with NSManagedObject.
Assuming you are using the Xcode project template as you described, wherein AppDelegate has a property managedObjectContext, the following function in your AppDelegate class will maintain, creating when necessary, and return, what I call a singular object – an object of a particular entity, in this case Employee, which your app requires there to be one and only one of in the store.
#discardableResult func singularEmployee() -> NSManagedObject? {
var singularEmployee: NSManagedObject? = nil
let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "Employee")
let objects = try? self.managedObjectContext.fetch(fetchRequest)
singularEmployee = objects?.first
if singularEmployee == nil {
singularEmployee = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: self.managedObjectContext)
}
return singularEmployee
}
Then, add this line of code to applicationDidFinishLaunching
singularEmployee()
I am developing an application using Xcode 7 and Swift 2. I recently discovered an error in my code. In the debugger log (I think that is what it is called) , it printed this:
[AppDeveloper] ADBannerView: Unhandled error (no delegate or delegate does not implement didFailToReceiveAdWithError:): Error Domain=ADErrorDomain Code=7 "Ad was unloaded from this banner" UserInfo={ADInternalErrorCode=7, NSLocalizedFailureReason=Ad was unloaded from this banner, ADInternalErrorDomain=ADErrorDomain}
I did some research and found out that I needed this code:
iAdBannerView.delegate = self
In my viewDidLoad method. I tried it, and I no longer recieved the error. However, I have two viewControllers. Both contain iAds. In the original view controller, ViewController.swift, the code workds. In the view controller that I later added, AboutViewContoller, I get this error:
Cannot assign a value of type 'AboutViewController' to a value of type 'ADBannerViewDelegate?"
Could someone please show me my error in my code?
Earlier, I had:
class AboutViewController: UIViewController {
I forgot the ADBannerViewDelegate. The correct code is:
class AboutViewController: UIViewController, ADBannerViewDelegate {
Thanks to Charles A. and Daniel Storm for helping out!
Update for Xcode 8:
In Xcode 8, one needs to go to the Core Data Model Editor and Show the File Inspector. Near the bottom is an option for code generation. Select Swift.
Edit: I found the solution to generate a Swift model from Core Data entity:
On Xcode:
Editor > Create NSManagedOjbect > Click button "Next" > Click button "Next" > Select "Swift" Langage > Click button "Create"
I tried Swift langage by creating a new Swift project on Xcode 6 beta using Core Data.
When I generate my models from my Core Data's entities, Xcode creates Objective-C models.
Is there a way to generate Swift model rather than Obejctive-C model with Core Data ?
Thanks !
Lets have a look on the Objective-C way:
Person.h (Header-File)
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface Person : NSManagedObject
#property (nonatomic, retain) NSString *name;
#end
Person.m (Implementation-File)
#import "Person.h"
#implementation Person
#dynamic name;
#end
Swift
The documentation already included in Xcode6-Beta says:
Core Data provides the underlying storage and implementation of properties in subclasses of the NSManagedObject class. Add the #NSManaged attribute before each property definition in your managed object subclass that corresponds to an attribute or relationship in your Core Data model. Like the #dynamic attribute in Objective-C, the #NSManaged attribute informs the Swift compiler that the storage and implementation of a property will be provided at runtime. However, unlike #dynamic, the #NSManaged attribute is available only for Core Data support.
So that is how I would rewrite the above example for Swift (not tested):
Person.swift
import CoreData
class Person: NSManagedObject {
#NSManaged var name : NSString
}
And according to your question I think the subclass-generation-feature might be not included in Xcode6 yet. Did you made sure that you have chosen "Swift" as programming language when you were creating the Cocoa-Project in Xcode?
You can get Swift model back using NSEntityDescription.insertNewObjectForEntityForName but you must edit your core data model file and not use Person as a Class Entity but <ProjectName>.Person else it returns NSManagedObject...
Using println() you won't see Person instance but something like <_TtC5ProjectName4Person: 0xc9ad5f0> but calling methods on this will prove it's a Person instance for real. I guess it's just the way for Swift to generate unique class names, not conflict and CoreData methods show this internal mechanism.
The Apple documentation says:
Swift classes are namespaced—they’re scoped to the module (typically, the project) they are compiled in. To use a Swift subclass of the NSManagedObject class with your Core Data model, prefix the class name in the Class field in the model entity inspector with the name of your module.
According to Apple's video regarding What's new In CoreData frame: 38mins (WWDC2014 Session 225), in inspector's Data Model, prefix the class name with the project name. Like projectName.Doctor
I've tried this but what will happen is that the generated managed object class becomes: projectName.swift instead of Doctor.swift. Even the class declaration becomes class projectName: ManagedObject
Solution:
In Data model inspector, just specify the Name & Class of your object to what name you want, example: Doctor
After you generated an object model and selecting Swift, this will create a file (Doctor.swift).
Now, when inserting new records in Core Data, you might an experience error "Class not found, using default NSManagedObject instead" even if you cast the newly inserted object to a correct object name.
To solve this, you just need to add #objc(class name) above the class declaration. See sample below.
import Foundation
import CoreData
#objc(Doctor)
class Doctor: NSManagedObject {
#NSManaged var name: String
}
Then:
let doctorManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Doctor", inManagedObjectContext: context) as Doctor
doctorManagedObject.name = "John" // you can now use dot syntax instead of setValue
Save context to commit insert.
I tested #NSManaged, it didn't work. :( .
But mixed models files(.h) generated by xcdatamodel, it succeed.
please read the doc and code in https://github.com/iascchen/SwiftCoreDataSimpleDemo
Alternatively, you can just add #import "Person.h" to the bridging header, Project-Bridging-Header.h that Xcode generates for you (if you accepted it's offer to generate). Then you can use all the auto-generated Obj-C as if it were native Swift.
Editor -> Create NSManagedObject Subclass works fine for Swift
Simply go through all the usual steps, but when you get to creating the files, choose Language 'Swift' if it's the first time you've used Create NSManagedObject Subclass with a Swift project it'll be defaulting to Objective C
For XCode 12.
You can change generating model language.
I want to do some stuff from the appDelegate in Xcode. One of these things are to change a UILabel.
ViewController *viewController = [[UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:#"id"];
viewController.label.text = #"heeej";
I was told this would do the trick. Doesn't work. Label doesn't change. Does anyone know what the problem is?
There are several problems:
Don't do anything in the AppDelegate except for loading the window an the initial view controllers (if needed).
You are instantiating a new view controller in the first line. I assume you already have a view controller and you want to change the label in that view controller. Than you need a reference to that view controller and use this reference to send messages to it.
The label should not be a property of the view controller. You should try to follow the design pattern Model-View-Controller or the pattern Model-View-ViewModel. Ask you preferred search engine what those are if you don't know.
id as an identifier for anything in Objective-C is a bad idea because this is used as an object type.
Edit: You don't need a reference to change a property in the view controller. Use notifications to update the label. The system sends a notification with the name UIApplicationWillEnterForgroundNotification' (see [here][1]). Add the view controller as an observer to the[NSNotificationCenter defaultCenter]` for this name and react on the notification. Read the Apple documentation if you don't know what I am talking about.