i have some problems with delegates under xcode while programming an application for Mac OS. I want to communicate with mobile phones if they are in the same network via TCP. I have the following server integrated in my project:
https://github.com/tuscland/osc-echo-example/blob/master/TCPServer.m
https://github.com/tuscland/osc-echo-example/blob/master/TCPServer.h
The only thing I changed at the server is that I extended the start-method so that I can specify a special port. Also I changed the TCPServerDelegation in TCPServer.h to #protocol.
Now I want to set the delegate to this class. But then I get the following error:
[MobileSync copyWithZone:]: unrecognized selector sent to instance 0x109e0f950
I tried a lot but I could not found any solution.
Here is my code, some irrelevant functions are taken out:
MobileSync.h
#import <Foundation/Foundation.h>
#import "TCPServer.h"
#interface MobileSync: NSObject <TCPServerDelegation> {
}
-(id)init;
-(void)StartServer:(int)port;
-(void)StopServer;
// Properties
#end
MobileSync.m
#import "MobileSync.h"
#import "TCPServer.h"
#implementation MobileSync {
TCPServer *tcpServer;
// Other variables
}
-(id)init {
self = [super init];
if (self != nil) {
// Fill variables with values
}
return self;
}
-(void)StartServer:(int)port {
tcpServer = [[TCPServer alloc] init];
[tcpServer setDelegate:self] // <<<<<<< This line is broken
NSError *__autoreleasing* error = NULL;
if ([tcpServer start:port error:error]) {
NSLog(#"Server started successfully");
}
}
-(void)StopServer {
if (tcpServer.stop)
NSLog(#"Server stoped successfully");
}
// different sync functions
// tcpServer Delegate function
-(void)TCPServer:(TCPServer *)server didReceiveConnectionFromAddress:(NSData *)addr inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr {
NSLog(#"Connection received.");
}
TCPServer.h
#import <Foundation/Foundation.h>
#import <CoreServices/CoreServices.h>
NSString * const TCPServerErrorDomain;
typedef enum {
kTCPServerCouldNotBindToIPv4Address = 1,
kTCPServerCouldNotBindToIPv6Address = 2,
kTCPServerNoSocketsAvailable = 3,
} TCPServerErrorCode;
#interface TCPServer : NSObject {
#private
id delegate;
NSString *domain;
NSString *name;
NSString *type;
uint16_t port;
CFSocketRef ipv4socket;
CFsocketRef ipv6socket;
NSNetService *netService;
}
#property (readwrite, copy) id delegate;
#property (readwrite, copy) NSString *domain;
#property (readwrite, copy) NSString *name;
#property (readwrite, copy) NSString *type;
#property (readwrite) uint16_t port;
-(BOOL)start:(int)port error:(NSError **)error;
-(BOOL)stop;
-(void)handleNewConnectionFromAddress:(NSData *)addr inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr;
#end
#protocol TCPServerDelegation
-(void)TCPServer:(TCPServer *)server didReceiveConnectionFromAddress:(NSData *)addr inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr;
#end
Can someone help me solving the problem? That would be great
Related
In my AppDelegate.m, I am doing something like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#try {
// initalizing Meeting config
MeetingConfig *config = [[MeetingConfig alloc] init];
NSLog(#"Initalized Meeting Config: %#", config);
[config setRoomName:#"test123"];
NSLog(#"SetRoom name for Meeting config: %#", config.roomName);
NSString *clientId = #"";
NSLog(#"Unused Client id is: %#", clientId);
//Call UIView from here
}#catch (NSException *exception) {
NSLog(#"exception: %#", exception);
}
return YES;
}
Where my MeetingConfig.m file looks like this
#implementation MeetingConfig
- (id) init
{
if (self = [super init]) {
self.apiBase = #"https://api.in";
self.showSetupScreen = false;
self.autoTune = true;
}
return self;
}
- (void) setAuthToken:(NSString *)authToken
{
self.authToken = authToken;
}
- (void) setApiBase:(NSString *)apiBase
{
self.apiBase = apiBase;
}
// more code
and MeetingConfig looks like this
#import <Foundation/Foundation.h>
#interface MeetingConfig : NSObject
#property (nonatomic, assign) NSString* roomName;
#property (nonatomic, assign) NSString* authToken;
#property (nonatomic, assign)Boolean autoTune;
#property (nonatomic, assign)NSString* apiBase;
#property (nonatomic, assign)Boolean showSetupScreen;
- (void) setRoomName:(NSString *)roomName;
- (void) setAuthToken:(NSString *)authToken;
- (void) setShowSetupScreen:(Boolean)showSetupScreen;
- (void) setAutoTuneEnabled:(Boolean)autoTune;
- (id) init;
#end
Can someone help me in determining what I could be doing wrong here? and why doesn't it log exception in NSLog? Also, I am super new to objective C (i have been asked to stick with Objective c) and if anyone have any suggestion in regards to the code then please let me know.
Error
You're using assign for reference/pointer types: #property retain, assign, copy, nonatomic in Objective-C
They should probably be declared copy, because this is a kind of value object, I think.
No exceptions were caught because no exceptions were thrown. Throwing/catching exceptions for control flow is not common in Objective-C
You don't need to write explicit setter functions for #properties
You should prefer to use BOOL type instead of Boolean, with values of YES/NO instead of true/false.
You should return instancetype not id from init, at least in reasonably modern Objective C
Consider making an initialiser that takes all the properties (initWithRoomName:clientID:) and make them read only once set
You don't need to declare -(id) init in your header since it gets that from NSObject
I have an 2 objective C classes:
Class 1 scanDatabase (Scans a database and puts that into a mutable array)
Class 2 Mapper (Is a mapping class for the database scan "model")
In objective C this successfully scans the database and puts it into a mutable array. Using the mapping class I can access individual groups of elements (AlbumTitles) like so:
for (Mapper *mapper in scanResult) {
NSLog(#"%#", mapper.AlbumTitle);
}
Everything is working as it should and I can return individual elements from my array i.e as above I am only returning album titles.
I then need to use that array in Swift. I call the objective C in my Swift class and again it runs fine and creates the array. This is done with:
let scanTable = ScanTable();
let scanMapper = Mapper();
scanTable.scanTableDo();
but when I try to retrieve a particular set of items like Album title as I did in the objective C for loop above I get the error "scanMapper is not a type" (scanMapper is my swift instance of the objective C mapper class:
I tried two different ways and both have the same error:
for mapper: scanMapper in scanTable.scanResult {
print("\(mapper.AlbumTitle)")
}
for object in scanTable.scanResult as! [scanMapper] {
print("\(mapper.AlbumTitle)")
}
Can I use an objective C class as a model/mapper and not sure whether I would need to recreate it in Swift.
I will include the mapper and scanTable .h and .m code just in case it is needed, plus the bridging header:
Mapper.h:
#import <Foundation/Foundation.h>
#import <AWSDynamoDB/AWSDynamoDB.h>
#interface Mapper : AWSDynamoDBObjectModel <AWSDynamoDBModeling>
#property (nonatomic, strong) NSNumber *SongID;
#property (nonatomic, strong) NSString *Artist;
#property (nonatomic, strong) NSString *SongURL;
#property (nonatomic, strong) NSString *Location;
#property (nonatomic, strong) NSNumber *UserRatings;
#property (nonatomic, strong) NSNumber *AVGUserRating;
#property (nonatomic, strong) NSString *Category;
#property (nonatomic, strong) NSString *PictureURL;
#property (nonatomic, strong) NSNumber *SongDuration;
#property (nonatomic, strong) NSString *SongTitle;
#property (nonatomic, strong) NSNumber *AVGMusicianRating;
#property (nonatomic, strong) NSString *AlbumTitle;
#end
Mapper.m
#import <AWSDynamoDB/AWSDynamoDB.h>
#import "Mapper.h"
#implementation Mapper
+ (NSString *)dynamoDBTableName {
return #"Songs";
}
+ (NSString *)hashKeyAttribute {
return #"SongID";
}
#end
ScanTable.h:
#import <Foundation/Foundation.h>
#import <AWSDynamoDB/AWSDynamoDB.h>
#interface ScanTable : NSObject
- (void) scanTableDo;
#property (nonatomic, strong) NSMutableArray *scanResult;
#end
ScanTable.m
#import "ScanTable.h"
#import "Mapper.h"
#implementation ScanTable
- (void) scanTableDo {
AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
scanExpression.limit = #10;
[[dynamoDBObjectMapper scan:[Mapper class]
expression:scanExpression]
continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(#"The request failed. Error: [%#]", task.error);
}
if (task.exception) {
NSLog(#"The request failed. Exception: [%#]", task.exception);
}
if (task.result) {
AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
NSMutableArray *scanResult = [[NSMutableArray alloc] initWithArray:paginatedOutput.items]; //// ADDED /////
for (Mapper *mapper in scanResult) {
NSLog(#"%#", mapper.AlbumTitle);
}
}
return nil;
}];
}
#end
//EDITED ADDED BRIDGING HEADER//
MySampleApp-Bridging-Header.h:
//
// MySampleApp-Bridging-Header.h
// MySampleApp
#import "ScanTable.h"
#import "Mapper.h"
#import "Hello World.h"
Thanks for your help
The problem is just as the error explains, you're attempting to cast the items in your array to scanMapper, which is a variable holding an instance of Mapper, not the Mapper type itself. Assuming that scanTable.scanResult is an NSArray of Mappers, try this instead:
guard let scanResult = scanTable.scanResult as? [Mapper] else {
print("scanResult was not an array of mappers!")
return
}
for mapper: Mapper in scanResult {
print("\(mapper.AlbumTitle)")
}
I'm getting the error incompatible pointer types assigning to Deck *__strong from PlayCards *
And i'm not sure why is that. Its in the first method implemented (deck):
#import "CardGameViewController.h"
#import "PlayingCards.h"
#interface CardGameViewController ()
#property (weak, nonatomic) IBOutlet UILabel *cardLabel;
#property (nonatomic) NSUInteger flipsCount;
#property (strong, nonatomic) Deck *deck;
#end
#implementation CardGameViewController
-(Deck *) deck {
if (!_deck) _deck = [[PlayingCards alloc] init];
return _deck;
}
-(void) setFlipsCount:(NSUInteger)flipsCount {
_flipsCount = flipsCount;
self.cardLabel.text = [NSString stringWithFormat:#"Flips:%d", self.flipsCount];
}
- (IBAction)flipCard:(UIButton *)sender {
sender.selected = !sender.isSelected;
self.flipsCount++;
}
#end
This is the header file(nothing going on here):
#import <UIKit/UIKit.h>
//#import "Card.h"
//#import "Deck.h"
//#import "PlayingCards.h"
#interface CardGameViewController : UIViewController
#end
And the PlayingCard class inheriting from Deck class..
this is the PlayingCards.m
#import "PlayingCards.h"
#implementation PlayingCards
#synthesize suit = _suit;
//modifying the contents getter so it will return array with the ranks and rank+suit
-(NSString *) contents {
NSArray *cardsRank = [PlayingCards rankStrings];
return [cardsRank[self.rank] stringByAppendingString:self.suit];
}
//creating a method to make sure we get validated suits
+(NSArray *) validSuit {
return #[#"♠",#"♣",#"♥",#"♦"];
}
//creating calss method to validate the rank
+(NSArray *) rankStrings {
return #[#"?",#"A",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"J",#"Q",#"K"];
}
//creating a new setter for suit to make sure we get the valitated suits, uding the validateSuit method
-(void) setSuit:(NSString *)suit {
if ([[PlayingCards validSuit] containsObject:suit]) {
_suit = suit;
}
}
//creating new getter for suit to make sure its not empty
-(NSString *) suit {
return _suit? _suit: #"?";
}
//creating a class method to make sure when user set the rank he will will
+(NSUInteger) maxRank {
return [self rankStrings].count - 1;
}
//creating a new setter to the renk to make sure the rank is validates
-(void) setRank:(NSUInteger)rank {
if (rank <= [PlayingCards maxRank]) {
_rank = rank;
}
}
#end
PlayingCards.h
#import "Card.h"
#import "Deck.h"
#interface PlayingCards : Card
#property (strong, nonatomic) NSString *suit;
#property (nonatomic) NSUInteger rank;
+(NSArray *) validSuit;
+(NSUInteger) maxRank;
#end
This line:
if (!_deck) _deck = [[PlayingCards alloc] init];
Should be:
if (!_deck) _deck = [[PlayingCardDeck alloc] init];
If the parent for Card is of class NSObject as you say, and given that PlayingCards inherits from Card, then you can't assign an instance of PlayingCards to a variable of type Deck*. That's what the compiler is telling you.
If you really need to do it, you have to write:
if (!_deck) _deck = (Deck*)[[PlayingCards alloc] init];
It would only be valid because in Objective-C the implementation is given at runtime and which method of which class is called is only decided at runtime when the message is dispatched. However, this pattern is very unusual and you better be certain that PlayingCards is implementing all the selectors that might be called on a Deck instance. A better way would be to use protocols.
You can define a protocol and then use:
id <myProtocol> deck = [[PlayingCards alloc] init];
Put in the protocol all the selectors you need.
Why can't you use this ?
PlayingCards* deck = [[PlayingCards alloc] init];
I run this code:
- (void)unitButtonButtonTapped:(id)sender {
[_label setString:#"Last button: Unembossed square"];
MilitaryUnits *target = nil;
target = [Peasants militaryUnits];
target.position = ccp(100, 450);
[self addChild:target];
}
And I get this error:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Argument must be non-nil'
These are my .h and .m class files
#import "cocos2d.h"
#interface MilitaryUnits : CCSprite {
int _experience;
int _number_of_units;
int _stamina;
int _armor_level;
int _weapon_levell;
}
#property (nonatomic, assign) int experience;
#property (nonatomic, assign) int number_of_units;
#property (nonatomic, assign) int stamina;
#property (nonatomic, assign) int armor_level;
#property (nonatomic, assign) int weapon_levell;
#end
#interface Peasants : MilitaryUnits{
}
+(id)militaryUnits;
#end
#import "MilitaryUnits.h"
#implementation MilitaryUnits
#synthesize number_of_units = _number_of_units;
#synthesize stamina = _stamina;
#synthesize experience = _experience;
#synthesize armor_level = _armor_level;
#synthesize weapon_levell = _weapon_levell;
#end
#implementation Peasants
+ (id)militaryUnits {
Peasants *militaryUnits = nil;
if ((militaryUnits = [[[super alloc] initWithFile:#"Target.png"] autorelease])) {
}
return militaryUnits;
}
#end
Note, I'm using cocos 2d
looks to me like your sprite is nil, ie the file "Target.png" is not found. Make certain the file name has the same case (in finder) as you spelled out in your code, and that the file is included in the target's membership in Xcode.
Also
+ (id)militaryUnits {
Peasants *militaryUnits;
if ((militaryUnits = [[[super alloc] initWithFile:#"Target.png"] autorelease])) {
return militaryUnis;
} else {
CCLOGERROR(#"your favorite whine style for errors like file not found");
return nil;
}
}
I'm new to ObjectiveC and Xcode and I'm having a strange behavior:
This is the Packet class header: Packet.h
#import <Foundation/Foundation.h>
#interface Packet : NSObject
{
short index;
NSData *packetData;
short totalChunks;
}
#property (nonatomic) short index;
#property (strong, nonatomic) NSData *packetData;
#property (nonatomic) short totalChunks;
#end
And this is Packet.m
#import "Packet.h"
#implementation Packet
#synthesize index;
#synthesize packetData;
#synthesize totalChunks;
-(id)init
{
self = [super init];
return self;
}
#end
The problem is i can't use getter and setter although it seems to me that properties are declared and synthesized correctly!
for example:
#import "TransferManager.h"
#implementation TransferManager
-(void)sendAckPacket
{
Packet *packet = [[Packet alloc] init];
packet.index; //ERROR HERE: Property not found on object of type Packet *
}
#end
I know there is no TransferManager.h attached becaues I don't want to write useless stuff, but it imports "Packet.h". Otherwise i should have error during the initialization of *packet.
I'm stuck... Any Help? :)