Three20 Search Scope - search

I'm using Three20 and I've got the standard search mechanism working.
TTTableViewController* searchController = [[[TTTableViewController alloc] init] autorelease];
searchController.dataSource = [[[MyDataSource alloc] init] autorelease];
self.searchViewController = searchController;
self.tableView.tableHeaderView = _searchController.searchBar;
I'd like to use a scope. but I'm having trouble implementing it. Going through the three20 code it appears the searchdisplaycontroller is already built in. Is there a method I'm missing like
-(void)search:(NSString *)text withinScope:(NSString *)scope
How do I pull the scope from the searchdisplaycontroller? I tried using the delegate methods for the searchdisplaycontroller but the datasource isn't populating the table.
Any ideas?
Thanks,
Howie

After searching high and low, I came to the conclusion that something must be missing from the core Three20 library. I did a little snooping around and found that the UISearchDisplayDelegate methods are in TTSearchDisplayController.m and unfortunately don't incorporate the scope when they hand things off to the datasource.
Here are the modifications I made:
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)searchAfterPause {
_pauseTimer=nil;
// HOWIE MOD
if([self.searchBar.scopeButtonTitlescount])
{
NSString*scope = [[self.searchBarscopeButtonTitles]objectAtIndex:[self.searchBarselectedScopeButtonIndex]];
//NSLog(#"sending text: %# for scope: %#", self.searchBar.text, scope);
[_searchResultsViewController.dataSource search:self.searchBar.textwithinScope:scope];
}else
{
[_searchResultsViewController.dataSource search:self.searchBar.text];
}
/*
// Original
[_searchResultsViewController.dataSource search:self.searchBar.text];
*/
// /HOWIE MOD
}
and
///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)searchDisplayController:(UISearchDisplayController*)controller
shouldReloadTableForSearchString:(NSString*)searchString {
if(_pausesBeforeSearching) {
[selfrestartPauseTimer];
} else{
// HOWIE MOD
if([self.searchBar.scopeButtonTitlescount])
{
NSString*scope = [[self.searchBarscopeButtonTitles]objectAtIndex:[self.searchBarselectedScopeButtonIndex]];
[_searchResultsViewController.dataSource search:searchString withinScope:scope];
returnYES;
} else
{
[_searchResultsViewController.dataSource search:searchString];
}
/*
// Original
[_searchResultsViewController.dataSource search:searchString];
*/
// / HOWIE MOD
}
returnNO;
}
and
///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)searchDisplayController:(UISearchDisplayController*)controller
shouldReloadTableForSearchScope:(NSInteger)searchOption {
// HOWIE MOD
if([self.searchBar.scopeButtonTitlescount])
{
NSString*scope = [[self.searchBarscopeButtonTitles] objectAtIndex:searchOption];
[_searchResultsViewController.dataSource search:self.searchBar.textwithinScope:scope];
returnYES;
}else
{
[_searchResultsViewControllerinvalidateModel];
[_searchResultsViewController.dataSource search:self.searchBar.text];
}
/*
// Original
[_searchResultsViewController invalidateModel];
[_searchResultsViewController.dataSource search:self.searchBar.text];
*/
// / HOWIE MOD
returnNO;
}
Then I added the following to TTTableViewDataSource.h
// HOWIE MOD
- (void)search:(NSString*)text withinScope:(NSString*)scope;
// /HOWIE MOD
And the following to TTTableViewDataSource.m
// HOWIE MOD
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)search:(NSString*)text withinScope:(NSString*)scope {
}
// /HOWIE MOD
Now I can create the method - (void)search:(NSString*)text withinScope:(NSString*)scope in my datasource and it will respond accordingly as a search with scope is performed. I also enabled pausesBeforeSearching when I instantiate the search controller in my tableview controller so that it waits a couple of seconds before performing the search as a user types. This is helpful since my search is querying a server and rather than send each character as the user types, it makes more sense to let them type a few characters first.
Hope this helps.
Howie

Related

Linphone fails to create SAS for ZRTP Secure call

