MPTweakValue without internet - ios

I try to implement Mixpanel's tweaks into my app for A/B testing. This is my code:
if (MPTweakValue(kFeaturedOffersTweak, NO)) {
return MenuItemRowHeight;
}
else {
return 0;
}
On the first lunch everything is OK and tweak value is YES. Then I switch off internet on my iPhone, open run again and tweak value is NO.
What is correct way to use Mixpanel's tweak without internet?

So, I created my custom manager, where I implemented tweaks' persistency.
Please, let me know, if you have better solution.
My code:
-(void)initManager {
[[Mixpanel sharedInstance] joinExperimentsWithCallback:^{
USE_SETTINGS;
SETTINGS_SETBOOL(kPreferredPartnersTweak, MPTweakValue(kPreferredPartnersTweak, NO));
SYNCHRONIZE_SETTINGS;
//===
SEND_NOTIF(kTweaksUpdated, nil);
}];
}
-(BOOL)getTweakWithName:(NSString*)tweakName {
BOOL result = NO;
//===
USE_SETTINGS;
if (SETTINGS_BOOL(tweakName)) {
result = SETTINGS_BOOL(tweakName);
}
else {
result = MPTweakValue(kPreferredPartnersTweak, NO);
}
//===
return result;
}
USE_SETTINGS, SETTINGS_BOOL, SYNCHRONIZE_SETTINGS is my macros wrappers for working with NSUserDefaults.

Related

How can I use the result returned in a delegate method to fire a callback in React-Native (iOS)

