Swift 2.1: Property cannot be marked dynamic? - objective-c

How do I fix this compilation error?
dynamic var users = [User]()
Property cannot be marked dynamic because its type cannot be represented in Objective-C
I need dynamic so that certain view controllers can observe (via KVO) users and update their views when users changes.

Just as the error mentions
error, not #objc : NSObject:
class A{
}
func something(){
dynamic var a = [A]()
}
should be changed to:
#objc class A:NSObject{
}
func something(){
dynamic var a = [A]() //works, all good
}

Related

Unable to cast element in ForEach Loop to NSManagedObject Subclass SwiftUI

I got a ListView in SwiftUI and want to generate RowViews depending on a given property.
Therefore I want to check the property of the element in the ForEach loop.
Xcode does not recognize the type of the element, thats why i want to cast the element to the correct Class which is an NSManagedObject Subclass.
I created the NSManagedObject Subclass from the xcdatamodeld (Editor -> Create NSManagedObject Subclass...).
The NSManagedObject Subclass is created in objective-c and I added the .h file to the bridging header.
I have no problem working with the NSManagedObject Subclass in the rest of the project.
I can even create an property of that Type in the same Struct like so:
struct MyListView: View {
var test : MyNSManagedObjectSubclass //Xcode does recognize it here
For some reason Xcode wont recognize the NSManagedObject Subclass inside the ForEach Loop.
code looks like:
struct MyListView: View {
var test : MyNSManagedObjectSubclass //Xcode does recognize it here
#EnvironmentObject private var fetchResultsContainer : FetchedResultsContainer
var body: some View {
NavigationView{
VStack{
ForEach(fetchResultsContainer.results , id: \.identifier) { result in
if let castedResult = result as! MyNSManagedObjectSubclass { //Xcode does not recognize it here
if castedResult.property{
ResultRowView(input: result)
}
}
}
}
}
}
}
FetchedResultsContainer:
#objc class FetchedResultsContainer : NSObject, ObservableObject{
#objc #Published var results: [MyNSManagedObjectSubclass]()
#objc static let sharedInstance: FetchedResultsContainer = {
let instance = FetchedResultsContainer()
return instance
}()
}
I feel like im missing something obvious, as im still quite new to Swift and SwiftUI.
Appreciate your help.
Ok after taking a step back and simply coding it again from scratch it simply worked an no casting was needed...
List(fetchResultsContainer.results, id: \.identifier) { result in
if (result.property == 0) {
//do something
}
}
My assumption that the casting was not working was not correct.
I probably checked result.property == false, with property being of type NSNumber and it gave out some strange compile errors that led me on the wrong path.

Would it have any bad influence to add #objc to a Swift method or variable?

I got some Objective-C files imported in Swift project, and tried to access some Swift classes.
According to Apple's Guideline, I added the #objc to the method I wanted it to be exposed to Objective-C files.
But the question is, does this "#objc" have any side effect to my Swift project?
The following code is a singleton local data manager.
#objc class LocalDataManager {
#objc public static let shared = LocalDataManager()
private init() {}
#objc var nickName: String {
get { return loadData("nickName") } // loadData is a convenience access method to UserDefaults
set { UserDefaults.standard.set(newValue, forKey: "nickName") }
}
}
The #objc keyword does severely affect performance. The Apple docs states:
applying the #objc attribute can increase the compiled size of an app and adversely affect performance.
Therefore, only use #objc if you really need too.

How to use pointer from other classes in swift