I have recently updated my Linphone library from latest release to follow Appleā€™s IPV6 standard support.
But it fails to create secure call.
Each time i try to convert call to secure call ,Acknowledgment fails and SAS returns null.
Same thing working with old library(IPV4 Support).
I am using ZRTP Encryption for Secure call.
I am struggling with since last 15 days.
Below line of code returns SAS value null.
NSString *localLize = NSLocalizedString(#"Confirm the following SAS with peer:\n%s", nil);
const char *authToken = linphone_call_get_authentication_token(call);
NSLog(#"localize %# authToken %s",localLize,authToken);
Below is full function to convert call to security call.
- (IBAction)onSecurityClick:(id)sender {
if (linphone_core_get_calls_nb(LC)) {
LinphoneCall *call = linphone_core_get_current_call(LC);
if (call != NULL) {
//force encryption ZRTP
LinphoneMediaEncryption enc = LinphoneMediaEncryptionZRTP;
if (enc == LinphoneMediaEncryptionZRTP) {
NSString *localLize = NSLocalizedString(#"Confirm the following SAS with peer:\n%s", nil);
const char *authToken = linphone_call_get_authentication_token(call);
NSLog(#"localize %# authToken %s",localLize,authToken);
NSString *message =
[NSString stringWithFormat:NSLocalizedString(#"Confirm the following SAS with peer:\n%s", nil),
linphone_call_get_authentication_token(call)];
if (securityDialog == nil) {
__block __strong StatusBarView *weakSelf = self;
securityDialog = [UIConfirmationDialog ShowWithMessage:message
cancelMessage:NSLocalizedString(#"DENY", nil)
confirmMessage:NSLocalizedString(#"ACCEPT", nil)
onCancelClick:^() {
if (linphone_core_get_current_call(LC) == call) {
linphone_call_set_authentication_token_verified(call, NO);
}
weakSelf->securityDialog = nil;
}
onConfirmationClick:^() {
if (linphone_core_get_current_call(LC) == call) {
linphone_call_set_authentication_token_verified(call, YES);
}
weakSelf->securityDialog = nil;
}];
}
}
}
}
}
Any help should be appreciable.
Thanks in Advance.
So I figured out what was the problem for me. Maybe can be useful for you too.
I was calling linphone_call_get_authentication_token immediately after the call state changed to LinphoneCallOutgoingProgress. All I had to do to fix it was to start a Timer that calls a method every 1 second when the call state changes to LinphoneCallOutgoingProgress because it takes some time for the SAS to be generated it seems. Here's what worked for me:
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) {
DispatchQueue.main.async {
let sas = linphone_call_get_authentication_token(Call.current())
if sas != nil {
self!.sasLabel.text = String(cString: sas!)
timer.invalidate()
}
}
}

Toggling click handler using waitForKeyElements

I recently discovered, waitForKeyElements. An amazing utility from BrockA.
I'm using the userscript below in Tampermonkey to automatically accept chats from SalesForce's LiveAgent.
Works great, my question is if there's a way to add a button or a link to toggle between it, without having to flip the disable & enable switch on Tampermonkey, and then refreshing the page?
Any help is greatly appreciated since I've spent a few days looking for an answer, and very little to show for. Thanks in advance!!
// ==UserScript==
// #name AutoAccept Chats
// #version 0.1
// #author Me
// #include https://*.ladesk.com/agent/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #grant GM_addStyle
// ==/UserScript==
'use strict';
waitForKeyElements (
"div.TicketNotificationWindowIn",
AnswerChat
);
function AnswerChat (jNode) {
document.getElementsByClassName("ImLeButtonImLeButtonMainOut TicketNotificationAcceptButton")[0].click();
}
This is what I had which didn't work, but might help explain my question.
var turnsOff = 1;
function doToggle() {
if (turnsOff == 1) {
turnsOff = 2;
}else{
turnsOff = 1;
}
ToggleState();
}
function ToggleState () {
if (turnsOff == 1) {
waitForKeyElements (
"div.TicketNotificationWindowIn",
AnswerChat
);
}else{
console.log('not answered');
}
}

Retrieving company name from HMService and/or HMAccessory object instance

I am using Home Kit Accessory simulator and I'd like to retrieve the company name of an accessory from an instance of HMService. However, when I add a breakpoint I cannot see any field related to the company name (I searched in both HMService and HMAccessory).
Any suggestion?
You can get name of Manufacturer from HMServiceTypeAccessoryInformation service, Service contains characteristic array in this there is HMCharacteristicTypeManufacturer characteristic.
You can use this to display name of company.
- (HMCharacteristic *)characteristicForAccessory:(HMAccessory *)accessoryValue{
HMAccessory *thisAccessory = accessoryValue;
HMService *service;
for (HMService *thisService in thisAccessory.services) {
if([thisService.serviceType isEqualToString:HMServiceTypeAccessoryInformation]) {
service = thisService;
}
}
HMCharacteristic *characteristic;
if (service) {
for (HMCharacteristic *charact in service.characteristics) {
if ([charact.characteristicType isEqualToString:HMCharacteristicTypeManufacturer]) {
characteristic = charact;
}
}
}
return characteristic;
}
Use Characteristic object's value property to get name of manufacturer.
Like characteristic.value
Take a look at Raeid Saqur's RSHomeKit framework:
You can get accessory by calling service.accessory. Then use:
+ (NSString *)getManufacturerNameForHMAccessory:(HMAccessory *)accessory;
+ (NSString *)getManufacturerNameForHMAccessory:(HMAccessory *)accessory {
if (!accessory) {
return nil;
}
HMCharacteristic *manufacturer = [HomeKitUtility getCharacteristicWithUUID:HMCharacteristicTypeManufacturer forAccessory:accessory];
if (manufacturer && manufacturer.value) {
return (NSString *)manufacturer.value;
}
return nil;
}

AirPrint UIWebView content in iOS8

I am trying to AirPrint the contents of my UIWebView (iOS8.1) and am getting an exception with no detail as to what the problem is. If I toggle "Global Breakpoint State" to OFF in Xcode 6.1 then it occasionally prints, although sometimes the page is blank. I am also using an up-to-date installation of Printopia for printing to the iMac.
Is anyone else experiencing problems with AirPrinting in iOS8? Are there any problems with the code below that could be causing this issue?
// AirPrint functionality
-(void)printBid {
if ([UIPrintInteractionController isPrintingAvailable]) { // check that we can print
// Use UIPrintInteractionController to print the web view content
// This generates an exception when Global Breakpoint State is set to On but seems to work when Off
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
//pic.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = #"QuickBids";
printInfo.duplex = UIPrintInfoDuplexLongEdge;
pic.printInfo = printInfo;
pic.showsPageRange = YES;
UIViewPrintFormatter *formatter = [bidPreviewWebView viewPrintFormatter];
pic.printFormatter = formatter;
UIPrintInteractionCompletionHandler completionHandler =
^(UIPrintInteractionController *printController, BOOL completed,
NSError *error) {
if(!completed && error){
NSLog(#"Print failed - domain: %# error code %u", error.domain,
error.code);
}
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { // The device is an iPad running iPhone 3.2 or later.
// iOS 8 Issue on iPad - As a workaround, I recommend delaying the presentation until the next runloop, using the following method:
// http://stackoverflow.com/questions/24854802/presenting-a-view-controller-modally-from-an-action-sheets-delegate-in-ios8
dispatch_async(dispatch_get_main_queue(), ^ {
[pic presentFromBarButtonItem:shareButton animated:YES completionHandler:completionHandler];
});
}else { // The device is an iPhone or iPod touch.
dispatch_async(dispatch_get_main_queue(), ^ {
[pic presentAnimated:YES completionHandler:completionHandler];
});
}
}else { // we can't print so show an alert
// show simple alert
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:#"Printing Unavailable"
message:#"You cannot print from this device."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"OK", #"OK action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(#"OK action");
}];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}
}
Thanks in advance for any help.

Reordering UITableView with NSOrderedSet in CoreData

Does anyone has sample code for ordering in UITableView using NSOrderedSet?
Had read many articles about reordering, but still don't understand how to do this in iOS5.
Hi i implemented it like this. The "currentObject" is root object of the relationship and "subItems" the name of the ordered relationship in the model which is managed by the UITableViewController.
- (void)moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
NSMutableOrderedSet* orderedSet = [self.currentObject mutableOrderedSetValueForKey:#"subItems"];
NSInteger fromIndex = fromIndexPath.row;
NSInteger toIndex = toIndexPath.row;
// see http://www.wannabegeek.com/?p=74
NSIndexSet *indexes = [NSIndexSet indexSetWithIndex:fromIndex];
if (fromIndex > toIndex) {
// we're moving up
[orderedSet moveObjectsAtIndexes:indexes toIndex:toIndex];
} else {
// we're moving down
[orderedSet moveObjectsAtIndexes:indexes toIndex:toIndex-[indexes count]];
}
[self.dataStore saveObjectContext];
}

Resources