Where can I find updated, live exchange rates? - iphone

How do I link live currency exchange rates to my iPhone app? First, anyone know any sites where I can get the exchange rates? And second, how do I link that to my app? I want to do what this app does. http://the-dream.co.uk/currencee/

Here is a blog post about this, however to recap, if you use TBXML you can do it with the methods below.
They do the following:
Assume you have made a mutable dictionary object as a class property called exchangeRates
Set's EUR as the base rate (value of 1.0)
Call the European Central Bank's exchange rate XML feed and parses it.
After you've called the loadExchangeRates() method you can obtain a specific exchange rate by doing:
NSDecimalNumber *rate = [NSDecimalNumber decimalNumberWithString:[self.exchangeRates objectForKey:#"USD"]];
Here are the methods:
- (void)loadExchangeRates {
// initialize rate array
exchangeRates = [[NSMutableDictionary alloc] init];
// Load and parse the rates.xml file
TBXML * tbxml = [[TBXML tbxmlWithURL:[NSURL URLWithString:#"http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml"]] retain];
// If TBXML found a root node, process element and iterate all children
if (tbxml.rootXMLElement)
[self traverseElement:tbxml.rootXMLElement];
// add EUR to rate table
[exchangeRates setObject:#"1.0" forKey:#"EUR"];
// release resources
[tbxml release]; }
- (void) traverseElement:(TBXMLElement *)element {
do {
// Display the name of the element
//NSLog(#"%#",[TBXML elementName:element]);
// Obtain first attribute from element
TBXMLAttribute * attribute = element->firstAttribute;
// if attribute is valid
NSString *currencyName;
while (attribute) {
/* Display name and value of attribute to the log window
NSLog(#"%#->%# = %#",
[TBXML elementName:element],
[TBXML attributeName:attribute],
[TBXML attributeValue:attribute]);
*/
// store currency
if ([[TBXML attributeName:attribute] isEqualToString: #"currency"]) {
currencyName = [TBXML attributeValue:attribute];
}else if ([[TBXML attributeName:attribute] isEqualToString: #"rate"]) {
// store currency and rate in dictionary
[exchangeRates setObject:[TBXML attributeValue:attribute] forKey:currencyName];
}
// Obtain the next attribute
attribute = attribute->next;
}
// if the element has child elements, process them
if (element->firstChild)
[self traverseElement:element->firstChild];
// Obtain next sibling element
} while ((element = element->nextSibling));
}

I realise this question has been answered already, but for anyone else looking for a solution to this same issue, there's also a great JSON solution available at openexchangerates.org as well.

My first port of call would be to find a webservice that provides currency rates with a public API.
Then you'd need to integrate some functionality into your app that communicates with the API in order to get the information you need.
There might be some services that offer the exchange rates in an RSS feed or similar feed. You could then parse the XML downloaded from that feed into some objects that you can use in your app.

Average monthly exchange rates of GBP to other currencies you can find as xml in link -
string url = "http://www.hmrc.gov.uk/softwaredevelopers/rates/exrates-monthly-" +
month2SymbolsYear2SymbolsString + ".xml";
then you can load this xml into lists and use in your code -
string xmlStr;
using (var wc = new WebClient())
{
xmlStr = wc.DownloadString(url);
}
var doc = XDocument.Parse(xmlStr);
var currenciesCodes = doc.Root.Elements().Select(x => x.Element("currencyCode"));
var rates = doc.Root.Elements().Select(x => x.Element("rateNew"));
List<string> currenciesCodesList = new List<string>();
foreach (var code in currenciesCodes)
{
currenciesCodesList.Add(code.Value);
}
List<double> currenciesRatesToGBPList = new List<double>();
foreach (var rate in rates)
{
double rateDouble;
if (!Double.TryParse(rate.Value, out rateDouble))
{
errorMessage = "During monthly average exchanges rates loading from page" + "\r\n" +
url + "\r\n" +
"program found text value - " + rate.Value + "\r\n" +
"which can't be converted to double value" + "\r\n" +
"Program can't correctly form reports and will end now.";
return errorMessage;
}
currenciesRatesToGBPList.Add(rateDouble);
}

Related

get value for specific question/item in a Google Form using Google App Script in an on submit event

I have figured out how to run a Google App Script project/function on a form submit using the information at https://developers.google.com/apps-script/guides/triggers/events#form-submit_4.
Once I have e I can call e.response to get a FormResponse object and then call getItemResponses() to get an array of all of the responses.
Without iterating through the array and checking each one, is there a way to find the ItemResponse for a specific question?
I see getResponseForItem(item) but it looks like I have to somehow create an Item first?
Can I some how use e.source to get the Form object and then find the Item by question, without iterating through all of them, so I could get the Item object I can use with getResponseForItem(item)?
This is the code I use to pull the current set of answers into a object, so the most current response for the question Your Name becomes form.yourName which I found to be the easiest way to find responses by question:
function objectifyForm() {
//Makes the form info into an object
var myform = FormApp.getActiveForm();
var formResponses = myform.getResponses()
var currentResponse = formResponses[formResponses.length-1];
var responseArray = currentResponse.getItemResponses()
var form = {};
form.user = currentResponse.getRespondentEmail(); //requires collect email addresses to be turned on or is undefined.
form.timestamp = currentResponse.getTimestamp();
form.formName = myform.getTitle();
for (var i = 0; i < responseArray.length; i++){
var response = responseArray[i].getResponse();
var item = responseArray[i].getItem().getTitle();
var item = camelize(item);
form[item] = response;
}
return form;
}
function camelize(str) {
str = str.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()#\+\?><\[\]\+]/g, '')
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
return index == 0 ? match.toLowerCase() : match.toUpperCase();
});
}
//Use with installable trigger
function onSubmittedForm() {
var form = objectifyForm();
Logger.log(form);
//Put Code here
}
A couple of important things.
If you change the question on the form, you will need to update your
code
Non required questions may or may not have answers, so check if answer exists before you use it
I only use installable triggers, so I know it works with those. Not sure about with simple triggers
You can see the form object by opening the logs, which is useful for finding the object names

Send Email fields not rendering in Sitecore Web Forms For Marketers

I have an issue with the WFFM Send Email Message save action (Sitecore 6.5.0). I'm trying to send an email that includes the form placeholders from the "Insert Field" dropdown in the Send Email editor. Sometimes the fields will render correctly, but most times the email will include the placeholder text instead of the field's actual value.
For example, this is the email that is coming through:
First Name: [First Name]
Last Name: [Last Name]
Email: [Email Address]
Company Name: [Company Name]
Phone Number: [Phone Number]
I think it has to do with the Send Email editor using a rich text editor for the email template, but I've tried adjusting the message's HTML to no avail. This is what the markup looks like: (the <p> tags and labels used to be inline, but that didn't work either)
<p>First Name:
[<label id="{F49F9E49-626F-44DC-8921-023EE6D7948E}">First Name</label>]
</p>
<p>Last Name:
[<label id="{9CE3D48C-59A0-432F-B6F1-3AFD03687C94}">Last Name</label>]
</p>
<p>Email:
[<label id="{E382A37E-9DF5-4AFE-8780-17169E687805}">Email Address</label>]
</p>
<p>Company Name:
[<label id="{9C08AC2A-4128-47F8-A998-12309B381CCD}">Company Name</label>]
</p>
<p>Phone Number:
[<label id="{4B0C5FAC-A08A-4EF2-AD3E-2B7FDF25AFA7}">Phone Number</label>]
</p>
Does anyone know what could be going wrong?
I have encountered this issue before, but was using a custom email action. I managed to fix it by not using the deprecated methods in the SendMail class and instead using the
Sitecore.Form.Core.Pipelines.ProcessMessage namespace's ProcessMessage and ProcessMessageArgs classes.
My use case was a little more complicated than yours, as we were also attaching a PDF brochure to our message (which is why we were using the custom email action in the first place), but here is the code:
public class SendBrochureEmail : SendMail, ISaveAction, ISubmit
{
public new void Execute(ID formId, AdaptedResultList fields, params object[] data)
{
try
{
var formData = new NameValueCollection();
foreach (AdaptedControlResult acr in fields)
{
formData[acr.FieldName] = acr.Value;
}
var senderName = formData["Your Name"];
var emailTo = formData["Recipient Email"];
var recipientName = formData["Recipient Name"];
var documentTitle = formData["Document Title"];
if (documentTitle.IsNullOrEmpty())
{
documentTitle = String.Format("Documents_{0}", DateTime.Now.ToString("MMddyyyy"));
}
Subject = documentTitle;
if (!String.IsNullOrEmpty(emailTo))
{
BaseSession.FromName = senderName;
BaseSession.CatalogTitle = documentTitle;
BaseSession.ToName = recipientName;
var tempUploadPath = Sitecore.Configuration.Settings.GetSetting("TempPdfUploadPath");
var strPdfFilePath =
HttpContext.Current.Server.MapPath(tempUploadPath + Guid.NewGuid().ToString() + ".pdf");
//initialize object to hold WFFM mail/message arguments
var msgArgs = new ProcessMessageArgs(formId, fields, MessageType.Email);
var theDoc = PdfDocumentGenerator.BuildPdfDoc();
theDoc.Save(strPdfFilePath);
theDoc.Clear();
FileInfo fi = null;
FileStream stream = null;
if (File.Exists(strPdfFilePath))
{
fi = new FileInfo(strPdfFilePath);
stream = fi.OpenRead();
//attach the file with the name specified by the user
msgArgs.Attachments.Add(new Attachment(stream, documentTitle + ".pdf", "application/pdf"));
}
//get the email's "from" address setting
var fromEmail = String.Empty;
var fromEmailNode = Sitecore.Configuration.Factory.GetConfigNode(".//sc.variable[#name='fromEmail']");
if (fromEmailNode != null && fromEmailNode.Attributes != null)
{
fromEmail = fromEmailNode.Attributes["value"].Value;
}
//the body of the email, as configured in the "Edit" pane for the Save Action, in Sitecore
msgArgs.Mail.Append(base.Mail);
//The from address, with the sender's name (specified by the user) in the meta
msgArgs.From = senderName + "<" + fromEmail + ">";
msgArgs.Recipient = recipientName;
msgArgs.To.Append(emailTo);
msgArgs.Subject.Append(Subject);
msgArgs.Host = Sitecore.Configuration.Settings.MailServer;
msgArgs.Port = Sitecore.Configuration.Settings.MailServerPort;
msgArgs.IsBodyHtml = true;
//initialize the message using WFFM's built-in methods
var msg = new ProcessMessage();
msg.AddAttachments(msgArgs);
msg.BuildToFromRecipient(msgArgs);
//change links to be absolute instead of relative
msg.ExpandLinks(msgArgs);
msg.AddHostToItemLink(msgArgs);
msg.AddHostToMediaItem(msgArgs);
//replace the field tokens in the email body with the user-specified values
msg.ExpandTokens(msgArgs);
msg.SendEmail(msgArgs);
//no longer need the file or the stream - safe to close stream and delete delete it
if (fi != null && stream != null)
{
stream.Close();
fi.Delete();
}
}
else
{
Log.Error("Email To is empty", this);
throw new Exception("Email To is empty");
}
}
catch (Exception ex)
{
Log.Error("Test Failed.", ex, (object) ex);
throw;
}
finally
{
BrochureItems.BrochureItemIds = null;
}
}
public void Submit(ID formid, AdaptedResultList fields)
{
Execute(formid, fields);
}
public void OnLoad(bool isPostback, RenderFormArgs args)
{
}
}
It is very possible that the Email Action that WFFM ships with is using the deprecated methods, which could be your problem. I do not have time to look into it, but you can decompile the DLL and look to see what their Email Action is doing. Regardless, the above code should work out of the box, save for updating the fields to those that you are using and removing the code for attaching the PDF, should you choose to not have attachments.
Good luck, and happy coding :)
If you change a field on the form in any way (caption, name, type, etc) the link will change and you need to re-insert the placeholder and move it up to its location in your expected email. This is also true if you duplicate a form. You'll have to reinsert all the fields in the email or you will just get the outcome you show above.
Reinserting upon a change will ensure the value is collected!

Extract entity strings from an Outlook365 item

// Global variables
var _Item;
var _MyEntities;
// The initialize function is required for all apps.
Office.initialize = function (reason) {
var _mailbox = Office.context.mailbox;
// Obtains the current item.
Item = _mailbox.item;
// Reads all instances of supported entities from the subject
// and body of the current item.
MyEntities = _Item.getEntities();
// Checks for the DOM to load using the jQuery ready function.
$(document).ready(function () {
// After the DOM is loaded, app-specific code can run.
});
}
// Gets instances of the Address entity on the item.
function myGetAddresses()
{
var htmlText = "";
// Gets an array of postal addresses. Each address is a string.
var addressesArray = _MyEntities.addresses;
for (var i = 0; i < addressesArray.length; i++)
{
htmlText += "Address : <span>" + addressesArray[i] + "</span><br/>";
}
document.getElementById("entities_box").innerHTML = htmlText;
}
I am using above code to access email address, but I am not able to see any result in entities_box div.
Please suggest how can I can get to,cc and from email address from it.
entities are only available if the message itself has entities extracted (eg "123 Main st, New York, New York 10001"). I would start debugging by first checking if the address has actually been detected (does the Bing Maps app activate on that message? did you leave it enabled?). Then, call json.stringify and see what item.getEntities() actually returns. Here's an article on how to extract entities: http://msdn.microsoft.com/en-us/library/office/fp161071(v=office.15).aspx

Xcode>Instruments>Automation>Mac: is there a way to use regular expression within Automation in Instruments

I am totally new to Instruments>Automation. Trying to test the internal app using Automation in Instruments.
Here is my problem:
Our app has the UI cells generated on the fly. There is no way to predict how many cells will be created and what name they will have. But, all of them will contain a certain string (like "Courses"). The question is - How, using Automation, find out if particular cell contain that string in its name?
You are able to get total cells count simply using "length" property.
var cellsCount = <YourUIATableViewObject>.cells().length;
UIALogger.logMessage("total cells count = " + cellCount);
After that you will be able to get cell properties and operate with them:
for (var i = 0; i < cellsCount; i ++)
{
var cellValue = <YourUIATableViewObject>.cells()[i].value();
var cellName = <YourUIATableViewObject>.cells()[i].name();
UIALogger.logMessage("Cell #"+i+" properties: cellValue ="+cellValue+"; cellName ="+cellName);
//Try to use match() or search() functions to find what you need.
if ( cellName.search("Courses") != -1 )
//if (cellValue.search("Courses") != -1 )
{
UIAlogger.logMessage("Cell #"+i+" contains 'Courses'");
}
else
{
UIAlogger.logMessage("Cell #"+i+" does not contain 'Courses'");
}
}
This JavaScript tutorial will help you:

iPhone: Get value in multi-dimentional array

I have an array that is many levels deep and I am wondering what is the best way to get one of the child element values that is deep in my array.
I assume I need to use a recursive method, but what is the best way to do this? Or is there a faster way to do this?
The array comes from an XML Parser that I am using which builds everything into an array like this (using NSLog to show the structure):
{
children = (
{
children = (
{
children = (
{
children = (
);
data = 12;
element = AssetID;
}
);
data = "";
element = "ns1:GetUserIdByUsernameResponse";
}
);
data = "";
element = "SOAP-ENV:Body";
}
);
data = "";
element = "SOAP-ENV:Envelope";
}
What I would like to get at is the AssetID data, which in this case is 12.
Looks like the parser is returning an NSDictionary for each element with a "children" key that is an NSArray of child elements.
If the response will always be in this format with the AssetID element always in this position, you can directly access it without using recursion or looping.
Use something like this:
//"parserResultObject is the object the parser returns to you
NSDictionary *bodyDict = [[parserResultObject objectForKey:#"children"] objectAtIndex:0];
NSDictionary *responseDict = [[bodyDict objectForKey:#"children"] objectAtIndex:0];
NSDictionary *assetIdDict = [[responseDict objectForKey:#"children"] objectAtIndex:0];
//assuming AssetID's data is stored as an NSNumber...
int assetIdData = [[assetIdDict objectForKey:#"data"] intValue];