Basically within my app I have two text fields for pound and pence value inputs. I am currently working on making my app localised and I have ran into an issue. My textfields have the placeholders 'Pounds' and 'Pence' and I need them to display placeholders for the currency and sub-currency based on the users location such as 'Dollars' and 'Cents' for the US.
I have no idea how to do this in a way that would be efficient and I was hoping for some suggestions as to how I could go about this.
Any help would be much appreciated!
You can get the name of the local currency by using NSLocale:
var locale = NSLocale.currentLocale()
var currencyCode: (AnyObject!) = locale.objectForKey(NSLocaleCurrencyCode)
locale.displayNameForKey(NSLocaleCurrencyCode, value: code) // "British Pound"
However, it seems that you may not be satisifed with the official name and I am not aware of a way to get Pence or Cents so you can also create your own list using locale identifiers:
struct LocalCurrency {
static func wholeName(forLocale locale: NSLocale = NSLocale.currentLocale()) -> String {
var identifier : String = locale.localeIdentifier
switch(identifier) {
case "en_UK":
return "Pounds"
case "en_US":
return "Dollar"
default:
return ""
}
}
}
LocalCurrency.wholeName() // "Pounds"
You can create a similar method for partial currencies and you will have to add all locales you want to support manually, but at least the device will tell you what the current Locale is.
Update:
You can also get the currency symbol:
locale.displayNameForKey(NSLocaleCurrencySymbol, value: code) // £
Or you can use an NSNumberFormatter to format currency for you:
var formatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
formatter.stringFromNumber(1.23) // £1.23
Perhaps you can use one of those to come up with a new format for how you want to display it without creating a manual list.
Related
I am looking for a xpath like query language for protobuf messages. For example, for the Person message shown below [ borrowed from the Developer guide ]
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
I would like to have methods like
XPBQuery.get(person, "$.id") ==> returns the id
XPBQuery.get(person, "$.name") ==> returns the name
XPBQuery.get(person, "$.phone.number[0]") ==> returns the first phone number
One way is to convert the proto to Json and use a JsonPath/JsPath API's. But it may be expensive to convert to Json everytime especially for large Proto objects.
Any help is much appreciated.
Thanks,
Irfan
Support for that is coming in protobuf v3: https://github.com/google/protobuf/blob/4644f99d1af4250dec95339be6a13e149787ab33/src/google/protobuf/field_mask.proto
While looking for a solution to a similar problem I discovered:
PbQuery (python)
protobuf-utils (java)
protobuf-el (java)
(I did not use those libraries as my target language is C++, but hope this might help someone else)
Good luck!
I read somewhere that it was best practice to use structs when passing around model data using Swift.
I have been doing so but I have been wondering whether there is anything that I can do in regards to the creation of large (and growing) user data objects like this:
struct UserAccount {
var id: String?
let authId: String
let emailAddress: String
let mobilePhoneNumber: String
let firstName: String
let lastName: String
let countryCode: String
let homepageUrl: String
let tagline: String
let pictureUrl: String
let accountState: AccountState = .NoAccount
// ...
}
This is more or less what I use when I create a user account, but later on it feels cumbersome and wrong to have to instantiate gigantic objects in code. I am parsing JSON responses using json-swift but then having to instantiate the models separately, like so:
let id = jsonData["id"].string!
let authId = jsonData["authId"].string!
let emailAddress = jsonData["emailAddress"].string!
let mobilePhoneNumber = jsonData["mobilePhoneNumber"].string!
let firstName = jsonData["firstName"].string!
let lastName = jsonData["lastName"].string!
let countryCode = jsonData["countryCode"].string!
let homepageUrl = jsonData["homepageUrl"].string!
let tagline = jsonData["tagline"].string!
let pictureUrl = jsonData["pictureUrl"].string!
let accountState = convertAccountStateStringToEnum(jsonData["accountState"].string!)
let userAccount = UserAccount(
id: id,
authId: authId,
emailAddress: emailAddress,
mobilePhoneNumber: mobilePhoneNumber,
firstName: firstName,
lastName: lastName,
countryCode: countryCode,
homePageUrl: homepageUrl,
tagline: tagline,
pictureUrl: pictureUrl,
accountState: accountState
)
It might seem absurd that above I've instantiated the variables before I instantiate the struct, but the reason I did so is that when the IDE gives me type coercion errors from within a struct it is very difficult to understand what is wrong, and so this allows me to troubleshoot it quicker when I am making model changes. Any thoughts around this?
My Question:
Later on that user object is likely to contain a lot more data on the server side and instantiating use models with 50+ lines seems like a bad idea, therefore:
Are there solutions to create structs in some simpler way? Does the pattern have a name?
Should I be creating User models that are related to specific tasks? For example, a UserAccount model to GET or PUT a profile might be different from the one used to authenticate, get the user settings or list the most popular accounts on my service.
Do people just leave it as it is and define mappers so that there is no redundancy? If so - what's a good example of this?
Thanks.
When faced with this, I would build another initializer for the model that takes the JSON data:
struct UserAccount {
// ...
init(jsValue: JSValue) {
id = jsonData["id"].string!
authId = jsonData["authId"].string!
emailAddress = jsonData["emailAddress"].string!
mobilePhoneNumber = jsonData["mobilePhoneNumber"].string!
firstName = jsonData["firstName"].string!
lastName = jsonData["lastName"].string!
countryCode = jsonData["countryCode"].string!
homepageUrl = jsonData["homepageUrl"].string!
tagline = jsonData["tagline"].string!
pictureUrl = jsonData["pictureUrl"].string!
accountState = convertAccountStateStringToEnum(jsonData["accountState"].string!)
}
}
Then you can simply create new UserAccount instances from your JSON data:
let userAccount = UserAccount(jsValue: jsonData)
A few thoughts:
Can you share the reference that suggests its best practice to use structs rather than classes when passing around model data? I would have thought that passing around structs (especially big ones) by value would be less efficient than passing around class instances by reference.
See Choosing between classes and structures in The Swift Programming Language: Classes and Structures which suggests you want to use structures when:
The structure’s primary purpose is to encapsulate a few relatively simple data values.
It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
The structure does not need to inherit properties or behavior from another existing type.
Your user object does not seem to match this criteria. I would have thought the class approach is more logical.
BTW, if using classes, you can also simplify the code to instantiate an object if the class is KVO compliant. For example, you can iterate through an array of key names, grabbing the value associated with each key name from the JSON and then using setValue:forKey: to set the object's property for that particular key.
For more information about KVO-compliance see the Key-Value Observing Programming Guide: KVO Compliance. For more information about how to make Swift object KVO-compliant, see Key-Value Observing section of Using Swift with Cocoa and Objective-C: Adopting Cocoa Design Patterns.
In terms of separate user models for different tasks, that doesn't makes sense for me. You might have different objects for different functional purposes (e.g. accounts/authentication objects) which might reference the user objects, but it doesn't seem to make sense to have different types of user classes/structures.
I am working in a Spring 3.1 application and I need to find a String template document located in Alfresco's repository. I can already create a file in alfresco with OpenCMIS, but I couldn't figure out how to find a template, so if anyone knows how to do it or point me an example, please let me know, thanks in advance!
There are a number of options you can use. First of all, you need to have a criteria that uniquely identifies your document. Here below I'll show some, hopefully your case falls in one of them or they will inspire you towards a proper solution. The following uses pseudo code, please have a look to the OpenCMIS dev guide for working with the Java client API.
BY ID
Once you create a Document via CMIS, you get the unique ID of it that you can store in your application for later retrieval.
Map<String, Object> templateProperties = createDocumentProperties();
Folder folder = getTemplatesFolder();
ObjectId templateId = createTemplateIn(folder);
storeTemplateId(templateId.getId(), templateProperties); // persist the ID
...
// later on
...
String id = getTemplateId(); // retrieve the ID
Session session = openCMISSession();
Document template = (Document)session.getObject(id);
BY PATH
Similar to the previous example, you will have to take note of where you stored the document instead of its ID, or having a way to construct the path by hand.
String path = getTemplatePath(); // either recover it from DB or construct a path
Document template = (Document)session.getObjectByPath(path);
BY PROPERTY VALUE
Let's say you can use a specific metadata field on a template Document that allows you to easily retrieve it afterwards (e.g. you created some specific Alfresco metadata model for your use case).
String meta = TemplateProperties.TEMPLATE_ID; // e.g. my:templateId
String type = TemplateProperties.TEMPLATE_TYPE; // e.g. my:template
String templateMeta = "TEMPLATE1";
Map<String, Object> templateProperties = createDocumentProperties();
templateProperties.put(meta, templateMeta);
templateProperties.put(PropertyIds.OBJECT_TYPE_ID, type);
createTemplate(templateProperties);
...
// later on
...
String type = TemplateProperties.TEMPLATE_TYPE; // e.g. my:template
String meta = TemplateProperties.TEMPLATE_ID;
String tplId = "TEMPLATE1";
String query = String.format("SELECT * FROM % WHERE % = '%'", type, meta, tplId);
ItemIterable<QueryResult> i = session.query(query, false);
QueryResult qr = i.iterator().next(); // let's assume we have one single match
String templateId = qr.getPropertyByQueryName("cmis:objectId").getFirstValue()
Document template = (Document)session.getObject(templateId);
BY QUERY
The previous approach is not really tied to search by property name, and can be easily extended to use any kind of query that identifies your templates. Have a look at the Alfresco page on its CMIS query language implementation details to learn more ways of querying the repository.
Hi I been searching for my error but I can't find anything that help me. The problem is this. I been working with Subsonic 3, Newtonsoft Json and the linq way of write so I have this easy query:
var found = from client in newclients.All() where client.Period == "sometext" select client;
string periodoJSON = JsonConvert.SerializeObject(periodoFound); //this get "Self referencing loop Exception"
the problem is when I run this script I get the horrible exception "Self referening loop exception" in the JsonConvert line, subsonic have all the objects without any problem but if I do the following.
var found = from client in newclients.All() where client.Period == "sometext" select new client{client.Name, client.LastName, etc};
string periodoJSON = JsonConvert.SerializeObject(periodoFound);
I get the object serialize with a any problem with all the properties. I'm doing the last way because I have to finish my work but is any other way or solution for this problem, if not I will have to write all the properties every time I want to get a full table properties.
hope any can solve my problem o help me in the path for find a solution....
what I have is a really basic query with linq and I try the three values for JsonSerializerSettings and any work, again I'm working with subsonic 3 this not happend either with subsnoic 2 and I can make it work if I specify one by one the properties of the object in the linq query does any have any clue of what is happend, ANY more help would be great!!! If I put the value of Serialize my page get crazy and in a infinity loop state, if I decide for error simple doesn't work and Ignore nothing happen... some more information about this self referencia loop?
var u = usuario.SingleOrDefault(x => x.TipoUsuario == "A" || x.TipoUsuario == "W");
JsonSerializerSettings setting = new JsonSerializerSettings();
setting.ReferenceLoopHandling = ReferenceLoopHandling.Error; //.Serialize .Ignore
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"usuario", "var usuario=" + JsonConvert.SerializeObject(u, Formatting.None, setting) + ";");
Update ------
I code the following
string jsU = JsonConvert.SerializeObject(u,Formatting.None,new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
and is workign but the only thing wrongs is that in the json object comes all the information about the columns of subsonic 3 and a BIG chunk of text explain it... does any one know how to not SEND this part of the object??
Without knowing more about you object model it is hard to provide a definitive answer, but I would take a look at the ReferenceLoopHandling enum.
You're calling string SerializeObject(object value) on JsonConvert. Try the string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) method instead. The JsonSerializerSettings settings parameter lets you set a bunch of things, including the ReferenceLoopHandling ReferenceLoopHandling { get; set; } property.
You can try these values:
public enum ReferenceLoopHandling
{
Error,
Ignore,
Serialize
}
Obviously, Error is the default and that's what you're getting. Perhaps one of the others will help.
I'm learning to use Crystal Reports (with VB 2005).
Most of what I've seen so far involves slurping data directly from a database, which is fine if that's all you want to display in the report.
My DB has a lot of foreign keys, so the way I've tried to stay sane with presenting actual information in my app is to add extra members to my objects that contain strings (descriptions) of what the foreign keys represent. Like:
Class AssetIdentifier
Private ID_AssetIdentifier As Integer
Private AssetID As Integer
Private IdentifierTypeID As Integer
Private IdentifierType As String
Private IdentifierText As String
...
Here, IdentifierTypeID is a foreign key, and I look up the value in a different table and place it in IdentifierType. That way I have the text description right in the object and I can carry it around with the other stuff.
So, on to my Crystal Reports question.
Crystal Reports seems to make it straightforward to hook up to records in a particular table (especially with the Experts), but that's all you get.
Ideally, I'd like to make a list of my classes, like
Dim assetIdentifiers as New List(Of AssetIdentifier)
and pass that to a Crystal Report instead of doing a tight link to a particular DB, have most of the work done for me but leaving me to work around the part that it doesn't do. The closest I can see so far is an ADO.NET dataset, but even that seems far removed. I'm already handling queries myself fine: I have all kinds of functions that return List(Of Whatever) based on queries.
Is there an easy way to do this?
Thanks in advance!
UPDATE: OK, I found something here:
http://msdn.microsoft.com/en-us/library/ms227595(VS.80).aspx
but it only appears to give this capability for web projects or web applications. Am I out of luck if I want to integrate into a standalone application?
Go ahead and create the stock object as described in the link you posted and create the report (StockObjectsReport) as they specify. In this simplified example I simply add a report viewer (crystalReportViewer1) to a form (Form1) and then use the following code in the Form_Load event.
stock s1 = new stock("AWRK", 1200, 28.47);
stock s2 = new stock("CTSO", 800, 128.69);
stock s3 = new stock("LTWR", 1800, 12.95);
ArrayList stockValues = new ArrayList();
stockValues.Add(s1);
stockValues.Add(s2);
stockValues.Add(s3);
ReportDocument StockObjectsReport = new StockObjectsReport();
StockObjectsReport.SetDataSource(stockValues);
crystalReportViewer1.ReportSource = StockObjectsReport;
This should populate your report with the 3 values from the stock object in a Windows Form.
EDIT: Sorry, I just realized that your question was in VB, but my example is in C#. You should get the general idea. :)
I'm loading the report by filename and it is working perfect:
//........
ReportDocument StockObjectsReport;
string reportPath = Server.MapPath("StockObjectsReport.rpt");
StockObjectsReport.Load(reportPath);
StockObjectsReport.SetDataSource(stockValues);
//Export PDF To Disk
string filePath = Server.MapPath("StockObjectsReport.pdf");
StockObjectsReport.ExportToDisk(ExportFormatType.PortableDocFormat, filePath);
#Dusty had it. However in my case it turned out you had to wrap the object in a list even though it was a single item before I could get it to print. See full code example:
string filePath = null;
string fileName = null;
ReportDocument newDoc = new ReportDocument();
// Set Path to Report File
fileName = "JShippingParcelReport.rpt";
filePath = func.GetReportsDirectory();
// IF FILE EXISTS... THEN
string fileExists = filePath +#"\"+ fileName;
if (System.IO.File.Exists(fileExists))
{
// Must Convert Object to List for some crazy reason?
// See: https://stackoverflow.com/a/35055093/1819403
var labelList = new List<ParcelLabelView> { label };
newDoc.Load(fileExists);
newDoc.SetDataSource(labelList);
try
{
// Set User Selected Printer Name
newDoc.PrintOptions.PrinterName = report.Printer;
newDoc.PrintToPrinter(1, false, 0, 0); //copies, collated, startpage, endpage
// Save Printing
report.Printed = true;
db.Entry(report).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}
catch (Exception e2)
{
string err = e2.Message;
}
}