I'm immigrating my old ObjectiveC code to swift. In ObjcC had a separate class to handle my Admob activity.
In this class I've created a pointer in the init func, and when changing scene, I could use this pointer to change the location of the ads banner.
#implementation MyAdsSupport
+(id)ShowAds:(My_Ads_Position)posIndex
{
if (_adsBannerPointer == nil)
{
_adsBannerPointer = [[KTFAdsSupport alloc]initAds:posIndex];
}
else
{
[_adsBannerPointer setAdsPosition:posIndex];
}
return _adsBannerPointer;
}
In Swift I created the Admob class, and managed to present ads on screen but when I try to call the pointer from another class it returns always nil.
Here is my Swift Code:
var adsPointer: My_Ads_Support!
func initAds(myView: UIViewController, atPos: My_Ads_Position) -> KTF_Ads_Support {
if adsPointer == nil {
adsPointer = self
adsPointer.ShowAds(myView: myView, atPos: atPos)
}
else
{
print("adsPointer ALIVE")
adsPointer.setAdsPos( atPos: atPos)
}
return self.adsPointer!
}
How can I set a pointer in Swift to be able to reach the ads banner from any scene?
In your Objective-C code you have three methods, the instance methods initAds: and setAdsPosition:, and the class method ShowAds:. The latter uses a variable, presumably declared static, called _adsBannerPointer.
Your Swift code is not the same. It has two methods, the instance methods initAds and setAdsPos, and one variable, the instance variable adsPointer.
In Swift class methods are termed type methods (as they can belong to classes, structs and enumerations) and are indicated by the use of the keyword static, type (class) variables are also indicated with static. So to follow your Objective-C model you need something along the lines of:
static var adsPointer: My_Ads_Support!
// instance init
init(startingPos : My_Ads_Position) { ... }
// instance set position
fun setAdsPos(atPos : My_Ads_Position) { ... }
static func showAds(myView: UIViewController, atPos: My_Ads_Position) -> KTF_Ads_Support { ... }
HTH

Property 'sharedInstance' not found on object of type ClassA

I am creating a swift framework. In that one class is like this as shown below.
import Foundation
#objc public class classA: NSObject {
public override init (){
super.init();
}
/**
Singleton intance is returned.
*/
public class var sharedInstance: classA {
struct Static {
static let instance = popeye();
}
return Static.instance
}
}
Now when i add this framework into a Objective c project and try to access "sharedInstance" i get this error.
Property 'sharedInstance' not found on object of type ClassA.
Fix it Replace 'sharedInstance' with 'sharedInstance'
But even if i try use Fix it, this issue isnt solved.
NOTE: This issue doesn't happen when i integrate this framework with a swift project!!!
I AM STUCK.. :(
I tried to reproduce your problem. At first the syntax highlighter in Xcode flagged the same error in Objective-C that you mentioned, but the code actually was built and ran fine.
However, there is a cleaner way of doing this. In your code you are using a computed type property, which is evaluated every time you access it! You work around this by introducing the struct Static, where you essentially do what could be done in classA itself, like this:
/**
Singleton intance is returned.
*/
public static var sharedInstance: classA = popeye()
Here we used a stored type property, which is a recommended way to implement singletons, see here:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html
And here is some documentation on different kinds of properties:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html
Finally i was able to fix this with a minor change !! :)
Swift framework code
#objc class SingletonTest: NSObject {
// swiftSharedInstance is not accessible from ObjC
class var swiftSharedInstance: SingletonTest {
struct Singleton {
static let instance = SingletonTest()
}
return Singleton.instance
}
// the sharedInstance class method can be reached from ObjC
class func sharedInstance() -> SingletonTest {
return SingletonTest.swiftSharedInstance
}
// Some testing
func testTheSingleton() -> String {
return "Hello World"
}
}
Objective C parent project code
SingletonTest *aTest = [SingletonTest sharedInstance];
NSLog(#"Singleton says: %#", [aTest testTheSingleton]);

JSON from Objective-C in Swift

Connected Objective-C classes to the project Swift, as it is written here:
https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html
There's this code of the test project:
import UIKit
class ViewController: UITableViewController {
var locations:NSArray=[]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var jsonLoader:JSONLoader
var url = NSURL(fileURLWithPath: "http://mechnikova.info/api/pic2.php?task=1")
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
self.locations = jsonLoader.locationsFromJSONFile(url)
})
}
JSONLoader - Objective-C class. This class is connected normally, without errors.
Get an error indicating that the character "{" in the function dispatch_async:
Variable 'jsonLoader' used before initialized
Something is wrong in declaration variables.... Help please!
You can use former methods such as objectForKey() or access a specific element in an array using square brackets. Examples can be found at this link. Hope this will help you parse your json!
I fixed it:
var jsonLoader:JSONLoader = JSONLoadeer()
:-)