Duplicated display of NSUserActivity in Spotlight - corespotlight

I know there are several posts on this topic out there but they differed to much from my problem.
I am trying to display my NSUserActivity in Spotlight Search. For my NSUserActivity I am using three APIs: .isEligibleForHandoff, .isEligibleForSearch and .isEligibleForPrediction.
My problem is that my activity is being displayed twice in the Spotlight Search and that one of the results delivers an empty userInfo and the other one doesn't. However the Apple Programming Guide suggests:
Use the following strategies to avoid creating duplicate
representations of a single item:
If you’re using both NSUserActivity and Core Spotlight APIs to index
an item, use the same value for relatedUniqueIdentifier and
uniqueIdentifier to link the representations of the item.
But I don't think this is even my problem since I am not using any Core Spotlight APIs.
Thats my code inside my UIResponder class:
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
attributeSet.title = "Place Order Search"
attributeSet.contentDescription = "Get Your Avocado Toast Now"
attributeSet.relatedUniqueIdentifier = ActivityType.placeOrder.rawValue
let avocadoToastDictionary = AvocadoToastManger.dictionary(from: avocadoToastOrder)
let jsonAvocadoToastData = json(from: avocadoToastDictionary)
let activity = NSUserActivity(activityType: ActivityType.placeOrder.rawValue)
activity.title = "Place Order"
activity.userInfo = ["PlaceOrder.avocadoToast": jsonAvocadoToastData]
activity.requiredUserInfoKeys = ["PlaceOrder.avocadoToast"]
activity.suggestedInvocationPhrase = "Order an Avocado Toast"
activity.keywords = ["Order", "Avocado Toast"]
activity.isEligibleForHandoff = true
activity.isEligibleForSearch = true
activity.isEligibleForPrediction = true
activity.contentAttributeSet = attributeSet
self.userActivity = activity
activity.becomeCurrent()
Note: The updateUserActivityState(activity:) method is getting called twice in a row.
So how can I void getting multiple search results in the Spotlight Search and make sure the one which has the userInfo property set stays.

Related

Why some string in SwiftUI app are not localized

I use Export/Import localization functionality in Xcode 13.2.1 and it works more or less fine but some strings are not exported in xcloc file, for example texts from function below
func createInitialStepTypes(inContext context: NSManagedObjectContext) {
let names = ["NVA", "NEC", "VA"]
let nvaDesc = "Step with not added value (typically preparing of equipment, exception handling, etc.)."
let necDesc = "Necessary steps but still not adding value (typically system actions like login, manual data entry, etc.)."
let vaDesc = "Step with added value (typically material handling)."
let descs = [nvaDesc, necDesc, vaDesc]
let colors: [Color] = [Color.red, Color.orange, Color.green]
for (i, _) in names.enumerated() {
name = names[i]
desc = descs[i]
color = colors[i]
save(stepTypeID: nil, inContext: context)
}
}
Strings from other functions in the same class like e.g. this one
errMsg = "Step type \(stepType.name!) can't be deleted because it's being used."
are captured correctly. Any idea why?
Thanks.

Xamarin Android : Retain data on activity change and come back

