How do you get the data setup in the dashboard.
I have added a key and a value in "Deep Link Data(Advanced)"
In Branch.io dashboard
Login / Menu: Marketing / Actions / Edit
I have this in objective-c:
Branch *branch = [Branch getTestInstance];
[branch setDebug];
NSDictionary *params = [branch getLatestReferringParams];
I am working in "test" of the dashboard.
Alex with Branch here:
The $ symbol is only used to indicate reserved system control parameters (you can find a list of these parameters here). Since you're setting a custom data key, the key : value pair you're using in the example actually just needs to be myplan : 10.
Your session initialization snippet is also a bit odd. Would you mind sharing where you found it? We might have some documentation somewhere that's out of date...
Branch *branch = [Branch getTestInstance];
[branch setDebug];
[branch initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {
if (!error) {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
NSLog(#"params: %#", params.description);
}
}];
Related
Using the Nest API I am trying to set the nest thermostat's away status
Reading & Setting for temperature is working fine.
I have the read and write permissions correctly configured for both
thermostat temperature control and for setting thermostat away
I can read the status correctly. Does anyone with some experience of this API know how to go about setting this status?
in "FirebaseManager.h"
Firebase *newFirebase2 = [self.rootFirebase childByAppendingPath:#"structures"];
[newFirebase2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
// Put structures into a dictionary
NSMutableDictionary *dict = snapshot.value;
NSLog(#"\n\n\n1. Away Status = %#", [dict valueForKey:#"away"]);
NSLog(#"Dict Contents %#", dict); // <--- Reads thermostat status. A string either home or away
dict[#"away"] = #"away"; //<--- Changes status string but not a correct solution, and does not set the stat to away
//Changes status name but this is not parsed back to firebase
NSLog(#"new status = %#", [dict valueForKey:#"away"]);
}];
To update a child value
assume this structure
structures
structure_id_0
away: "home"
setting the away node to a string of away (this code is quite verbose so it's easy to follow)
Firebase *structuresRef = [self.rootFirebase childByAppendingPath:#"structures"];
//build a reference to where we want to write structures/structure_id/
Firebase *thisStructureRef = [structuresRef childByAppendingPath:#"structure_id_0"];
Firebase *awayRef = [thisStructureRef childByAppendingPath:#"away"];
[awayRef setValue:#"away"];
Now, if you want to do this for snapshots that have been retrieved via observing a node with FEventTypeChildAdded, the node name will be whatever is used in place of structure_id_0. The is the key of the key:value pair.
That can be obtained via snapshot.key.
So NSString *key = snapshot.key
Substitute the key variable in for #"structure_id_0" in the path.
Also check out Firebase Writing Data, and then the updateChildValues for another option.
I have an Objective-C application (https://github.com/NBICreator/NBICreator) with a privileged helper tool.
I have a few different privileged tasks the helper will need to perform during one build, and I want to have the user authenticate only once to perform those tasks.
The authorization works, but I can't seem to reuse the session in the helper. The user always have to authenticate for every step, even if I supply the exact same right to the Security Server and use the same AuthenticationRef.
I have read the docs and tested the pre-authentication methods in the main app first, and tried printing out (and retaining the auth session in the helper as well). But nothing I've tried have yet to work successfully.
I need som help figuring out why the Security Server feel the need to reauthenticate.
The code on GitHub in the Master Branch is current, and what I'm trying and testing by changing things back and forth. With that code, the user have to authenticate each time I call a helper function, even if I use the same authentication right.
This is what the right looks like in the authorization database:
class = rule;
created = "470329367.933364";
"default-prompt" = {
"" = "NBICreator is trying to start an Imagr workflow.";
};
identifier = "com.github.NBICreator";
modified = "470329367.933364";
requirement = "identifier \"com.github.NBICreator\" and anchor apple generic and certificate leaf[subject.CN] = \"Mac Developer: Erik Berglund (BXUF2UUW7E)\" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */";
rule = (
"authenticate-admin"
);
version = 0;
This is where I define the right: https://github.com/NBICreator/NBICreator/blob/master/NBICreator/Helper/NBCHelperAuthorization.m#L36-L43
NSStringFromSelector(#selector(authorizeWorkflowImagr:withReply:)) : #{
kCommandKeyAuthRightName : #"com.github.NBICreator.workflowImagr",
kCommandKeyAuthRightDefault : #kAuthorizationRuleAuthenticateAsAdmin,
kCommandKeyAuthRightDesc : NSLocalizedString(
#"NBICreator is trying to start an Imagr workflow.",
#"prompt shown when user is required to authorize to add a user"
)
},
And this is where I check if the user is authenticated:
https://github.com/NBICreator/NBICreator/blob/master/NBICreator/Helper/NBCHelperAuthorization.m#L222-L253
+ (NSError *)checkAuthorization:(NSData *)authData command:(SEL)command authRef:(AuthorizationRef)authRef {
#pragma unused(authData)
NSError * error;
OSStatus err = 0;
AuthorizationItem oneRight = { NULL, 0, NULL, 0 };
AuthorizationRights rights = { 1, &oneRight };
oneRight.name = [#"com.github.NBICreator.workflowImagr" UTF8String];
err = AuthorizationCopyRights(
authRef,
&rights,
NULL,
kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed,
NULL
);
if ( err != errAuthorizationSuccess ) {
NSString *message = CFBridgingRelease(SecCopyErrorMessageString(err, NULL));
error = [NSError errorWithDomain:[[NSProcessInfo processInfo] processName] code:err userInfo:#{ NSLocalizedDescriptionKey : message }];
}
return error;
}
As you can see there, I'm testing by setting a hardcoded right name to try and resue that right to the Security Server.
I'm stumped right now, and can't seem to find a way forward. Hoping someone here might know where to look.
I found the answer in how I set up the right in the rights database.
I was using the default code from the Apple example EvenBetterAuthorizationExample for creating and using the rights. But that only points to this documentation for the different rights to use.
None of those were helping me with authenticatin once and the having the helper be authenticated the next time I request authentication for the same right.
After some digging and looking into the actual rules in the authorization database I found a way to copy the rule that AuthenticateWithPrivileges uses, that works by authenticating for 5 minutes until requiring re-authentication.
So, I changed my code for creating my custom right from this:
NSStringFromSelector(#selector(addUsersToVolumeAtPath:userShortName:userPassword:authorization:withReply:)) : #{
kCommandKeyAuthRightName : NBCAuthorizationRightAddUsers,
kCommandKeyAuthRightDefault : #kAuthorizationRuleAuthenticateAsAdmin,
kCommandKeyAuthRightDesc : NSLocalizedString(
#"NBICreator is trying to add a user.",
#"prompt shown when user is required to authorize to add a user"
)
},
To this:
NSStringFromSelector(#selector(addUsersToVolumeAtPath:userShortName:userPassword:authorization:withReply:)) : #{
kCommandKeyAuthRightName : NBCAuthorizationRightAddUsers,
kCommandKeyAuthRightDefault : #{
#"class": #"user",
#"group": #"admin",
#"timeout": #(300),
#"version": #(1),
},
kCommandKeyAuthRightDesc : NSLocalizedString(
#"NBICreator is trying to add a user.",
#"prompt shown when user is required to authorize to add a user"
)
},
So, instead of using #kAuthorizationRuleAuthenticateAsAdmin as the RightDefault, i passed in this dict:
#{
#"class": #"user",
#"group": #"admin",
#"timeout": #(300),
#"version": #(1),
},
After that, my helper can request authorization from the user, and then I can reuse that session for the same right during 5 minutes without asking the user again.
I need to pass data on subscribing to a notification, so, I've taken the example code in Module_07_04_iOSNativePush app and added the following code to the connect method (in ViewController.m):
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:
#"userName", #"DoronK",
#"password", #"testPwd", nil];
id pushit = [WLPushOptions new];
[pushit addSubscriptionParameter:#"test" :#"Test1"];
[pushit addSubscriptionParameters:dic];
[[WLPush sharedInstance] subscribe:readyToSubscribeListener.alias: pushit :connectListener];
This does not throw any errors, but, when I run the example PushAdapter code, and adding to the adapter using this:
var usub = 'json:'+JSON.stringify(userSubscription);
...
return { result: "Notification sent to user :: " + userId +
", wait " + waittime + " before sending another. UserSub:" + usub};
The result in the adapter is:
{
"isSuccessful": true,
"result": "Notification sent to user :: worklight, wait 0 before sending another.
UserSub:json:{\"userId\":\"worklight\",\"state\":{}}"
}
I would expect the variables that I passed in via the dictionary under "state", correct? Is there another way in the adapter to get the parameters that were passed in on the [WLPush subscribe] call?
As you can probably tell, I am VERY new to Objective C, so, don't assume the call to the subscribe is done correctly. Also, I'm using Worklight Studio 6 with Fix Pack 1.
The state will not contain the parameters passed during subscribe call. You need to first get the device subscription. The options object of the device subscription will contain the parameters passed during subscribe.
For eg.
var deviceSubscriptions=userSubscription.getDeviceSubscriptions();
var usub = 'json:'+JSON.stringify(deviceSubscriptions[0]);
Please refer to the following infocenter link
http://pic.dhe.ibm.com/infocenter/wrklight/v6r0m0/topic/com.ibm.worklight.help.doc/apiref/r_method_usersubscription_getdev.html
I'm using the dropbox api for iOS and have been messing with the loadDelta function. I get the whole "key" that is sent, and I get how the structure is set up (see below this code), but what I don't understand is how to download the file that is sent and how to save it to the iOS device. Does anyone have any insight on how to do this?
-(void)restClient:(DBRestClient *)client loadedDeltaEntries:(NSArray *)entries reset:(BOOL)shouldReset cursor:(NSString *)cursor hasMore:(BOOL)hasMore{
for (DBDeltaEntry *file in entries) {
if(!file.metadata.isDirectory){
NSLog(#"File: %# ", file.metadata.filename );
}else {
NSLog(#"Directory: %# ", file.metadata.filename );
}
}
}
The call sends back an array called entries. Each entry in entries is this:
#interface DBDeltaEntry : NSObject {
NSString *lowercasePath;
DBMetadata *metadata;
}
with the DBMetadata object being:
#interface DBMetadata : NSObject <NSCoding> {
BOOL thumbnailExists;
long long totalBytes;
NSDate* lastModifiedDate;
NSDate *clientMtime; // file's mtime for display purposes only
NSString* path;
BOOL isDirectory;
NSArray* contents;
NSString* hash;
NSString* humanReadableSize;
NSString* root;
NSString* icon;
NSString* rev;
long long revision; // Deprecated; will be removed in version 2. Use rev whenever possible
BOOL isDeleted;
NSString *filename;
}
What I can't figure out is how to recursively set up my offline structure or the best practice for doing so. My assumption is though, using delta, I won't need to keep a database of the files I have saved for update purposes, right?
The /delta call only tells you what has changed. It doesn't itself give you any access to the file contents. If you want to download any particular file that you heard about from /delta, you should use the path it gave you with the /files (GET) call to download the file:
https://www.dropbox.com/developers/reference/api#files-GET
(The iOS SDK makes this available as the loadFile function.)
The /delta call does save you the trouble of having to call /metadata to manually figure out what has changed and keep track of the current state, but note that the Dropbox API best practices ( https://www.dropbox.com/developers/reference/bestpractice ) do say that you shouldn't download anything until the user asks for it.
One scheme is to use a SQLite table with the following columns:
lc_path: The lowercase'd path of the file (primary key for this table)
name: The name of the file
lc_parent_path: The lowercase'd path of the parent folder
other metadata... (last modified, revision, is_dir, etc.)
So when processing an "add" /delta entry, you insert a row into the table (you might have to replace an existing row).
When processing a "delete" entry for the path /a/b/c, you need to delete all children as well, so you can do DELETE ... WHERE lc_path = "/a/b/c" and then DELETE ... WHERE lc_path LIKE "/a/b/c/%".
If you want to query the database for a list of immediate children of the folder "/a/b/c", do SELECT ... WHERE lc_parent_path = "/a/b/c"
You may have noticed that you the path is stored somewhat redundantly (lc_parent_path+name and lc_path). This probably won't be a problem. But if you find that your database is too large and that most of the space is going toward storing the path strings, there are encoding tricks you can do.
I need to find out the number of routes from a source to a destination using the Google maps API, and then find, among those, which one is the shortest route.
I am able to get one route by using this code
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t {
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.google.com/maps?output=dragdir&saddr=%#&daddr=%#", saddr, daddr];
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSLog(#"api url: %#", apiUrl);
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl];
NSString* encodedPoints = [apiResponse stringByMatching:#"points:\\\"([^\\\"]*)\\\"" capture:1L];
return [self decodePolyLine:[encodedPoints mutableCopy]];
}
but I'm unable to get multiple routes.
I'm new to using the Google Maps API; I followed this tutorial.
How can I do this? Can any one please post some sample code or a tutorial?
alternatives (optional), if set to
true, specifies that the Directions
service may provide more than one
route alternative in the response.
Note that providing route alternatives
may increase the response time from
the server.
From The Google Directions API
You need to add in your query link alternatives=true
For getting the multiple routes you have to use the standard google direction api. Through this api you can get different routes on the bases of traveling mode you select in api ie driving, walking or bicycling( bicycling route availabel in US only) For example : http://maps.googleapis.com/maps/api/directions/xml?origin=srcLatitude,srcLongitude&destination=destLatitude,destLongitude&mode=driving&sensor=false
Here you can give the source and destination latitude and longitude and change the value of mode parameter to driving, walking or bicycling to get multiple route.