So I'm in a bit of a pickle here...
I'm creating an application that requires me to use an awkward SDK for a specific hardware api - and to get the status of anything, rather than return a value it fires off a delegate method where the value is accessible there as an argument for the delegate method. This is making callbacks to React-Native a challenge.
Here is my basic method being called from React:
RCT_EXPORT_METHOD(openSirenAlarm: (RCTResponseSenderBlock) callback)
{
cameraControl.cameraSiren.delegate = self;
[cameraControl.cameraSiren playCameraSiren];
callback(#[#(error), #(response)]);
}
RCT_EXPORT_METHOD(closeSirenAlarm: (RCTResponseSenderBlock) callback)
{
cameraControl.cameraSiren.delegate = self;
[cameraControl.cameraSiren stopCameraSiren];
callback(#[#(error), #(response)]);
}
And here are the delegate methods provided in the SDK:
#pragma mark CameraSirenDelegate
- (void) cameraSiren:(CameraSiren *)cameraSiren stopResult:(ENUM_APP_RESULT)result
{
NSLog(#"stop result: %u", result);
if (result == RESULT_SUCCESS)
{
NSLog(#"stop success");
error = 0;
response = 1;
}
else
{
error = 1;
response = 0;
}
}
- (void) cameraSiren:(CameraSiren *)cameraSiren playResult:(ENUM_APP_RESULT)result
{
NSLog(#"start result: %u", result);
if (result == RESULT_SUCCESS)
{
NSLog(#"start success");
error = 0;
response = 1;
}
else
{
error = 1;
response = 0;
}
}
I'm having a couple issues:
As you can see, I'm setting the error result in the delegate methods, but the callback fires right away (including before they're even set the first time) - so at best they're one action behind in terms of information.
I've played with RCTEventEmitters but I find them to be generally sloppy and unreliable - generally firing at least twice and causing me a bit of a headache (if this is a common thing that anyone can help me with I'd gladly use emission).
Is there an obvious way to do this that I'm missing, or a smarter design pattern to handle this?

How to stop JavaScriptCore JSContext evaluating by force on iOS?

Sometime the script being evaluated should be stopped by force, but I can't find a way to achieve this. Someone pointed out JSContextGroupSetExecutionTimeLimit might work, but It doesn't in my testing, can anyone help?
Another reference: https://github.com/phoboslab/JavaScriptCore-iOS/issues/14
My code:
int extendTerminateCallbackCalled = 0;
static bool extendTerminateCallback(JSContextRef ctx, void *context)
{
extendTerminateCallbackCalled++;
if (extendTerminateCallbackCalled == 2) {
JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
return false;
}
return true;
}
+ (void)stop
{
JSGlobalContextRef ref = [_context JSGlobalContextRef];
JSContextGroupRef contextGroup = JSContextGetGroup(ref);
JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
}
Here is an idea of possible approach
+ (void)stop
{
JSContext *context = [JSContext currentContext]; // or whichever your
// set property of JS global object to specific know value
// that should be checked inside JS code regularly during
// long operations and interrupt self execution
context[#"externallyCancelled"] = #(YES);
}

Epson TM-T88V-i print only once

I've a problem with an Epson TM-T88V-i printer, I can print the first time but after I receive always a EPOS2_ERR_CONNECT error.
I use the example in the SDK and it has this problem.
This is the code:
int result = EPOS2_SUCCESS;
if (self.printer == nil) {
return NO;
}
result = [self.printer connect:#"TCP:192.168.1.15" timeout:EPOS2_PARAM_DEFAULT];
if (result != EPOS2_SUCCESS) {
return NO;
}
result = [self.printer beginTransaction];
if (result != EPOS2_SUCCESS) {
[self.printer disconnect];
return NO;
}
After the first time it goes in the if after the connect method with the EPOS2_ERR_CONNECT
I must restart the printer to reprint something.
I had the same problem months ago...
For the TM-T88V-i printers you must connect with another syntax:
use <connection type>:<identifier>[<device ID>] instead of <connection type>:<identifier>
So your code is something like this:
result = [self.printer connect:#"TCP:192.168.1.15[local_printer]" timeout:EPOS2_PARAM_DEFAULT];
N.B. local_printer is the default identifier.

Common way to execute a stored proc from both ColdFusion and Railo

I think I've gotten the most simplest scenario built. I just want to pass it by everyone for a sanity check. Here's the idea:
GetErrorCodes.cfm does the following:
<cfscript>
response = new ErrorCodes().WhereXXX(); // ACF or Railo, doesn't matter
</cfscript>
ErrorCodes.cfc:
function WhereXXX() {
return new sproc().exec('app.GetErrorCodes'); // All my functions will do this instead of executing the sproc themselves.
}
sproc.cfc:
component {
function exec(procedure) {
local.result = {};
if (server.ColdFusion.productname == 'Railo') {
return new Railo().exec(arguments.procedure); // Has to be outside of sproc.cfc because ColdFusion throws a syntax error otherwise.
}
local.svc = new storedProc();
local.svc.setProcedure(arguments.procedure);
local.svc.addProcResult(name='qry');
try {
local.obj = local.svc.execute();
local.result.Prefix = local.obj.getPrefix();
local.result.qry = local.obj.getProcResultSets().qry;
} catch(any Exception) {
request.msg = Exception.Detail;
}
return local.result;
}
Railo.cfc:
component {
function exec(procedure) {
local.result = {};
try {
storedproc procedure=arguments.procedure result="local.result.Prefix" returncode="yes" {
procresult name="local.result.qry";
}
} catch(any Exception) {
request.msg = Exception.Message;
}
return local.result;
}
}
So I've been working on this all day, but tell me, is this a sane way to keep the source code the same if it's to be run on either a ColdFusion server or a Railo server?
Um... just use <cfstoredproc> instead of trying to use two different CFScript approaches that are mutually exclusive to each other of the CFML platforms.

How do I detect a first-run in Firefox a addon?

I would like to know the simplest way to detect a first-run in a Firefox addon. I prefer not to use the (SQLite) Storage API as this seems way overkill for this simple usecase.
I guess my question could also be: what is the simplest way to store a flag?
There you go: http://mike.kaply.com/2011/02/02/running-add-on-code-at-first-run-and-upgrade/
var firstrun = Services.prefs.getBoolPref("extensions.YOUREXT.firstrun");
var curVersion = "0.0.0";
if (firstrun) {
Services.prefs.setBoolPref("extensions.YOUREXT.firstrun", false);
Services.prefs.setCharPref("extensions.YOUREXT.installedVersion", curVersion);
/* Code related to firstrun */
} else {
try {
var installedVersion = Services.prefs.getCharPref("extensions.YOUREXT.installedVersion");
if (curVersion > installedVersion) {
Services.prefs.setCharPref("extensions.YOUREXT.installedVersion", curVersion);
/* Code related to upgrade */
}
} catch (ex) {
/* Code related to a reinstall */
}
}
Maybe a better solution would be:
/**
* Check if this is the first run of the addon
*/
function checkFirstRun(){
if(ss.storage.firstRun == undefined){
ss.storage.firstRun = false;
return true;
}
else{
return false;
}
}

Resources