PubNub framework in Apple Watch - watchkit

I have been trying to manually import the PubNub Framework into my Apple Watch app. There are a lot of dependencies and frameworks that are used by PubNub that are not available on the watch (i.e. SystemConfiguration, CFNetworking, etc.). Is Apple Watch supported by PubNub? How do I get it to nicely import into my Apple Watch app?

Only a few modifications needs to be made. Replacing UIKit with WatchKit replacements:
TLDR:
Replace UIDevice with WKInterfaceDevice replacements
Replace [[UIDevice currentDevice] identifierForDevice] with UUID stored in NSUserDefaults
Replace UIApplicationWillEnterForegroundNotification and UIApplicationDidEnterBackgroundNotification with NSExtensionHostWillEnterForegroundNotification and NSExtensionHostDidEnterBackgroundNotification
Remove GZIP references
Detailed Explanation By File:
PNConfiguration.m:
- (NSString *)uniqueDeviceIdentifier {
#if TARGET_OS_WATCH
NSString *key = #"PNUserDefaultsUUIDKey";
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:key];
if (!uuid) {
uuid = [[NSUUID UUID] UUIDString];
[[NSUserDefaults standardUserDefaults] setValue:uuid forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
return uuid;
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
return ([self serialNumber]?: [self macAddress]);
#endif
}
PNNetwork.m:
- (NSDictionary *)defaultHeaders {
NSString *device = #"iPhone";
NSString *osVersion = #"2.0";
#if TARGET_OS_WATCH
osVersion = [[WKInterfaceDevice currentDevice] systemVersion];
device = [[WKInterfaceDevice currentDevice] model];
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
device = [[UIDevice currentDevice] model];
osVersion = [[UIDevice currentDevice] systemVersion];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
NSOperatingSystemVersion version = [[NSProcessInfo processInfo]operatingSystemVersion];
NSMutableString *osVersion = [NSMutableString stringWithFormat:#"%#.%#",
#(version.majorVersion), #(version.minorVersion)];
if (version.patchVersion > 0) {
[osVersion appendFormat:#".%#", #(version.patchVersion)];
}
#endif
NSString *userAgent = [NSString stringWithFormat:#"iPhone; CPU %# OS %# Version",
device, osVersion];
return #{#"Accept":#"*/*", #"Accept-Encoding":#"gzip,deflate", #"User-Agent":userAgent,
#"Connection":#"keep-alive"};
}
PubNub+Core.m:
- (instancetype)initWithConfiguration:(PNConfiguration *)configuration
callbackQueue:(dispatch_queue_t)callbackQueue {
// Check whether initialization has been successful or not
if ((self = [super init])) {
#if DEBUG
[PNLog dumpToFile:YES];
#else
[PNLog dumpToFile:NO];
#endif
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> PubNub SDK %# (%#)",
kPNLibraryVersion, kPNCommit);
_configuration = [configuration copy];
_callbackQueue = callbackQueue;
[self prepareNetworkManagers];
_subscriberManager = [PNSubscriber subscriberForClient:self];
_clientStateManager = [PNClientState stateForClient:self];
_listenersManager = [PNStateListener stateListenerForClient:self];
_heartbeatManager = [PNHeartbeat heartbeatForClient:self];
[self addListener:self];
[self prepareReachability];
#if TARGET_OS_WATCH
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:NSExtensionHostWillEnterForegroundNotification object:nil];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:NSExtensionHostDidEnterBackgroundNotification object:nil];
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:UIApplicationWillEnterForegroundNotification object:nil];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
NSNotificationCenter *notificationCenter = [[NSWorkspace sharedWorkspace] notifiertionCenter];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:NSWorkspaceWillSleepNotification object:nil];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:NSWorkspaceSessionDidResignActiveNotification object:nil];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:NSWorkspaceDidWakeNotification object:nil];
[notificationCenter addObserver:self selector:#selector(handleContextTransition:)
name:NSWorkspaceSessionDidBecomeActiveNotification object:nil];
#endif
}
return self;
}
PubNub+Core.m:
- (void)handleContextTransition:(NSNotification *)notification {
#if TARGET_OS_WATCH
if ([notification.name isEqualToString:NSExtensionHostDidEnterBackgroundNotification]) {
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> Did enter background execution context.");
}
else if ([notification.name isEqualToString:NSExtensionHostWillEnterForegroundNotification]) {
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> Will enter foreground execution context.");
}
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
if ([notification.name isEqualToString:UIApplicationDidEnterBackgroundNotification]) {
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> Did enter background execution context.");
}
else if ([notification.name isEqualToString:UIApplicationWillEnterForegroundNotification]) {
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> Will enter foreground execution context.");
}
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
if ([notification.name isEqualToString:NSWorkspaceWillSleepNotification] ||
[notification.name isEqualToString:NSWorkspaceSessionDidResignActiveNotification]) {
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> Workspace became inactive.");
}
else if ([notification.name isEqualToString:NSWorkspaceDidWakeNotification] ||
[notification.name isEqualToString:NSWorkspaceSessionDidBecomeActiveNotification]) {
DDLogClientInfo([[self class] ddLogLevel], #"<PubNub> Workspace became active.");
}
#endif
}
PubNub+Core.m:
- (void)dealloc {
#if TARGET_OS_WATCH
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:NSExtensionHostWillEnterForegroundNotification
object:nil];
[notificationCenter removeObserver:self name:NSExtensionHostDidEnterBackgroundNotification
object:nil];
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:UIApplicationWillEnterForegroundNotification
object:nil];
[notificationCenter removeObserver:self name:UIApplicationDidEnterBackgroundNotification
object:nil];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
NSNotificationCenter *notificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
[notificationCenter removeObserver:self name:NSWorkspaceWillSleepNotification object:nil];
[notificationCenter removeObserver:self name:NSWorkspaceSessionDidResignActiveNotification
object:nil];
[notificationCenter removeObserver:self name:NSWorkspaceDidWakeNotification object:nil];
[notificationCenter removeObserver:self name:NSWorkspaceSessionDidBecomeActiveNotification
object:nil];
#endif
}
PubNub+Publish.m: where PNGZIP is used
NSData *publishData = nil;
if (compressed) {
#if !TARGET_OS_WATCH
NSData *messageData = [messageForPublish dataUsingEncoding:NSUTF8StringEncoding];
NSData *compressedBody = [PNGZIP GZIPDeflatedData:messageData];
publishData = (compressedBody?: [#"" dataUsingEncoding:NSUTF8StringEncoding]);
#else
NSLog(#"Tried to compress, but GZip is not available");
#endif
}

Related

getInitialNotification not working on iOS

I am using react-native-firebase version 5.3.1.
and pod Firebase/Messaging version 5.20.1.
On iOS, getInitialNotification is always returning null.
It is working fine on Android though.
onNotification and onNotificationOpened working fine on both platforms.
Should I enable remote notification from xcode capabilities ? (I tried and still no luck)
Here is my AppDelegate.m
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#if __has_include(<React/RNSentry.h>)
#import <React/RNSentry.h> // This is used for versions of react >= 0.40
#else
#import "RNSentry.h" // This is used for versions of react < 0.40
#endif
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import "SplashScreen.h"
#import "RNGoogleSignin.h"
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
#import <Firebase.h>
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[RNFirebaseNotifications configure];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"wiy"
initialProperties:nil];
[RNSentry installWithRootView:rootView];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// Facebook react-native SDK
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
[SplashScreen show];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
] || [RNGoogleSignin application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
#end

qt private member function calling another member function crashes program

I have a class with a lot of member functions. Here are the ones giving me trouble (Segmentation Fault):
#include "mainwindow.h"
#include <QTimer>
#include <QDebug>
#include <QMessageBox>
#include "ui_mainwindow.h"
#include "LabJackUD.h"
MainWindow::MainWindow(QWidget *parent, LJ_HANDLE *lngHandle2) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
blah
}
MainWindow::~MainWindow(){delete ui;}
void MainWindow::resetHandle() {
//Open the first found LabJack U3.
lngErrorcode = OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
runningErrors(lngErrorcode, __LINE__, 0);
lngErrorcode = GoOne(*lngHandle);
runningErrors(lngErrorcode, __LINE__, 0);
}
void MainWindow::runningErrors(LJ_ERROR lngErrorcode, long lngLineNumber, long lngIteration) {
char err[255];
if((lngErrorcode == 1015) && (!isOpen))
{
isOpen = true;
//STOP EVERYTHING
MainWindow::on_pushButton_clicked(false);
//Create an error message dialog only to prompt to connect labjack.
QMessageBox *msg = new QMessageBox();
msg->show();
msg->setText("WARNING:\n\nLabjack is not connected. Please\nconnect Labjack.");
}
if(lngErrorcode == 1003)
{
//attempt to solve handle problem by resetting handle
OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
GoOne(*lngHandle);
}
if(lngErrorcode != LJE_NOERROR)
{
ui->textBrowser->show();
ui->exitTextBrowser->show();
ErrorToString(lngErrorcode,err);
ui->textBrowser->setText(err);
}
}
void MainWindow::update_timer_complete()
{
//Display new LCD values
//qDebug()<<"updateLCDs timeout";
QString minutesTop = QString::number((cycleComplete->remainingTime()/1000)/7);
QString secondsTop = QString::number((cycleComplete->remainingTime()/1000)%7);
QString minutesBot = QString::number((nextExperiment->remainingTime()/1000)/7);
QString secondsBot = QString::number((nextExperiment->remainingTime()/1000)%7);
ui->lcdNumber->display(minutesTop+":"+secondsTop);
ui->lcdNumber_2->display(minutesBot+":"+secondsBot);
minutesTop.~QString();
minutesBot.~QString();
secondsTop.~QString();
secondsBot.~QString();
//I really wanted to check if stuff is working during each update.
resetHandle(); //Will call runningError() handler if problem
}
I can call my error handling function runningError() from any member function except void update_timer_complete(). When I do, I get a .exe crash.
There were a lot more member functions omitted.
If this helps, here is the class definition header file:
#include <QMainWindow>
#include "LabJackUD.h"
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0, LJ_HANDLE* lngHandle = 0);
~MainWindow();
private slots:
void cycle_timer_complete();
void next_timer_complete(bool update = false);
void update_timer_complete();
void on_radioButton_pressed();
void on_radioButton_2_pressed();
void on_radioButton_released();
void on_radioButton_3_pressed();
void on_radioButton_4_pressed();
void on_pushButton_toggled(bool checked);
void on_pushButton_clicked();
void on_pushButton_4_clicked();
void on_pushButton_clicked(bool checked);
void on_exitTextBrowser_clicked();
private:
Ui::MainWindow *ui;
LJ_HANDLE *lngHandle;
LJ_ERROR lngErrorcode;
void clearAll();
void runningErrors(LJ_ERROR lngErrorcode, long lngLineNumber, long lngIteration);
QTimer *cycleComplete;
QTimer *nextExperiment;
QTimer *updateLCDs;
int selectedPin;
int timer1;
int timer2;
int timer3;
int prevTime, prevSpin1, prevSpin2, prevSpin3, prevSpin4;
void resetHandle();
void updatePins();
};
What could allow two equivalent member functions of the form private void doStuff() to have unequal access to the same member function? One calls it fine, the other calls it and produces a segmentation fault!
If really required, here is the full code:
#include "mainwindow.h"
#include <QTimer>
#include <QDebug>
#include <QMessageBox>
#include "ui_mainwindow.h"
#include "LabJackUD.h"
bool isOpen = false;
MainWindow::MainWindow(QWidget *parent, LJ_HANDLE *lngHandle2) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
lngHandle = lngHandle2;
cycleComplete = new QTimer(this);
nextExperiment = new QTimer(this);
updateLCDs = new QTimer(this);
selectedPin = 0;
timer1 = 0;
timer2 = 0;
timer3 = 0;
lngErrorcode = 0;
connect(cycleComplete,SIGNAL(timeout()),this,SLOT(cycle_timer_complete()));
connect(nextExperiment,SIGNAL(timeout()),this,SLOT(next_timer_complete()));
connect(updateLCDs,SIGNAL(timeout()),this,SLOT(update_timer_complete()));
ui->textBrowser->hide();
ui->textBrowser->raise();
ui->exitTextBrowser->hide();
ui->exitTextBrowser->raise();
clearAll();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resetHandle() {
//Open the first found LabJack U3.
lngErrorcode = OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
runningErrors(lngErrorcode, __LINE__, 0);
lngErrorcode = GoOne(*lngHandle);
runningErrors(lngErrorcode, __LINE__, 0);
}
void MainWindow::runningErrors(LJ_ERROR lngErrorcode, long lngLineNumber, long lngIteration) {
char err[255];
if((lngErrorcode == 1015) && (!isOpen))
{
isOpen = true;
//STOP EVERYTHING
MainWindow::on_pushButton_clicked(false);
//Create an error message dialog only to prompt to connect labjack.
QMessageBox *msg = new QMessageBox();
msg->show();
msg->setText("WARNING:\n\nLabjack is not connected. Please\nconnect Labjack.");
}
if(lngErrorcode == 1003)
{
//attempt to solve handle problem by resetting handle
OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
GoOne(*lngHandle);
}
if(lngErrorcode != LJE_NOERROR)
{
ui->textBrowser->show();
ui->exitTextBrowser->show();
ErrorToString(lngErrorcode,err);
ui->textBrowser->setText(err);
//Qdebugging purposes
qDebug() << ("Error number = ") << lngErrorcode;
qDebug() << ("Error string = ") << err;
qDebug() << ("Source line number = ") << lngLineNumber;
qDebug() << ("Iteration = ") << lngIteration;
}
}
void MainWindow::clearAll() {
lngErrorcode = eDO(*lngHandle, 4, 0);
runningErrors(lngErrorcode, __LINE__, 0);
lngErrorcode = eDO(*lngHandle, 5, 0);
runningErrors(lngErrorcode, __LINE__, 0);
lngErrorcode = eDO(*lngHandle, 6, 0);
runningErrors(lngErrorcode, __LINE__, 0);
lngErrorcode = eDO(*lngHandle, 7, 0);
runningErrors(lngErrorcode, __LINE__, 0);
ui->radioButton->setChecked(false);
ui->radioButton_2->setChecked(false);
ui->radioButton_3->setChecked(false);
ui->radioButton_4->setChecked(false);
}
void MainWindow::on_radioButton_pressed()
{
clearAll();
lngErrorcode = eDO(*lngHandle, 4, 1);
runningErrors(lngErrorcode, __LINE__, 0);
qDebug() << "radio button 1 pressed";
ui->radioButton->setChecked(true);
}
void MainWindow::on_radioButton_2_pressed()
{
clearAll();
lngErrorcode = eDO(*lngHandle, 5, 1);
runningErrors(lngErrorcode, __LINE__, 0);
qDebug() << "radio button 2 pressed";
ui->radioButton_2->setChecked(true);
}
void MainWindow::on_radioButton_3_pressed()
{
clearAll();
lngErrorcode = eDO(*lngHandle, 6, 1);
runningErrors(lngErrorcode, __LINE__, 0);
qDebug() << "radio button 3 pressed";
ui->radioButton_3->setChecked(true);
}
void MainWindow::on_radioButton_4_pressed()
{
clearAll();
lngErrorcode = eDO(*lngHandle, 7, 1);
runningErrors(lngErrorcode, __LINE__, 0);
qDebug() << "radio button 4 pressed";
ui->radioButton_4->setChecked(true);
}
void MainWindow::on_pushButton_toggled(bool checked)
{
}
void MainWindow::on_pushButton_clicked()
{
}
void MainWindow::cycle_timer_complete()
{
qDebug()<<"cycleComplete timeout";
}
void MainWindow::next_timer_complete(bool update)
{
qDebug()<<"nextExperiment timeout";
if (!update) {
selectedPin++;
}
qDebug()<<"selectedPin is " << selectedPin;
switch ( selectedPin ) {
case 4:
qDebug() << "case 4";
if (!update) {
nextExperiment->start((ui->spinBox->value())*1000*7);
}
MainWindow::on_radioButton_pressed();
break;
case 5:
qDebug() << "case 5";
nextExperiment->start((ui->spinBox_2->value())*1000*7);
MainWindow::on_radioButton_2_pressed();
break;
case 6:
qDebug() << "case 6";
nextExperiment->start((ui->spinBox_3->value())*1000*7);
MainWindow::on_radioButton_3_pressed();
break;
case 7:
qDebug() << "case 7";
nextExperiment->start((ui->spinBox_4->value())*1000*7);
MainWindow::on_radioButton_4_pressed();
break;
case 8:
qDebug() << "case 8";
MainWindow::on_pushButton_clicked(true);
break;
}
//ui->pushButton->setText("Timer Complete");
}
void MainWindow::update_timer_complete()
{
//Display new LCD values
//qDebug()<<"updateLCDs timeout";
QString minutesTop = QString::number((cycleComplete->remainingTime()/1000)/7);
QString secondsTop = QString::number((cycleComplete->remainingTime()/1000)%7);
QString minutesBot = QString::number((nextExperiment->remainingTime()/1000)/7);
QString secondsBot = QString::number((nextExperiment->remainingTime()/1000)%7);
ui->lcdNumber->display(minutesTop+":"+secondsTop);
ui->lcdNumber_2->display(minutesBot+":"+secondsBot);
minutesTop.~QString();
minutesBot.~QString();
secondsTop.~QString();
secondsBot.~QString();
//I really wanted to check if stuff is working during each update.
resetHandle();
}
void MainWindow::on_pushButton_4_clicked()
{
//figure out the total cycle time
int t_total = ui->spinBox->value();
t_total += ui->spinBox_2->value();
t_total += ui->spinBox_3->value();
t_total += ui->spinBox_4->value();
//continue counting from previous state, correct for new values
int newCycleTime = timer1;
int newExpTime = timer2;
int c1 = ui->spinBox->value();
int c2 = ui->spinBox_2->value();
int c3 = ui->spinBox_3->value();
int c4 = ui->spinBox_4->value();
switch(selectedPin) {
case 4:
newExpTime += (c1 - prevSpin1)*1000*7;
newCycleTime += (c1+c2+c3+c4-prevSpin1-prevSpin2-prevSpin3-prevSpin4)*1000*7;
case 5:
newExpTime += (c2 - prevSpin2)*1000*7;
newCycleTime += (c2+c3+c4-prevSpin2-prevSpin3-prevSpin4)*1000*7;
case 6:
newExpTime += (c3 - prevSpin3)*1000*7;
newCycleTime += (c3+c4-prevSpin3-prevSpin4)*1000*7;
case 7:
newExpTime += (c4 - prevSpin4)*1000*7;
newCycleTime += (c4-prevSpin4)*1000*7;
}
cycleComplete->start(newCycleTime);
nextExperiment->start(newExpTime);
updateLCDs->start(timer3);
//change back appearance
ui->pushButton_4->setEnabled(false);
ui->pushButton->setText("STOP");
ui->radioButton->setEnabled(false);
ui->radioButton_2->setEnabled(false);
ui->radioButton_3->setEnabled(false);
ui->radioButton_4->setEnabled(false);
ui->pushButton->setChecked(true);
prevSpin1 = c1;
prevSpin2 = c2;
prevSpin3 = c3;
prevSpin4 = c4;
//no dialog open so reset
isOpen=false;
}
void MainWindow::on_radioButton_released()
{
}
void MainWindow::on_pushButton_clicked(bool checked)
{
if(checked) {
//START NRML OPERATION
//selectedPin will become 4 very shortly.
selectedPin = 3;
//figure out the total cycle time
int t_total = ui->spinBox->value();
t_total += ui->spinBox_2->value();
t_total += ui->spinBox_3->value();
t_total += ui->spinBox_4->value();
t_total *= 1000*7;
//keep track for continue option.
prevTime = t_total;
//configure timers
cycleComplete->setInterval(t_total);
nextExperiment->setInterval(0);
updateLCDs->setInterval(100);
ui->pushButton->setText("STOP");
ui->radioButton->setEnabled(false);
ui->radioButton_2->setEnabled(false);
ui->radioButton_3->setEnabled(false);
ui->radioButton_4->setEnabled(false);
ui->pushButton_4->setEnabled(false);
ui->spinBox->setEnabled(false);
ui->spinBox_2->setEnabled(false);
ui->spinBox_3->setEnabled(false);
ui->spinBox_4->setEnabled(false);
//start timers
cycleComplete->start();
nextExperiment->start();
updateLCDs->start();
//no dialog open so reset
isOpen=false;
} else {
//STOP EVERYTHING REVERT EVERYTHING
//enable continue button
ui->pushButton_4->setEnabled(true);
//revert appearance
ui->pushButton->setText("START");
ui->radioButton->setEnabled(true);
ui->radioButton_2->setEnabled(true);
ui->radioButton_3->setEnabled(true);
ui->radioButton_4->setEnabled(true);
ui->spinBox->setEnabled(true);
ui->spinBox_2->setEnabled(true);
ui->spinBox_3->setEnabled(true);
ui->spinBox_4->setEnabled(true);
//copy the current state for continuing
//+1 because finished timer is -1
timer1 = (cycleComplete->remainingTime()+1);
timer2 = (nextExperiment->remainingTime()+1);
timer3 = (updateLCDs->remainingTime()+1);
prevSpin1 = ui->spinBox->value();
prevSpin2 = ui->spinBox_2->value();
prevSpin3 = ui->spinBox_3->value();
prevSpin4 = ui->spinBox_4->value();
//stop the timers
cycleComplete->stop();
nextExperiment->stop();
updateLCDs->stop();
}
}
void MainWindow::on_exitTextBrowser_clicked()
{
ui->textBrowser->hide();
ui->exitTextBrowser->hide();
}
Strangely, the solution was rearange the body of the definition of the member function void update_timer_complete() {body}. I had to put
//I really wanted to check if stuff is working during each update.
resetHandle(); //Will call runningError() handler if problem
above
//Display new LCD values
//qDebug()<<"updateLCDs timeout";
QString minutesTop = QString::number((cycleComplete->remainingTime()/1000)/7);
QString secondsTop = QString::number((cycleComplete->remainingTime()/1000)%7);
QString minutesBot = QString::number((nextExperiment->remainingTime()/1000)/7);
QString secondsBot = QString::number((nextExperiment->remainingTime()/1000)%7);
ui->lcdNumber->display(minutesTop+":"+secondsTop);
ui->lcdNumber_2->display(minutesBot+":"+secondsBot);
minutesTop.~QString();
minutesBot.~QString();
secondsTop.~QString();
secondsBot.~QString();
For some reason, the other way around produces a crash. I would love to hear an explanation, and if one is given, I will select it as the answer.