I'm developing an app in Xamarin.android where in I want to retain the data of Edit Text, spinners etc. whenever i revisit to that activity. E.g.
Activity A contains Edit Text, Spinners.
I navigate to Activity B from Activity A, and whenever I come back to Activity A from B I want to retain those values of Edit Text and Spinners.
I tried using Put Extra and Get Extra, but as there are multiple values this approach seems to be wrong.
var activity2 = new Intent (this, typeof(Activity2));
activity2.PutExtra ("MyData", "Data from Activity1");
StartActivity (activity2);
Also OnSaveInstanceState and OnRestoreInstanceState is not working out for me as I'm using Fragments in my Activity A
Please Guide
Can't your fragments save their own data using Fragment.onSaveInstanceState ?
in your case you need to save this temp data in Shared Preference
here is example
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
ISharedPreferencesEditor editor = prefs.Edit();
editor.PutInt(("number_of_times_accessed", accessCount++);
editor.PutString("date_last_accessed", DateTime.Now.ToString("yyyy-MMM-dd"));
editor.Apply();
save what ever you want int or string
and when you load you activity retrieve this data and set it to your views
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
string passedString = prefs.GetString(key, defValue);
// here set retured data to your view
// Ex : YourEditText.Text = passedString
hope this help

Xamarin: string represantation of object

I'm looking for something similar in Xamarin to iOS -description method which is just string representation of object (called when u type po object in XCode console)
F.e I'm getting a Array or Dictionary and I need to display it in a label
in iOS I'd easilly do:
label.text = object.description;
and it would work for dictionary and arrays:
<__NSArrayI 0x7f8a83ef4b10>(
{
description = "set_loyalty";
event = "";
mutation = 100;
previous = 0;
timestamp = "2016-04-08 09:45:15";
},
{
description = "set_loyalty";
event = "";
mutation = 100;
previous = 100;
timestamp = "2016-04-08 09:45:16";
},
but in Xamarin I weren't able to find easy way to achieve the same.
I've tried:
object.toString();
String.Format("{0}", object);
object.Description;
None of it works like I want (I don't expect it to work :) like I want )
Is there a simple way to achieve this?
If it's an iOS object (inherits from NSObject), you can still use myObect.Description.
If not:
some types overload ToString() to print their properties nicely, but not all
have a look at: https://stackoverflow.com/a/1347630/1489968
or use a serializer of your choice (e.g. JSON.NET). But these will not dump every field / property.

Using Javascript for Automation to copy cells in Numbers

I want to use JXA to automate some updating of Numbers spreadsheets. For example, copying a range of cells from one spreadsheet to another one with a different structure.
At this point, I'm just testing a simple program to set or read the value of a cell and I can't get this to work.
When I try to set a value I get "Error -1700: Can't convert types." and when I try to read a value I get back a [object ObjectSpecifier] rather than a text or number value.
Here's an example of the code:
Numbers = Application('Numbers')
Numbers.activate()
delay(1)
doc = Numbers.open(Path('/Users/username/Desktop/Test.numbers'))
currentSheet = doc.Sheets[0]
currentTable = currentSheet.Tables[0]
console.log(currentTable['name'])
console.log(currentTable.cell[1][1])
currentTable.cell[1][1].set(77)
When I run this, I get and output of [object ObjectSpecifier] for the two console.logs and then an error -1700: Can't convert types when it tries to set a cell.
I've tried several other variations of accessing or setting properties but can't get it to work.
Thanks in advance,
Dave
Here is a script that sets and gets a cell's value and then sets a different cell's value in the same table:
// Open Numbers document (no activate or delay is needed)
var Numbers = Application("Numbers")
var path = Path("/path/to/spreadsheet.numbers")
var doc = Numbers.open(path)
// Access the first table of the first sheet of the document
// Note:
// .sheets and .tables (lowercase plural) are used when accessing elements
// .Sheet and .Table (capitalized singular) are used when creating new elements
var sheet = doc.sheets[0]
var table = sheet.tables[0]
// Access the cell named "A1"
var cell = table.cells["A1"]
// Set the cell's value
cell.value = 20
// Get the cell's value
var cellValue = cell.value()
// Set that value in a different cell
table.cells["B2"].value = cellValue
Check out the Numbers scripting dictionary (with JavaScript selected as the language) to see classes and their properties and elements. The elements section will show you the names of elements (e.g. the Document class contains sheets, the Sheet class contains tables, and so on). To open the scripting dictionary, in Script Editor's menu bar, choose Window > Library, and then select Numbers in the library window.
In regards to the logging you were seeing - I recommend using a function similar to this:
function prettyLog(object) {
console.log(Automation.getDisplayString(object))
}
Automation.getDisplayString gives you a "pretty print" version of any object you pass to it. You can then use that for better diagnostic logging.

Programatically updating underlying data in Slickgrid

I have 6 textboxes at the top of the screen that update an entire column(one textbox per column) based on any changes. I was selecting the columns based on their class (.l#). Here is the code (issues to follow):
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = [".l1", ".l7", ".l8", ".l9"];
var fields = $(bound[id]);
for (var i = 0; i < fields.length; i++)
{
fields[i].innerHTML = $(ctrl).val();
}
};
which is bound to the keyup event for the text areas. Issues are:
1) initially fields.length was -1 as I didn't want to put data in the "add new
row" section at the bottom. However, when running it, I noticed the
final "real" record wasn't being populated. Also, when stepping through, I
noticed that the "new row" field was before the "last row" field.
2) when doing it this way, it is purely superficial: if I double click the field,
the real data hasn't been changed.
so in the grand scheme of things, I know that I was doing it wrong. I'm assuming it involves updating the data and then forcing a render, but I'm not certain.
Figured out how to do it. Modified the original code this way:
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = ['title1', 'title2', 'title3', 'title4'];
var field = bound[id];
for (var i = 0; i < dataView.getLength(); i++)
{
var item = dataView.getItem(i);
item[field] = $(ctrl).val();
dataView.updateItem(i, item);
}
grid.invalidate();
};
I have 6 textboxes (item1-item6) that "bind" to fields in the sense that if I change data in a textbox, it updates all of the rows and any new rows added also have this data.
Parts where the two issues can be explained this way:
1) to work around that, though still it would be a presentational fix and not a real updating of the underlying data, one could force it to ignore if it had the active class attached. Extra work, and not in the "real" direction one is going for (masking the field).
2) It was pretty obvious with the original implementation (though it was all I could figure out via Chrome Dev Tools that I could modify at the time) that it was merely updating a div's content and not actually interacting with the data underneath. Would look nice, and perhaps one could just pull data from the item1-item6 boxes in place of the column if it is submitted, but if someone attempts to modify the cell, they'll be looking at the real data again.

Resources