I have two objective-c classes HondaDealerShip and FordDealerShip. They both contain similar properties and methods, so I want to define a common protocol DealerShip and do some polymorphism.
The problem is this DealerShip needs to contain generic enum type properties, so that HondaDealerShip and FordDealerShip can have different concrete enum types.
So I want something like this,
#protocol DealerShip
#property (nonatomic, readonly) enum location;
-(void)printPriceOfModel:(enum)vehicleModel;
#end
typedef NS_ENUM(NSInteger, HondaLocation) {
HondaLocationSouthEast,
HondaLocationNorthWest
}
typedef NS_ENUM(NSInteger, HondaModel) {
Accord,
Civic
}
#interface HondaDealerShip: NSObject<DealerShip>
#property (nonatomic, readonly) HondaLocation location;
- (void)printPriceOfModel:(HondaModel)vehicleModel {
//print price here
}
#end
typedef NS_ENUM(NSInteger, FordLocation) {
FordLocationEast,
FordLocationWest
}
typedef NS_ENUM(NSInteger, FordModel) {
Mustang,
Focus
}
#interface FordDealerShip: NSObject<DealerShip>
#property (nonatomic, readonly) FordLocation location;
- (void)printPriceOfModel:(FordModel)vehicleModel {
//print price here
}
#end
If I have to do this in swift, I could use protocols with associated types like below
protocol DealerShip {
associatedtype Location
associatedtype Model
var location: Location { get }
func printPriceOfModel(model : Model)
}
enum HondaLocation: Int {
case sountEast
case northWest
}
enum HondaModel: Int {
case accord
case civic
}
struct HondaDealerShip: DealerShip {
var location: HondaLocation
func printPriceOfModel(model: HondaModel) {
//print
}
}
//same for FordDealerShip
can I do similar in objective-c?.
Nope, you cannot use enum with associated types in objective c. The language does not support it.
Related
I have few issues with Binding using Objective sharpie.I am binding IndoorAtlas iOS native sdk with Xamarin.ios.
Issue is while Implementing Protocols methods as those are not getting invoked. Do we need to handle it in special way?
I am attaching API defination file and Implementation file.
// #protocol IALocationManagerDelegate
[Protocol, Model]
[BaseType(typeof(NSObject))]
interface IALocationManagerDelegate
{
// #optional -(void)indoorLocationManager:(IALocationManager *
_Nonnull)manager didUpdateLocations:(NSArray * _Nonnull)locations;
[Export("indoorLocationManager:didUpdateLocations:")]
void DidUpdateLocations(IALocationManager manager, IALocation[] locations);
// #optional -(void)indoorLocationManager:(IALocationManager *
_Nonnull)manager didEnterRegion:(IARegion * _Nonnull)region;
[Export("indoorLocationManager:didEnterRegion:")]
void DidEnterRegion(IALocationManager manager, IARegion region);
}
// #interface IALocationManager : NSObject
[BaseType(typeof(NSObject))]
interface IALocationManager
{
[Wrap("WeakDelegate")]
[NullAllowed]
IALocationManagerDelegate Delegate { get; set; }
// #property (readwrite, nonatomic, weak) id<IALocationManagerDelegate>
_Nullable delegate;
[NullAllowed, Export("delegate", ArgumentSemantic.Weak)]
NSObject WeakDelegate { get; set; }
}
////ViewController --Calling delegate methods
[Export("indoorLocationManager:didUpdateLocations:")]
public void DidUpdateLocations(IALocationManager manager , IALocation[] locations)
{
IALocation loc = locations[locations.Length - 1];
if (mFloorPlan != null)
{
CoreGraphics.CGPoint cg = mFloorPlan.CoordinateToPoint(loc.Location.Coordinate);
this.map.Center = cg;
}
}
[Export("indoorLocationManager:didEnterRegion:")]
public void DidEnterRegion(IALocationManager manager, IARegion region)
{
if (region.Type != ia_region_type.FloorPlan)
Console.WriteLine("Region Changed to {0} " + region.Identifier);
else
{
FetchFloorPlan();
}
}
Don't forget to assign the viewcontroller to the weak delegate.
IALocationManager manager = new IALocationManager();
manager.WeakDelegate = this;
In Realm,
Is it possible to set the default value of a persisted property, based on the value of another property?
For example. I have a name property that includes UpperCase/LowerCase/Accents/etc. I want to have a tokenizedName that transforms the name property into a more simple string (all undercase, no accents).
You could easily do this with derived properties:
class Person: Object {
var name: String {
get {
return _name
}
set {
_name = newValue
// perform tokenization...
tokenizedName = _name.lowercaseString
}
}
private dynamic var _name = ""
dynamic var tokenizedName = ""
override class func ignoredProperties() -> [String] { return ["name"] }
}
Here _name and tokenizedName are properties persisted in Realm, while name is ignored. Every time you read from name, you're just from its underlying storage. Every time you write to name, you set its backing storage and update the tokenized version.
Edit: In Objective-C
#interface Person : RLMObject
#property (nonatomic, copy) NSString *name;
#property NSString *_name;
#property NSString *tokenizedName;
#end
#implementation Person
- (NSString *)name {
return self._name;
}
- (void)setName:(NSString *)name {
self._name = name;
// perform tokenization...
self.tokenizedName = name.lowercaseString;
}
+ (NSArray<NSString *> *)ignoredProperties {
return #[#"name"];
}
#end
Hi I am trying to learn Opps concept in Objective C but I know PHP so I took a program in which for public, private and protected mentioned bellow.
<?php
//Public properties and method can be inherited and can be accessed outside the class.
//private properties and method can not be inherited and can not be accessed outside the class.
//protected properties and method can be inherited but can not be accessed outside the class.
class one
{
var $a=20;
private $b=30;
protected $c=40;
}
class two extends one
{
function disp()
{
print $this->c;
echo "<br>";
}
}
$obj2=new two;
$obj2->disp(); //Inheritance
echo"<br>";
$obj1=new one;
print $obj1->c; //Outside the class
?>
So this I am trying to convert in Objective c code mentioned bellow.
#import <Foundation/Foundation.h>
#interface one : NSObject
{
#private int a;
#public int b;
#protected int c;
}
#property int a;
#property int b;
#property int c;
#end
#implementation one
#synthesize a,b,c;
int a=10;
int b=20;
int c=30;
#end
#interface two : one
-(void)setlocation;
#end
#implementation two
-(void)setlocation;
{
// NSLog(#"%d",a);
NSLog(#"%d",b);
// NSLog(#"%d",c);
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
two *newtwo;
newtwo =[[two alloc]init];
//calling function
[newtwo setlocation];
}
return 0;
}
When I run the above code I am getting
2015-11-03 23:20:16.877 Access Specifier[3562:303] 0
Can some one resolve my problem.
This type of question has been asked before and there's a good explanation in the accepted answer for Private ivar in #interface or #implementation
In general I would recommend you avoid instance variables and use #property instead. Properties have the benefit of read-only/write controls, and free synthesized setters and getters (which if you're learning OOP concepts is a critical concept you should employ).
Properties are declared in the #interface part of an Obj-C file. For access control (according to the link) you have no public/private/protected keywords. All Obj-C methods (and by extension, properties) are public if they're defined in the .h file. If you want them "private" you define them in the the .m file using a class category:
//MyClass.m
#interface MyClass ()
#property(nonatomic, retain) NSString* myString;
#end
#implementation MyClass
#end
I'm having Objective-C project and i'd like to try Swift in it. I was able to configure it to use Swift classes. Anyway i can't see Swift object properties while debugging:
I've even overriden description property to print all the variables:
import Foundation
import ObjectMapper
#objc
public class Mcu : NSObject, Mappable {
var name : String?
var arch : String?
var macro : String?
var libraryName : String?
required public init?(_ map: Map) {
}
// Mappable
public func mapping(map: Map) {
name <- map["name"]
arch <- map["arch"]
macro <- map["macro"]
libraryName <- map["libraryName"]
}
override public var description : String {
return "name=\(name), arch=\(arch), macro=\(macro), libraryName=\(libraryName)"
}
}
If i print object in log (NSLog([mcus[0] description])) i
m getting correct string:
2015-11-01 10:27:19.262 Project[1447:261056] name=Optional("avr2"), arch=Optional("ARCH_AVR2"), macro=nil, libraryName=Optional("\"s8515\"")
It's not the solution to convert to Swift all the project as it's pretty large.. What can i do to provide convenient debugging for both Obj-C and Swift in Obj-C project?
PS. Xcode 7.1
PPS. For Swift class Mcu Xcode generates according Obj-c header and it looks correct (but there is difference for debugger):
SWIFT_CLASS("_TtC17ProjectModule3Mcu")
#interface Mcu : NSObject
#property (nonatomic, copy) NSString * __nullable name;
#property (nonatomic, copy) NSString * __nullable arch;
#property (nonatomic, copy) NSString * __nullable macro;
#property (nonatomic, copy) NSString * __nullable libraryName;
#property (nonatomic, readonly, copy) NSString * __nonnull description;
#end
I am moving from objective-C to Swift.
The header file was:
#interface RegisterType : NSObject
{
Class type;
NSString *typeName;
NSString *namespace;
int typeId;
}
#property (nonatomic,retain) Class type;
#property (nonatomic,retain) NSString *typeName;
#property (nonatomic,retain) NSString *namespace;
#property (nonatomic) int typeId;
#end
and the implementation was:
#implementation RegisterType
#synthesize type;
#synthesize typeName;
#synthesize namespace;
#synthesize typeId;
Now is Swift my code is:
class RegisterType {
//var type: AnyClass
var typeName: String = ""
var namespace: String = ""
var typeId: Int = 0
}
My main is problem is that I want to replace the generic type 'Class' that I used in objective-C. How do I replace it in Swift? Do I need an init method?
If I understand your question correctly, I would do something like this:
class RegisterType: NSObject {
override init() {
super.init()
self.type = self.classForCoder
}
var type: AnyClass?
var typeName: String = ""
var namespace: String = ""
var typeId: Int = 0
}
let xx = RegisterType()
println(xx.type) // prints "RegisterType"