I am new to Gimbal framework and I am trying to use this framework at basic level.
Here is my code:
- (void)viewDidLoad
{
....
self.contextCoreConnector = [[QLContextCoreConnector alloc] init];
self.contextCoreConnector.permissionsDelegate = self;
self.contextPlaceConnector = [[QLContextPlaceConnector alloc] init];
self.contextPlaceConnector.delegate = self;
self.contextInterestsConnector = [[PRContextInterestsConnector alloc] init];
self.contextInterestsConnector.delegate = self;
self.contentConnector = [[QLContentConnector alloc] init];
self.contentConnector.delegate = self;
[self.contextCoreConnector checkStatusAndOnEnabled:^(QLContextConnectorPermissions *contextConnectorPermissions) {
if (contextConnectorPermissions.subscriptionPermission)
{
if (self.contextPlaceConnector.isPlacesEnabled)
{
[self displayLastKnownPlaceEvent];
}
}
}
disabled:^(NSError *error) {
NSLog(#"%#", error);
if (error.code == QLContextCoreNonCompatibleOSVersion)
{
NSLog(#"%#", #"SDK Requires iOS 5.0 or higher");
}
else
{
enableSDKButton.enabled = YES;
placeNameLabel.text = nil;
contentInfoLabel.text = nil;
}
}];
}
#pragma mark - QLContextPlaceConnectorDelegate methods
- (void)didGetPlaceEvent:(QLPlaceEvent *)placeEvent
{
NSLog(#"Got place event");
[self savePlaceEvent:placeEvent];
[self displayLastKnownPlaceEvent];
}
- (void)didGetContentDescriptors:(NSArray *)contentDescriptors
{
contentInfoLabel.text = [[contentDescriptors lastObject] title];
NSLog(#"didGetContentDescriptors : %#",contentInfoLabel.text);
[self displaceLastKnownContentDescriptor];
for (QLContentDescriptor *contentDescriptor in contentDescriptors)
{
[self postOneContentDescriptorLocalNotification:contentDescriptor];
}
}
But the method
- (void)didGetContentDescriptors:(NSArray *)contentDescriptors
is not called. I have no idea why this is happening. In the demo app provided with the SDK this method is get called but not in my app. I have matched the code for both the apps but I am unable to find the issue in my app.
I will be very thankful if anyone can help.
is your didGetPlaceEvent delegate method being called?
Related
I have a screen which shows favourite locations and if a user wants to add new location he can search using uisearchcontroller and add it to favourite location's list.
The problem is that once i make the api call for autocomplete the list of searched locations is visible but i cannot select or scroll the table.
I know that the problem is where i set the uisearchcontroller. but i do not know the right way to do it.
I am newbie in iOS so ur suggestions will be welcome.
the following is the GithubRepository for the project(incase ul want to try out the app and make suggestions)
and heres the related code where i beleive the problem exists.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
favList = [[NSMutableArray alloc] init];
searchList = [[NSMutableArray alloc]init];
self.table.dataSource = self;
self.table.delegate = self;
[self initSearch];
}
#pragma mark UI Search methods
-(void) initSearch
{
FavouriteViewController *searchResultsController = [[FavouriteViewController alloc] init];
searchResultsController.table.dataSource = self;
searchResultsController.table.delegate = self;
searchResultsController.table.allowsSelectionDuringEditing = YES;
searchResultsController.table.allowsSelection = YES;
self.search = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
self.definesPresentationContext = NO;
self.table.tableHeaderView = self.search.searchBar;
self.search.searchResultsUpdater = self;
self.search.searchBar.delegate = self;
self.search.dimsBackgroundDuringPresentation = NO;
}
didSelectRowAtIndex method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.search.active) {
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObjectModel *place = [NSEntityDescription insertNewObjectForEntityForName:#"Place" inManagedObjectContext:context];
NSString *places =[searchList[indexPath.row] valueForKey:#"name"];
if (![favList containsObject:places])
{
NSString *lati = [searchList[indexPath.row] valueForKey:#"lat"];
NSString *longi = [searchList[indexPath.row] valueForKey:#"lon"];
if (places != NULL && lati != NULL && longi != NULL)
{
[place setValue:places forKey:#"placeName"];
[place setValue:lati forKey:#"latitude"];
[place setValue:longi forKey:#"longitude"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
}
[self.search setActive:NO];
filtered = NO;
[self getalldata];
[self.table reloadData];
}
else
{
NSManagedObject *device = [favList objectAtIndex:indexPath.row];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.SJI.Weather-App"];
[defaults setObject:[device valueForKey:#"placeName"] forKey:#"favSet"];
[[self navigationController] popToRootViewControllerAnimated:YES];
}
}
when I launch App for first time (App is not installed perviously) on simulator, the instance of CBLQueryEnumerator count returns nil.
I found it by placing breakpoints and executing
po enumeratorResult
but the enumerator object seems to be allocated.
When I launch App for second time (in this case App is already installed on simulator) the instance of CBLQueryEnumerator count returns 5 (I have 5 documents in DB).
Am I making mistake in using CBLQuery or CBLQueryEnumerator please guide me correct.
viewContoller.m
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.progressView.progressViewStyle = UIProgressViewStyleBar;
[self.progressView setProgress:2.5 animated:YES];
self.cbObject = [CouchBaseObject sharedInstance];
self.syncURLLabel.text = [NSString stringWithFormat:#"%#",self.cbObject.syncURL];
self.documentList = [NSMutableArray array];
[self addDocumentToTicketModel:self.cbObject.database];
if(self.cbObject.pull.status == kCBLReplicationOffline || self.cbObject.pull.status != kCBLReplicationActive){
[self performSelector:#selector(pushTicketDetailViewController) withObject:self afterDelay:2.5];
}
}
-(void)addDocumentToTicketModel:(CBLDatabase*)database{
CBLView* view = [database viewNamed:#"_temp_view"];
if (!view.mapBlock) {
[view setMapBlock:MAPBLOCK({
if (doc) {
emit(doc,#"1");
}
})version:#"1.0"];
}
CBLQuery* query = [view createQuery];
[query runAsync:^(CBLQueryEnumerator * enumeratorResult, NSError * error) {
if(!error){
for (CBLQueryRow* row in enumeratorResult) {
CBLDocument* document = [database documentWithID:row.documentID];
Ticket* ticket = [Ticket modelForDocument:document];
NSLog(#"Ticket ; %#",ticket.propertiesToSave);
[self.documentList addObject:ticket];
}
}
}];
}
#end
CouchBaseObject.m
#implementation CouchBaseObject
-(instancetype)init{
self = [super init];
if(self){
NSError* error;
self.manager = [CBLManager sharedInstance];
if(!self.manager){
NSLog(#"manager fail");
return nil;
}
self.database = [self.manager databaseNamed:#"couch_sample_one" error:&error];
if(!self.database){
NSLog(#"database fail");
return nil;
}
[self initReplication];
}
return self;
}
+(CouchBaseObject*)sharedInstance{
static CouchBaseObject* sharedInstance = nil;
if(sharedInstance == nil){
sharedInstance = [[CouchBaseObject alloc]init];
}
return sharedInstance;
}
-(void)initReplication{
self.syncURL = [[NSURL alloc]initWithString:#"http://***.***.***.***:5984/couch_sample_one"];
self.pull = [self.database createPullReplication:self.syncURL];
self.push = [self.database createPushReplication:self.syncURL];
self.pull.continuous = NO;
self.push.continuous = NO;
[self startReplication];
}
-(void)startReplication{
[self.push start];
[self.pull start];
}
-(void)stopReplication{
[self.push stop];
[self.pull stop];
}
#end
For first time the control will not enter into for in loop
for (CBLQueryRow* row in result)
and for second time control will be in that loop.
This also happens when on just on launch.
Scenario.
Run App (Freshly installed app)
Navigate from initialViewController to viewController.
First time control does not enter into for loop, CBLQueryEnumerator Object.count returns nil.
pop to initialViewController
Push viewController, but this time controls enter into for in loop and CBLQueryEnumerator object.count returns 5
Hierarchy (Push).
initialViewContoller -> ViewContoller -> ListViewController
I am working on passbook feature for creating Boarding pass in iOS, I am able to create a single boarding pass and it is working well, but while tying to create multiple passes, I am getting the following issues:
I am able to get the counts but all passes are being replaced with last one while REVIEW
After selecting SAVE ALL, there is only one pass in passbook app, i.e the last one.
I am using Following code to show passes
-(void) initializeWithMultiPassbookArray:(NSMutableArray *)arrPasses
{
NSMutableArray *arrPKPass = [[NSMutableArray alloc] init];
for(NSString *path in arrPasses)
{
NSData *data;
if(path && path.length)
{
data = [[NSData alloc] initWithContentsOfFile:path];
NSError *error;
PKPass *passSample = [[PKPass alloc] initWithData:data error:&error];
if(passSample)
{
[arrPKPass addObject:passSample];
passSample = nil;
}
else
JALog(#"passSample is nil");
}
else
{
JALog(#"Error occured while fetching pkpass data from cache path");
}
}
if(arrPKPass && arrPKPass.count > 1)
{
if(!self.passLibrary)
self.passLibrary = [[PKPassLibrary alloc] init];
__weak BookingSuccessfulViewController *self_ = self;
if(viewPopUpBg)
{
[viewPopUpBg removeFromSuperview];
viewPopUpBg = nil;
}
[self.passLibrary addPasses:arrPKPass withCompletionHandler:^(PKPassLibraryAddPassesStatus status) {
switch (status) {
case PKPassLibraryDidAddPasses:
{
[App_Delegate performSelectorOnMainThread:#selector(RemoveLoader) withObject:nil waitUntilDone:YES];
if([self_ respondsToSelector:#selector(showAlertFor:withMsg:withTag:)])
[self_ showAlertFor:SAVED withMsg:#"Your booking details have been added to Passbook." withTag:0];
break;
}
case PKPassLibraryDidCancelAddPasses:
{
[App_Delegate performSelectorOnMainThread:#selector(RemoveLoader) withObject:nil waitUntilDone:YES];
break;
}
case PKPassLibraryShouldReviewPasses:
{
//[self_ performSelectorOnMainThread:#selector(RemoveLoader) withObject:nil waitUntilDone:YES];
[App_Delegate performSelectorOnMainThread:#selector(RemoveLoader) withObject:nil waitUntilDone:YES];
PKAddPassesViewController *vcPKAddPass = [[PKAddPassesViewController alloc] initWithPasses:arrPKPass];
[vcPKAddPass setDelegate:(id)self_];
[self_ presentViewController:vcPKAddPass animated:YES completion:nil];
vcPKAddPass = nil;
break;
}
default:
break;
}
}];
}
else if(arrPKPass.count == 1)
{
if(viewPopUpBg)
{
[viewPopUpBg removeFromSuperview];
viewPopUpBg = nil;
}
[App_Delegate performSelectorOnMainThread:#selector(RemoveLoader) withObject:nil waitUntilDone:YES];
PKPass *passLocal = [arrPKPass objectAtIndex:0];
if(passLocal)
{
self.currentPass = passLocal;
//present view controller to add the pass to the library
PKAddPassesViewController *vcPKAddPass = [[PKAddPassesViewController alloc] initWithPass:passLocal];
[vcPKAddPass setDelegate:(id)self];
[self presentViewController:vcPKAddPass animated:YES completion:nil];
vcPKAddPass = nil;
}
}
else
{
JALog(#"arrPKPass is nil");
}
}
Got my ans:
Every Pass should contain different serial No in the key "serialNumber" while creating JSON
Also Check the Capabilities in Project>Target>Capabilities>Passbook
Allow subset of pass types is selected with specific identifiers.
These steps worked for me.
Hopefully help to others also.
Thanks
Hello i'm working on this app which has a login section. What i want is when i click the login button that button has to be unclickable until the login succeeds or fails. I already tried adding this line doLogin.enabled = NO;
But that wasn't useful. Please help. This is my code:
- (IBAction)doLogin:(id)sender {
[self loginUser];
}
- (void)loginUser
{
if (![self.usernameBox.text isEqualToString:#""] && ![self.passwordBox.text isEqualToString:#""])
{
//TODO: check id email pattern is correct
[self showLoginProcess:true];
[[AuthSingleton getInstance] attemptLoginWithUsername:self.usernameBox.text andPassword:self.passwordBox.text withSuccesBlock:^(AFHTTPRequestOperation *operation, id responseObject)
{
[self showLoginProcess:false];
UIViewController *newFrontController = nil;
PaMapViewController * vc = [[PaMapViewController alloc] init];
newFrontController = [[UINavigationController alloc] initWithRootViewController:vc];
SWRevealViewController *revealController = self.revealViewController;
[revealController pushFrontViewController:newFrontController animated:YES];
} andFailureBlock:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSDictionary *dic = [error.userInfo objectForKey:#"JSONResponseSerializerWithDataKey"];
#ifdef DEBUG
NSLog(#"dic = %#", dic);
#endif
if ([[dic objectForKey:#"error_uri"] isEqual:#"phone"])
{
NSError *jsonError;
NSData *objectData = [[dic objectForKey:#"error_description"] dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
[self loginFailed:json];
}
else
{
[self loginFailed:dic];
}
}];
}
else
{
//TODO: show proper message Test
NSLog(#"username or password is empty %#", kBaseURL);
}
}
- (void)showLoginProcess:(BOOL) show
{
[self.spinner setColor:[UIColor whiteColor]];
self.spinner.hidden = !show;
self.usernameBox.hidden = show;
self.passwordBox.hidden = show;
if (show)
{
[self.spinner startAnimating];
} else
{
[self.spinner stopAnimating];
}
}
Hope you have declared a property for the login button. Let it be "doLogin".
What you need to do is
- (IBAction)doLogin:(id)sender
{
[self loginUser];
doLogin.userInteractionEnabled = NO;
}
and when login succeeds or fails write
doLogin.userInteractionEnabled = YES;
within the corresponding block.
Instead of
doLogin.enabled = NO
write
doLogin.userInteractionEnabled = NO
- (IBAction)doLogin:(id)sender
{
doLogin.userInteractionEnabled = NO;
[self loginUser];
doLogin.userInteractionEnabled = YES;
}
Given below is the code snipe that should help
- (IBAction)loginUser:(id)sender
{
//before login disable the user interaction of the button
loginButton.userInteractionEnabled = NO;
/*Your login logic here*/
// after successful login enable the login button once again
loginButton.userInteractionEnabled = YES;
}
I'm using Phonegap's implementation to use the video capture and can't seem to get startVideoCapture to work. I'm a novice when it comes to Objective C, so I apologize if I'm off base here. Sounds like startVideoCapture is mainly for custom UI's. Is there something I can do to auto start the video recording (since I'm starting the video interface from another action). Here's a link to the full file:
https://github.com/apache/cordova-plugin-media-capture/blob/master/src/ios/CDVCapture.m
Thanks,
Steve
- (void)captureVideo:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
NSDictionary* options = [command.arguments objectAtIndex:0];
NSLog(#"hereeeee");
if ([options isKindOfClass:[NSNull class]]) {
options = [NSDictionary dictionary];
}
// options could contain limit, duration and mode
// taking more than one video (limit) is only supported if provide own controls via cameraOverlayView property
NSNumber* duration = [options objectForKey:#"duration"];
NSString* mediaType = nil;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
// there is a camera, it is available, make sure it can do movies
pickerController = [[CDVImagePicker alloc] init];
NSArray* types = nil;
if ([UIImagePickerController respondsToSelector:#selector(availableMediaTypesForSourceType:)]) {
types = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
// NSLog(#"MediaTypes: %#", [types description]);
if ([types containsObject:(NSString*)kUTTypeMovie]) {
mediaType = (NSString*)kUTTypeMovie;
} else if ([types containsObject:(NSString*)kUTTypeVideo]) {
mediaType = (NSString*)kUTTypeVideo;
}
}
}
if (!mediaType) {
// don't have video camera return error
NSLog(#"Capture.captureVideo: video mode not available.");
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:CAPTURE_NOT_SUPPORTED];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
pickerController = nil;
} else {
pickerController.delegate = self;
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
pickerController.allowsEditing = NO;
// iOS 3.0
pickerController.mediaTypes = [NSArray arrayWithObjects:mediaType, nil];
if ([mediaType isEqualToString:(NSString*)kUTTypeMovie]) {
if (duration) {
pickerController.videoMaximumDuration = [duration doubleValue];
}
// NSLog(#"pickerController.videoMaximumDuration = %f", pickerController.videoMaximumDuration);
}
// iOS 4.0
if ([pickerController respondsToSelector:#selector(cameraCaptureMode)]) {
pickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
// pickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
// pickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
// pickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
}
// CDVImagePicker specific property
pickerController.callbackId = callbackId;
SEL selector = NSSelectorFromString(#"presentViewController:animated:completion:");
if ([self.viewController respondsToSelector:selector]) {
[self.viewController presentViewController:pickerController animated:YES completion:nil];
} else {
// deprecated as of iOS >= 6.0
[self.viewController presentModalViewController:pickerController animated:YES];
}
// Auto start capture
[pickerController startVideoCapture];
}
}
My problem wasn't the use of startVideoRecording, it was when:
[self.viewController presentViewController:pickerController animated:YES completion:^(){
[pickerController startVideoCapture];
}];
Hope this helps someone else.
Thanks,
Steve