Xamarin: string represantation of object - xamarin

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.

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.

How to show and hide standard InDesign panels through scripting?

I’m able to get a reference to, for instance, the “Scripts” panel; but it doesn’t seem to have the show and hide methods like panels created through scripting (see code below). How can I get it to show or hide programmatically, without invoking the corresponding menu item?
function findPanelByName(name) { // String → Panel|null
for (var iPanel = 0; iPanel < app.panels.length; iPanel++) {
var panel = app.panels[iPanel];
if (panel.name == name) {
return panel;
}
}
return null;
}
var scriptsPanel = findPanelByName('Scripts');
scriptsPanel.show(); // → “scriptsPanel.show is not a function”
A few things: Your method to get the right panel is unneccessarily complicated. You could just get the panel by using the panel collection's item method like so:
var scriptsPanel = app.panels.item('Scripts');
Then, you don't need to use show() to show the panel (as that method does not exist), but you can just show the panel, by settings its visible property to true:
scriptsPanel.visible = true;
And lastly, in case anybody else is supposed to use the script, you should make sure, that it works with international versions of InDesign as well. In my German version, the above panel for example would not exist, as it is named Skripte instead of Scripts. To avoid that you can use the language independent key of InDesign:
var scriptsPanel = app.panels.item('$ID/Scripting');
So, in conclusion, the entire script could be shortened up to this one-liner
app.panels.item('$ID/Scripting').visible = true;

Duplicated display of NSUserActivity in Spotlight

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.

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.

How do I store and retrieve a variable from an array using the Firefox Add-on SDK?

I am attempting to develop a Firefox extension.
I have a simple need. At this time in testing, I simply wish to define an array. When the button is pushed, the Current Window goes to the first URL in the array. When the button is pushed again, it goes to the next URL in the array.
I am of the impression that I need to store the present sequence in the array using simple-storage (ss.storage) yet I cannot make it work. I thought perhaps I could store the sequence information using a Cookie but the Add-on SDK appears to be very stringent. Perhaps there is a far simpler method but I cannot seem to identify what that would be.
Current Status - when the button is pushed, the code opens three separate windows for each URL in the array. If you could please help me to modify this code so that opens one URL from the array each time the button is pushed - as described above.
require("widget").Widget({
id: "view-source-widget",
label: "View Source",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
var arr = new Array("one.com","two.com","three.com");
for(var i=0; i<arr.length; i++) {
var value = arr[i];
var ss = require("simple-storage");
ss.storage.myURL= value;
var windows = require("windows").browserWindows;
windows.open(ss.storage.myURL);
}
}
});
If I understand correctly what you are trying to do - you don't need persistent storage, a normal global variable will do. The global variable indicates the array index at which you are right now. Something like this:
var urls = ["one.com","two.com","three.com"];
var urlIndex = 0;
...
onClick: function() {
var windows = require("windows").browserWindows;
windows.open(urls[urlIndex]);
// Increase index for the next click
urlIndex++;
if (urlIndex >= urls.length)
urlIndex = 0;
}
...

Resources