Update Sqlite database only works once

I have an sqlite database and it's loaded into a tableview, now when i click a row to see its details..i go to another view controller in which details are displayed and a AddToFav button exists.
When i click it..and go to another view controller...i can see the changes correctly, my database is updating correctly, but if i try to add another entry..i notice that my database is not updated anymore..The addToFav button only updates the database once. Any ideas?
This is my Addbut IBaction :
- (IBAction)AddButClick:(UIButton *)sender {
[AddBut setImage:[UIImage imageNamed:#"apple-logo copy.png"] forState:UIControlStateSelected];
[AddBut setImage:[UIImage imageNamed:#"apple-logo copy.png"] forState:UIControlStateHighlighted];
Favo = [[NSMutableArray alloc] initWithCapacity:1000000];
#try {
// NSFileManager *fileMgr = [NSFileManager defaultManager];
// NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"dictionary.sqlite"];
//NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"authorsDb2.sqlite"];
// NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"FinalDb.sqlite"];
//NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"xxJuridique-FINAL-OK.sqlite"];
// [self createEditableCopyOfDatabaseIfNeeded];
// NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"data.sqlite"];
// [self.tableView reloadData];
sqlite3_stmt *compiled_statement1;
if(sqlite3_open([PathDB UTF8String], &db) == SQLITE_OK) {
// UIAlertView *DbO = [[UIAlertView alloc]
// initWithTitle:#"PATH" message:#"Database still open !" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
//
// [DbO show];
NSString *formatedSql = [NSString stringWithFormat:#"UPDATE Sheet1 SET Fav = 'YES' WHERE field3 = '%#'" , authorNAme2];
// UIAlertView *messageAlert = [[UIAlertView alloc]
// initWithTitle:#"Query" message:formatedSql delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
//
// [messageAlert show];
//
UIAlertView *PAth = [[UIAlertView alloc]
initWithTitle:#"PATH" message:PathDB delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[PAth show];
// NSLog(PathDB);
const char *sql = [formatedSql UTF8String];
NSLog(#" !!!!!!!! In the middle of it !!!!!!!!!!!!");
if (sqlite3_prepare_v2(db, sql, -1, &compiled_statement1, NULL) != SQLITE_OK) {
NSLog(#"!!!!!!!!!!!!!!!!!!!ERRRRROOOOOOORRRRRRRRR!!!!!!!!!!!!!!!!!!!!!!!!!");
//NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
NSLog(#"This is the query %#",formatedSql);
}
// sqlite3_bind_text(compiled_statement1, 1, [authorNAme2 UTF8String], -1, SQLITE_TRANSIENT);
int success = sqlite3_step(compiled_statement1);
// sqlite3_reset(compiled_statement1);
if (success != SQLITE_ERROR) {
NSLog(#"Successfully inserted");
sqlite3_last_insert_rowid(db);
}
//
// BOOL success = [fileMgr fileExistsAtPath:dbPath];
//
// if(!success)
// {
// NSLog(#"Cannot locate database file '%#'.", dbPath);
// }
// if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
// {
// NSLog(#"An error has occured: %#", sqlite3_errmsg(db));
//
// }
// const char *sql = "SELECT F_Keyword FROM wordss";
const char *sql = "SELECT * FROM Sheet1";
NSLog(#"Successfully selected from database");
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"Problem with prepare statement: %#", sqlite3_errmsg(db));
}else{
NSLog(#"Got in the else tag");
while (sqlite3_step(sqlStatement)==SQLITE_ROW /*&& PAss == NO*/) {
NSLog(#"Got in the while tag");
Author * author = [[Author alloc] init];
NSLog(#"Author initialized");
author.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,10)];
NSLog(#"Initialization ok");
// NSLog(author.name);
if(/*author.name == #"NO" &&*/ HighLighted == NO){
//const char *sql2 = "INSERT INTO Sheet1 ";
[AddBut setImage:[UIImage imageNamed:#"apple-logo copy.png"] forState:UIControlStateNormal];
NSLog(#"We have not selected it as fav yet");
// [AddBut setSelected:NO]; //btn changes to normal state
NSLog(#"The button was NOt highlighted and now is");
HighLighted = YES;
break;
}
else
{
NSLog(#"We have selected it as fav");
[AddBut setImage:[UIImage imageNamed:#"apple-logo.png"] forState:UIControlStateNormal];
[AddBut setSelected:NO]; //btn changes to normal state
NSLog(#"The button was highlighted and now is NOt");
HighLighted = NO;
break;
// [self viewDidLoad];
// PAss = YES;
}
// [Favo release];
// NSLog(Favo);
// author.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
// author.title = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
// author.genre = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 4)];
// [theauthors addObject:author];
}
}
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement: %#", sqlite3_errmsg(db));
}
#finally {
// sqlite3_finalize(sqlStatement);
// sqlite3_close(db);
UIAlertView *fin = [[UIAlertView alloc]
initWithTitle:#"Query" message:#"DOne with Click Button" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[fin show];
return Favo;
}
Thank you #crazyCreator for your answer !!!!
[self authorList2];
[self.tableView reloadData];

Update field value of Sqlite database using Xcode

I have an application with a save button. When I click on the save button, the application should automatically update the value of a row and set it to YES.
Till now I have the following code, but it isn't actually working. Keep in mind, my application is a tab menu application. In the first view I have the table cells, and on click I go to another view controller, a details view controller, where the button is present.
When I click on the button, the value of 'Fav' field in the database should change from NO to YES.
This is my code:
- (IBAction)AddButClick:(UIButton *)sender {
[AddBut setImage:[UIImage imageNamed:#"apple-logo copy.png"] forState:UIControlStateSelected];
[AddBut setImage:[UIImage imageNamed:#"apple-logo copy.png"] forState:UIControlStateHighlighted];
Favo = [[NSMutableArray alloc] initWithCapacity:1000000];
// NSLog(authorNAme);
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
// NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"dictionary.sqlite"];
//NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"authorsDb2.sqlite"];
// NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"FinalDb.sqlite"];
//NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"xxJuridique-FINAL-OK.sqlite"];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"data.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(#"An error has occured: %#", sqlite3_errmsg(db));
}
sqlite3_stmt *compiled_statement1;
if(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK) {
//const char *sqlStatement =
NSString *formatedSql = [NSString stringWithFormat:#"UPDATE Sheet1 SET Fav = 'YES' WHERE field3 = '%#' " , authorNAme2];
NSLog(#"This is the query %#",formatedSql);
const char *sql = [formatedSql UTF8String];
NSLog(#" !!!!!!!! In the middle of it !!!!!!!!!!!!");
if (sqlite3_prepare_v2(db, sql, -1, &compiled_statement1, NULL) != SQLITE_OK) {
NSLog(#"!!!!!!!!!!!!!!!!!!!ERRRRROOOOOOORRRRRRRRR!!!!!!!!!!!!!!!!!!!!!!!!!");
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db));
}
// sqlite3_exec(db, [compiled_statement1 UTF8String], NULL, NULL, NULL);
//sqlite3_bind_text(compiled_statement1, 1, [formatedSql UTF8String], -1, SQLITE_TRANSIENT);
int success = sqlite3_step(compiled_statement1);
sqlite3_reset(compiled_statement1);
if (success != SQLITE_ERROR) {
NSLog(#"Successfully inserted");
sqlite3_last_insert_rowid(db);
}
sqlite3_finalize(compiled_statement1);
}
//
// BOOL success = [fileMgr fileExistsAtPath:dbPath];
//
// if(!success)
// {
// NSLog(#"Cannot locate database file '%#'.", dbPath);
// }
// if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
// {
// NSLog(#"An error has occured: %#", sqlite3_errmsg(db));
//
// }
// const char *sql = "SELECT F_Keyword FROM wordss";
const char *sql = "SELECT * FROM Sheet1";
NSLog(#"Successfully selected from database");
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"Problem with prepare statement: %#", sqlite3_errmsg(db));
}else{
NSLog(#"Got in the else tag");
while (sqlite3_step(sqlStatement)==SQLITE_ROW /*&& PAss == NO*/) {
NSLog(#"Got in the while tag");
Author * author = [[Author alloc] init];
NSLog(#"Author initialized");
author.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,10)];
NSLog(#"Initialization ok");
// NSLog(author.name);
if(/*author.name == #"NO" &&*/ HighLighted == NO){
//const char *sql2 = "INSERT INTO Sheet1 ";
[AddBut setImage:[UIImage imageNamed:#"apple-logo copy.png"] forState:UIControlStateNormal];
NSLog(#"We have not selected it as fav yet");
// [AddBut setSelected:NO]; //btn changes to normal state
NSLog(#"The button was NOt highlighted and now is");
HighLighted = YES;
// PAss = YES;
// [self release];
break;
}
else
{
NSLog(#"We have selected it as fav");
[AddBut setImage:[UIImage imageNamed:#"apple-logo.png"] forState:UIControlStateNormal];
[AddBut setSelected:NO]; //btn changes to normal state
NSLog(#"The button was highlighted and now is NOt");
HighLighted = NO;
break;
// [self viewDidLoad];
// PAss = YES;
}
// [Favo release];
// NSLog(Favo);
// author.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
// author.title = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
// author.genre = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 4)];
// [theauthors addObject:author];
}
}
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement: %#", sqlite3_errmsg(db));
}
#finally {
// sqlite3_finalize(sqlStatement);
sqlite3_close(db);
return Favo;
}
The problem was not in the add but click, it was actually in the viewWillAppear, in which i should have done :
[self authorList2];
[self.tableView reloadData] ;
In order to load the mutable array and then reload data

Unused variable question

I have the following code in the implementation file:
#import "Possession.h"
#implementation Possession
#synthesize possessionName,serialNumber, valueInDollars, dateCreated;
+ (id)randomPossession
{
// Create an array of three adjectives
NSArray *randomAdjectiveList = [NSArray arrayWithObjects:#"Fluffy",
#"Rusty",
#"Shiny", nil];
// Create an array of three nouns
NSArray *randomNounList = [NSArray arrayWithObjects:#"Bear",
#"Spork",
#"Mac", nil];
// Get the index of a random adjective/noun from the lists
// Note: The % operator, called the modulo operator, gives
// you the remainder. So adjectiveIndex is a random number
// from 0 to 2 inclusive.
unsigned long adjectiveIndex = rand() % [randomAdjectiveList count];
unsigned long nounIndex = rand() % [randomNounList count];
NSString *randomName = [NSString stringWithFormat:#"%# %#",
[randomAdjectiveList objectAtIndex:adjectiveIndex],
[randomNounList objectAtIndex:nounIndex]];
int randomValue = rand() % 100;
NSString *randomSerialNumber = [NSString stringWithFormat:#"%c%c%c%c",
'O' + rand() % 10,
'A' + rand() % 26,
'O' + rand() % 10,
'A' + rand() % 26,
'O' + rand() % 10];
// Once again, ignore the memory problems with this method
Possession *newPossession =
[[self alloc] initWithPossessionName:randomName
valueInDollars:randomValue
serialNumber:randomSerialNumber];
return newPossession;
return [newPossession autorelease];
}
- (id) initWithPossessionName:(NSString *)name
valueInDollars:(int)value
serialNumber:(NSString *)sNumber
{
// Call the superclass's designated initializer
[super init];
// Give the instance variables initial values
[self setPossessionName:name];
[self setSerialNumber:sNumber];
[self setValueInDollars:value];
dateCreated = [[NSDate alloc] init];
// Return the address of the newly initialized object
return self;
}
- (id) init
{
return [self initWithPossessionName:#"Possession"
valueInDollars:0
serialNumber:#""];
}
- (NSString *)description;
{
NSString *descriptionString =
[[NSString alloc] stringWithFormat:#"%# (%#): Worth $%d, recorded on %#",
possessionName,
serialNumber,
valueInDollars,
dateCreated];
}
- (void) dealloc
{
[possessionName release];
[serialNumber release];
[dateCreated release];
[super dealloc];
}
#end
For the descriptionString, I am getting an unused variable error, and for the line which reads "dateCreated],", I am getting a Thread 1: Program received signal: "SIGABRT" error which opens up the debugger. For the line immediately following, I am receiving a Control reaches end of non-void function error.
Here is the header file:
#import <Foundation/Foundation.h>
#interface Possession : NSObject {
NSString *possessionName;
NSString *serialNumber;
int valueInDollars;
NSDate *dateCreated;
}
+ (id)randomPossession;
- (id)initWithPossessionName:(NSString *)name
valueInDollars:(int)value
serialNumber:(NSString *)number;
- (id) init;
#property (nonatomic, copy) NSString *possessionName;
#property (nonatomic, copy) NSString *serialNumber;
#property (nonatomic) int valueInDollars;
#property (nonatomic, readonly) NSDate *dateCreated;
#end
Here is the main file:
#import <Foundation/Foundation.h>
#import "Possession.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Create a mutable array, store its address in items variable
NSMutableArray *items = [[NSMutableArray alloc] init];
for(int i = 0; i < 10; i++) {
Possession *p = [Possession randomPossession];
[items addObject:p];
}
for (int i = 0; i < [items count]; i++)
NSLog(#"%#", [items objectAtIndex:i]);
[items release];
// Don't leave items pointed at freed memory!
items = nil;
[pool drain];
return 0;
}
For the description method,
the local variable descriptionString is never used other then being created.
it's a non-void method and you never return anything
The SIGABRT is likely to be caused by one of the possessionName, serialNumber, valueInDollars, dateCreated being nil.

Resources