I have a method which is supposed to be called once a BLE device is connected. but for some reason this is not happening.
There are multiple view controllers which are all doing there job first, but the final one which should update a label is not being called, this is called realDataCallBackWithData.
here is the code in viewController.m that is not being called:
#import "ViewController.h"
#import "CRPC_300SDK.h"
#import "CRBlueToothManager.h"
#import "CRHeartLiveView.h"
#import "DataObject.h"
#import "IntervalGraph.h"
#import <VTO2Lib/VTO2Lib.h>
#import "VTBLEUtils.h"
#import "VTConnectViewController.h"
#interface ViewController ()<CRPC_300SDKDelegate,CRBlueToothManagerDelegate,VTO2CommunicateDelegate>
- (void)viewDidLoad
{
[super viewDidLoad];
[VTO2Communicate sharedInstance].delegate = self;
}
#pragma mark -
#pragma mark VTO2Parser Update
//This is the method which when called should activate the realDataCallBackWithData method below.
- (void)readRealtimeData{
if (self.deviceCom.sensorConnected == NO){
NSLog(#"readRealtimeData NOT activated, sensor state %d", self.deviceCom.sensorConnected);
}else if (self.deviceCom.sensorConnected == YES){
NSLog (#"readRealtimeData activated");
[[VTO2Communicate sharedInstance] beginGetRealData];
}
}
// This is the method not being called:
-(void)realDataCallBackWithData:(NSData *)realData
{
if (realData == nil){
NSLog(#"error");
return;
}
VTRealObject *rObj = [VTO2Parser parseO2RealObjectWithData:realData];
u_char hr = rObj.hr;
_spo2Label.text = [NSString stringWithFormat:#"%d",hr];
NSLog(#"O2Ring HR = %hhu", hr);
}
for reference, here is the VTO2Communicate.h:
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "VTO2Def.h"
#class VTFileToRead;
NS_ASSUME_NONNULL_BEGIN
#protocol VTO2CommunicateDelegate <NSObject>
#optional
- (void)serviceDeployed:(BOOL)completed;
/// #brief Common command send to peripheral, callback
/// #param cmdType command for VTCmdTypeSyncParam/VTCmdTypeSetFactory
/// #param result view the enum VTProCommonResult
- (void)commonResponse:(VTCmdType)cmdType andResult:(VTCommonResult)result;
/// #brief Send the current progress of reading
/// #param progress progress value
- (void)postCurrentReadProgress:(double)progress;
/// #brief Read file complete
/// #param fileData view model --- VTFileToRead
- (void)readCompleteWithData:(VTFileToRead *)fileData;
/// #brief get information complete . if infoData == nil , an error occurred
/// #param infoData information data nullable
- (void)getInfoWithResultData:(NSData * _Nullable)infoData;
/// #brief use `parseO2RealObjectWithData` to parse realData. if realData == nil , an error occurred.
/// #param realData real data
- (void)realDataCallBackWithData:(NSData * _Nullable)realData;
/// #brief use `` to parse realPPG. if realPPG == nil , an error occurred.
/// #param realPPG real PPG data
- (void)realPPGCallBackWithData:(NSData * _Nullable)realPPG;
/// #brief read current peripheral's rssi
/// #param RSSI rssi
- (void)updatePeripheralRSSI:(NSNumber *)RSSI;
#end
#interface VTO2Communicate : NSObject
/// #brief This peripheral is currently connected. Need to be set after connection
#property (nonatomic, strong) CBPeripheral *peripheral;
/// #brief current file been read or written
#property (nonatomic, strong) VTFileToRead *curReadFile;
/// #brief time out ms
#property (nonatomic, assign) u_int timeout;
#property (nonatomic, assign) id<VTO2CommunicateDelegate> _Nullable delegate;
+ (VTO2Communicate *)sharedInstance;
- (void)readRSSI;
/// #brief Get information of peripheral. callback `getInfoWithResultData:`
- (void)beginGetInfo;
/// #brief Get real-time data. callback `realDataCallBackWithData:`
- (void)beginGetRealData;
/// #brief Restore factory. callback `commonResponse: andResult:`
- (void)beginFactory;
/// #brief get PPG data.
- (void)beginGetRealPPG;
/// #brief set params . all type view struct `VTParamType` . callback `commonResponse: andResult:`
/// #param paramType param type
/// #param paramValue param content/value
- (void)beginToParamType:(VTParamType)paramType content:(NSString *)paramValue;
/// #brief Download file from peripheral. callback `readCompleteWithData:` & `postCurrentReadProgress:`
/// #param fileName file's name
- (void)beginReadFileWithFileName:(NSString *)fileName;
#end
/// #brief this is a class to describe the completeed current loading or writing file
#interface VTFileToRead : NSObject
#property (nonatomic, assign) NSString *fileName;
#property (nonatomic, assign) u_int fileSize;
#property (nonatomic, assign) u_int totalPkgNum;
#property (nonatomic, assign) u_int curPkgNum;
#property (nonatomic, assign) u_int lastPkgSize;
/// #brief download completed response data .
#property (nonatomic, strong) NSMutableData *fileData;
/// #brief read file result
#property (nonatomic, assign) VTFileLoadResult enLoadResult;
#end
NS_ASSUME_NONNULL_END
and the VTO2Parser.h
#import <Foundation/Foundation.h>
#import "VTO2Info.h"
#import "VTO2Object.h"
#import "VTO2WaveObject.h"
#import "VTRealObject.h"
NS_ASSUME_NONNULL_BEGIN
#interface VTO2Parser : NSObject
/// #brief parse O2 information
/// #param infoData infoData from peripheral
+ (VTO2Info *)parseO2InfoWithData:(NSData * _Nonnull)infoData;
/// #brief parse O2 object
/// #param fileData fileData from peripheral
+ (VTO2Object *)parseO2ObjectWithData:(NSData * _Nonnull)fileData;
/// #brief parse O2 Wave array .
/// #param waveData waveData from VTO2Object
+ (NSArray <VTO2WaveObject *>*)parseO2WaveObjectArrayWithWaveData:(NSData * _Nonnull)waveData;
/// #brief parse O2 Real-time data
/// #param realData realData from peripheral
+ (VTRealObject *)parseO2RealObjectWithData:(NSData *)realData;
/// #brief parse O2 Real PPG data
/// #param realPPG real PPG data from peripheral
+ (NSArray <VTRealPPG *>*)parseO2RealPPGWithData:(NSData *)realPPG;
#end
NS_ASSUME_NONNULL_END
Everything else is being called and i have confirmed this in the logs, it is only the method in the viewController.m which is not firing, can someone tell me where i have gone wrong?
I discovered that the solution to the problem was to re-declare the delegate after the peripheral was connected, i did this by adding the following line of code into the readRealTimeData method:
[VTO2Communicate sharedInstance].delegate = self;
here is how the now working method looks:
- (void)readRealtimeData{
if (self.deviceCom.sensorConnected == NO){
NSLog(#"readRealtimeData NOT activated, sensor state %d", self.deviceCom.sensorConnected);
}else if (self.deviceCom.sensorConnected == YES){
NSLog (#"readRealtimeData activated");
[VTO2Communicate sharedInstance].delegate = self;
[[VTO2Communicate sharedInstance] beginGetRealData];
}
}
This ensured that the delegate was reset before the callback was fired.
Related
I'm having a bit of a nightmare trying to implement the ability to have two players playing against each other on my iPhone app through Game Center.
I am simply trying to access a function within GameCenterManager.m from a different .m file that I have. In my racetohundredViewController.h file I have:
#import <UIKit/UIKit.h>
#import "startPage.h"
#import "GameCenterManager.h"
#import <GameKit/GameKit.h>
#interface racetohundredViewController : UIViewController <UIActionSheetDelegate, GKLeaderboardViewControllerDelegate, GameCenterManagerDelegate>
{
GameCenterManager *gcManager;
BOOL gameIsMultiplayer;
double randomHostNumber;
}
#property (retain, nonatomic) GameCenterManager *gcManager;
in my corresponding .m file I have:
#interface racetohundredViewController ()
#end
#implementation racetohundredViewController
#synthesize gcManager;
- (void)generateAndSendHostNumber;
{
NSLog(#"Generate and send host number");
randomHostNumber = arc4random();
NSString *randomNumberString = [NSString stringWithFormat: #"$Host:%f", randomHostNumber];
NSLog(#"the random number string is: %#", randomNumberString);
[self.gcManager testString];
[self.gcManager sendStringToAllPeers:randomNumberString reliable: YES];
}
- (void)viewDidLoad
{
[self generateAndSendHostNumber];
}
It's the [self.gcManager testString]; and [self.gcManager sendStringToAllPeers:randomNumberString reliable: YES]; that are not being called. They were before, I have clearly messed it up somehow. I can see the NSLog for the random number string.
In my GameCenterManager.h file I have (including some bits unrelated to this problem):
#import <Foundation/Foundation.h>
#import <GameKit/GameKit.h>
#class GKLeaderboard, GKAchievement, GKPlayer;
#protocol GameCenterManagerDelegate <NSObject>
#optional
- (void) processGameCenterAuthentication: (NSError*) error;
- (void) scoreReported: (NSError*) error;
- (void) reloadScoresComplete: (GKLeaderboard*) leaderBoard error: (NSError*) error;
- (void) achievementSubmitted: (GKAchievement*) ach error:(NSError*) error;
- (void) achievementResetResult: (NSError*) error;
- (void) mappedPlayerIDToPlayer: (GKPlayer*) player error: (NSError*) error;
- (void) receivedData:(NSDictionary *)dataDictionary;
#end
#interface GameCenterManager : NSObject <GameCenterManagerDelegate>
{
id <GameCenterManagerDelegate, NSObject> delegate;
NSMutableDictionary* earnedAchievementCache;
id matchOrSession;
}
//This property must be atomic to ensure that the cache is always in a viable state...
#property (retain) NSMutableDictionary* earnedAchievementCache;
#property (nonatomic, strong) id <GameCenterManagerDelegate, NSObject> delegate;
#property(nonatomic, strong) id matchOrSession;
+ (BOOL) isGameCenterAvailable;
- (void) authenticateLocalUser;
- (void)sendStringToAllPeers:(NSString *)dataString reliable:(BOOL)reliable;
- (void)sendString:(NSString *)dataString toPeers:(id)peers reliable: (BOOL)reliable;
-(void)testString;
and finally a cut down version of the .m file for GameCenterManager:
#import "GameCenterManager.h"
#import <GameKit/GameKit.h>
#implementation GameCenterManager
#synthesize earnedAchievementCache;
#synthesize delegate;
#synthesize matchOrSession;
-(void)testString
{
NSLog(#"THIS IS A TEST");
}
I could post code about sendString too but the principle is that even with the basic testString function it is not calling it.
Am I missing something very obvious here? It seems when I step through the code it will highlight the function in the .h file of GameCenterManager, but it won't then display the NSLog as I request.
My best guess would be that self.gcManager is nil. Where do you instantiate your GameCenterManager?
I have a parent class and a child class. GameObjectBase (parent) GameObjectPlayer(child). When I override a method in Child class and call it using
[myPlayerClass showNextFrame]
It is calling the parent class one. It turns out in the debugger, I see the myPlayerClass was indeed class type GameObjectBase (which is the parent class) How come?
GameObjectBase.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#class GameLayer;
#interface GameObjectBase : NSObject
{
/* CCSprite *gameObjectSprite; // Sprite representing this game object
GameLayer *parentGameLayer; */ // Reference of the game layer this object
// belongs to
}
#property (nonatomic, assign) CCSprite *gameObjectSprite;
#property (nonatomic, assign) GameLayer *parentGameLayer;
// Class method. Autorelease
+ (id) initWithGameLayer:(GameLayer *) gamelayer
imageFileName:(NSString *) fileName;
// "Virtual methods" that the derived class should implement.
// If not implemented, this method will be called and Assert game
- (void) update: (ccTime) dt;
- (void) showNextFrame;
#end
GameObjectPlayer.h
#import <Foundation/Foundation.h>
#import "GameObjectBase.h"
#interface GameObjectPlayer : GameObjectBase
{
int direction;
}
#property (nonatomic) int direction;
#end
GameLayer.h
#import "cocos2d.h"
#import "GameObjectPlayer.h"
#interface GameLayer : CCLayer
{
}
// returns a CCScene that contains the GameLayer as the only child
+(CCScene *) scene;
#property (nonatomic, strong) GameObjectPlayer *player;
#end
When I call examine in debugger what type "temp" is in this function inside GameLayer class, it's giving parent class GameObjectBase instead of subclass GameObjectPlayer
- (void) update:(ccTime) dt
{
GameObjectPlayer *temp = _player;
[temp showNextFrame];
}
You are just assigning the value. Please allocate it & then assign it.
Hope it resolves your issue.
I noticed that the new map app has a feature that I need to implement in an app I am making. The feature is when the user drops a pin on a location, the address is shown as the subtitle of the annotation view. Does anyone know how to do that?
You should implement subtitle property in your custom annotation like:
// Geo.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface Geo : NSObject <MKAnnotation>
#property (nonatomic, strong) NSString* subtitle;
// Geo.m
#include "Geo.h"
#implementation Geo
- (NSString *)subtitle
{
return _subtitle; // Here you can reverse geocoding to get address from a CLLocationCoordinate2D object
};
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? :)
I have this code (snippet) from a .h file:
#import <UIKit/UIKit.h>
#import "ILView.h"
/**
* Controls the orientation of the picker
*/
typedef enum {
ILHuePickerViewOrientationHorizontal = 0,
ILHuePickerViewOrientationVertical = 1
} ILHuePickerViewOrientation;
#class ILHuePickerView;
/**
* Hue picker delegate
*/
#protocol ILHuePickerViewDelegate
/**
* Called when the user picks a new hue
*
* #param hue 0..1 The hue the user picked
* #param picker The picker used
*/
-(void)huePicked:(float)hue picker:(ILHuePickerView *)picker;
#end
/**
* Displays a gradient allowing the user to select a hue
*/
#interface ILHuePickerView : ILView {
id<ILHuePickerViewDelegate> delegate;
float hue;
ILHuePickerViewOrientation pickerOrientation;
}
/**
* Delegate
*/
//#property (assign, nonatomic) IBOutlet id<ILHuePickerViewDelegate> delegate;
#property (assign, nonatomic) IBOutlet __unsafe_unretained id<ILHuePickerViewDelegate> delegate;
/**
* The current hue
*/
#property (assign, nonatomic) float hue;
The .m file looks like this:
#import "ILHuePickerView.h"
#import "UIColor+GetHSB.h"
#interface ILHuePickerView(Private)
-(void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event;
#end
#implementation ILHuePickerView
#synthesize color, delegate, hue, pickerOrientation;
#pragma mark - Setup
-(void)setup
{
[super setup];
I looked on SO for similar cases, and saw that I needed to put "__unsafe_unretained" in the property... I did that (hopefully correct), but it still fails on the build. The full error message is: Existing ivar 'delegate' for property 'delegate' with assign attribute must be __unsafe_unretained
What am I doing wrong?
As the error message is telling you, the ivar:
#interface ILHuePickerView : ILView {
id<ILHuePickerViewDelegate> delegate; // <-- This is the ivar
needs to be declared __unsafe_unretained:
__unsafe_unretained id<ILHuePickerViewDelegate> delegate;
not the property:
#property (assign, nonatomic) IBOutlet id<ILHuePickerViewDelegate> delegate;
because the ARC ownership qualifiers don't apply to properties; they only apply to variables.
Since the #synthesize directive creates the ivar for you (with the correct ARC qualifier), however, you can just skip its declaration:
#interface ILHuePickerView : ILView
/**
* Delegate
*/
#property (assign, nonatomic) IBOutlet id<ILHuePickerViewDelegate> delegate;
// etc.
Which is, in fact, now the recommended procedure; see Defining Classes in TOCPL.
I've used ILColorPicker in the past, and it is definitely not ARC ready. Set
-fno-objC-arc in the compiler flag settings for the ILColorPicker classes.