How do you set a new Contact with a yearless birthday with Xamarin iOS?
iOS Documentation states you can just leave the NSDateComponent.year field blank for a yearless birthday.
After trying this in Xamarin iOS, it bugs out the birthday field on the New Contact UI, making it unusable.
var store = new CNContactStore();
var contact = new CNMutableContact();
// construct birthday w/o year
var birthDate = new NSDateComponents();
birthDate.Month = 11;
birthDate.Day = 12;
contact.Birthday = birthDate;
// pop iOS Contact UI
var editor = CNContactViewController.FromNewContact (contact);
editor.ContactStore = store;
editor.AllowsActions = false;
editor.AllowsEditing = true;
navcontroller.PushViewController(editor,true);
You need to save the contact first, then the iOS Contact Editor can handle the year-less date correctly.
var store = new CNContactStore();
var contact = new CNMutableContact()
{
GivenName = "Stack",
FamilyName = "Overflow"
};
var birthDate = new NSDateComponents();
contact.Birthday = new NSDateComponents()
{
Month = 11,
Day = 12,
};
######
var saveRequest = new CNSaveRequest();
saveRequest.AddContact(contact, null);
NSError error;
store.ExecuteSaveRequest(saveRequest, out error);
######
var editor = CNContactViewController.FromNewContact(contact);
editor.ContactStore = store;
editor.AllowsActions = false;
editor.AllowsEditing = true;
PresentViewControllerAsync(editor, true);
Figured it out. You have to set the calendar in the NSDateComponents to Gregorian.
var store = new CNContactStore();
var contact = new CNMutableContact();
// construct birthday w/o year
var birthDate = new NSDateComponents();
birthDate.Calendar = new NSCalendar(NSCalendarType.Gregorian);
birthDate.Month = 11;
birthDate.Day = 12;
contact.Birthday = birthDate;
// pop iOS Contact UI
var editor = CNContactViewController.FromNewContact (contact);
editor.ContactStore = store;
editor.AllowsActions = false;
editor.AllowsEditing = true;
navcontroller.PushViewController(editor,true);
Related
I'm developing an application in Xamarin for Android which needs to get a list of calendars. I've found an example how to do it but there is used CursorLoader which is mark as deprecated. I wasn't able to find a replacement of the function in Xamarin. Is there an another way how to get list of calendars?
Thanks.
AndroidCalendarModels _androidCalendarModel = new AndroidCalendarModels();
string[] calendarsProjection = {
CalendarContract.Calendars.InterfaceConsts.Id,
CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
CalendarContract.Calendars.InterfaceConsts.AccountName
};
var calendarsUri = CalendarContract.Calendars.ContentUri;
var loader = new CursorLoader(Android.App.Application.Context, calendarsUri, calendarsProjection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();
while (cursor.MoveToNext())
{
int calId = cursor.GetInt(0);
string calName = cursor.GetString(1);
string calAccount = cursor.GetString(2);
_androidCalendarModel.Calendars.Add(new AndroidCalendarModel()
{
Id = calId,
AccountName = calAccount,
CalendarDisplayName = calName,
});
}
In my mind, the script below takes a form submission gathered on a sheet and books it into a calendar (calId). In reality, however, the script falls apart at var event = thisCalendar.createEvent(:
Exception: Invalid argument: booker.
function calendarUpload() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Form Responses 1");
var Avals = ss.getRange("A1:A").getValues();
var lastRow = Avals.filter(String).length;
Logger.log(lastRow);
for (var i = 2; i <= lastRow ; i++) {
var approvalStatus = sheet.getRange(i,1).getValue();
var name = sheet.getRange(i,8).getValue(); //Event name.
var description = sheet.getRange(i,9).getValue(); //Event description, agenda.
var date = sheet.getRange(i,5).getValue(); //Event date.
var formattedStart = Utilities.formatDate(new Date(date), 'Europe/London', 'MMMM dd, yyyy');
var startTime = sheet.getRange(i,6).getValue(); //Event starting time.
var formattedSTime = Utilities.formatDate(new Date(startTime), 'Europe/London','hh:mm');
var endTime = sheet.getRange(i,7).getValue(); //Estimated end time of event.
var formattedETime = Utilities.formatDate(new Date(endTime), 'Europe/London','hh:mm');
var guests = sheet.getRange(i,15,1,10).getValues(); //Event guests by email address.
var staffMember = sheet.getRange(i,10).getValue(); //Meeting with... Determines Calendar ID (CalID).
var calId = sheet.getRange(i,11).getValue(); //Calendar.
var booker = sheet.getRange (i,3).getValue(); //The person booking the meeting.
var bookerEmail = sheet.getRange(i,4).getValue(); //Email booker, adds to guest list.
var eventStatus = sheet.getRange(1,1,i,12).getCell(i,12);
//Create eventName based on reason for meeting.
if (name == "one-on-one"){
var title = "ℳ " + booker + " and " + staffMember;
} else {
var title = name
}
Logger.log(eventStatus);
Logger.log(title);
Logger.log(formattedStart);
Logger.log(formattedSTime);
Logger.log(formattedETime);
Logger.log(guests);
var startDateandTime = (formattedStart+" "+formattedSTime);
var endDateandTime = (formattedStart+" "+formattedETime);
Logger.log(startDateandTime);
if (approvalStatus == "Approved" && eventStatus.isBlank()){
var thisCalendar = CalendarApp.getCalendarById(calId);
Logger.log('calId: '+calId);
Logger.log(thisCalendar );
var event = thisCalendar.createEvent(
title,
new Date(startDateandTime),
new Date(endDateandTime),
{guests: guests && bookerEmail, description: description});
Logger.log('Event Series ID: ' + eventSeries.getId());
var setEventStatus = sheet.getRange(i,12).setValue('Event Series ID: ' + event.getId());
} else {
Logger.log("No Events Found");
}
}
}
The logs seem to show that things go smoothly. Is there anything that you'd do differently? What can I do about the Exception error?
Example sheet.
I need to unify the "display name" of an business-process-flow in our environment.
The standard BPF "Opportunity Sales Process", should be called "Opportunity Sales Process" regardless of the UI language of the use (e.g. "Vertriebsprozess Verkaufschance" is the "LocalizedName" for German users).
I have not found any way to change the "LocalizedName" value - the only option is see, is the direct update of the customizations.xml.
Is is possible to update the "LocalizedName" of an BPF via code?
IOrganizationService os; // todo - initialize
Its not clear what you're after :) If you're after updating entity metadata - that is doable:
var request = new RetrieveEntityRequest { LogicalName = "opportunitysalesprocess" };
var response = (RetrieveEntityResponse)os.Execute(request);
var label = response.EntityMetadata.DisplayName.LocalizedLabels
.First(l => l.LanguageCode == 1033);
label.Label = "Thats Not My Name";
os.Execute(new UpdateEntityRequest { Entity = response.EntityMetadata });
If you're after updating process name in grid of processes; it is:
var sec = new SetLocLabelsRequest
{
AttributeName = "name",
Labels = new LocalizedLabel[]
{
new LocalizedLabel
{
Label = "Thats not my name",
LanguageCode = 1033
}
},
EntityMoniker = new EntityReference("workflow",
new Guid("3E8EBEE6-A2BC-4451-9C5F-B146B085413A"))
};
var res = (SetLocLabelsResponse)os.Execute(sec);
Refer to
https://learn.microsoft.com/en-us/dotnet/api/microsoft.crm.sdk.messages.setloclabelsrequest?view=dynamics-general-ce-9
https://learn.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.messages.updateentityrequest?view=dynamics-general-ce-9
I have a huge spreadsheet matrix, from which I create a long list of check boxes. The users then select different abilities, press search. The code the cross-checks with the database spreadsheet, returning names of the persons who has those abilities.
I need to update the "rightPanel" with the results of my search. But i simple can't figure out how to - if at all posible - update a panel in my UI..
var dataSSkey = 'sheetID'; //datasheet ID
var dataSheet = SpreadsheetApp.openById(dataSSkey).getSheetByName('Ansatte');
var groupsArray = [[],[],[],[]];
var lastRow = dataSheet.getLastRow();
var lastColumn = dataSheet.getLastColumn();
var dataArray = dataSheet.getRange(1,1,lastRow,lastColumn).getValues();
var numberGroups
var app = UiApp.createApplication().setTitle('Find Consultant');
var panel = app.createVerticalPanel();
var leftPanel = app.createVerticalPanel().setWidth(450);
var rightPanel = app.createVerticalPanel().setWidth(450);
var grid = app.createGrid(1, 2).setId('myGrid')
var outputArray = []; //to store output from search
var positiveList = [[],[]]; //array to store name and folder-ID of consultants matching
var numberPositive = 0; //number of consultants matching
function doGet() {
buildGroupsArray()
addCheckBoxesToUI()
var scrollPanel = app.createScrollPanel().setHeight(460);
//Search button
var searchButton = app.createButton('Search');
var clickHandler = app.createServerClickHandler("respondToSearch");
searchButton.addClickHandler(clickHandler);
clickHandler.addCallbackElement(panel);
var spacerImage = app.createImage("http://www.bi..ge.jpg").setHeight(3);
scrollPanel.add(panel);
rightPanel.add(app.createLabel('resultat her'));
leftPanel.add(scrollPanel);
leftPanel.add(spacerImage);
leftPanel.add(searchButton);
grid.setWidget(0, 0, leftPanel)
grid.setWidget(0, 1, rightPanel);
app.add(grid);
return app;
}
function respondToSearch(e){
var numberLogged = 0;
//define firstEmpty
var firstEmpty = "A"+lastRow;
if(lastRow !== 1){
firstEmpty = "A"+(lastRow+1);
};
//find selected competencies --> store in array + count competencies
for(i = 1; i <= lastRow; i++){
if (e.parameter["Checkbox"+i] == "true") {
var value = e.parameter["CheckboxValue"+i];
outputArray[numberLogged] = value;
numberLogged++;
}
}
for(i = 2; i <= lastColumn; i++){
var numberCorrect = 0;
//Run through rows according to content of output from selection
for(j in outputArray){
//Check if consultant own selected competency
if(dataArray[outputArray[j]][i] == "x"){
numberCorrect++; //if consultant owns selected competency then count
}
}
//if consultant owns all competencies, then add name and folder-id to array
if(numberCorrect == numberLogged){
positiveList[0][numberPositive] = dataArray[1][i]; //Add consultant name
positiveList[1][numberPositive] = dataArray[2][i]; //Add consultant-folder ID
numberPositive++ //count the number of consultants that own all competencies
}
}
for(j in positiveList[0]){
var name = positiveList[0][j];
var id = positiveList[1][j];
Logger.log(name);
Logger.log(id)
var anchor = app.createAnchor(name,'https://ww......folderviewid='+id);
rightPanel.add(anchor)
}
return app;
}
I don't really understand the problem you have...
In your handler function you only have to use app=UiApp.getActiveApplication() and from there populate the panel exactly the same way you did it in the doGet() function, ending with a return app; that will actually update the current Ui.
There are dozens of examples all around... did I misunderstand something in your question ?
Edit : following your comment.
I suppose you defined your variables outside of the doGet function hoping they will become global and so available to all the functions in your script but this is not going to work. Global variables in Google Apps script can't be updated by functions.
I would strongly recommend that you create app and panels in the doGet function and give them an ID so that you can get them back and update their values (or content) from the handler functions.
Here is a re-written version of your code (didn't test)
: (some parts are not reproduced (see //...)
var dataSSkey = 'sheetID'; //datasheet ID
var dataSheet = SpreadsheetApp.openById(dataSSkey).getSheetByName('Ansatte');
var groupsArray = [[],[],[],[]];
var lastRow = dataSheet.getLastRow();
var lastColumn = dataSheet.getLastColumn();
var dataArray = dataSheet.getRange(1,1,lastRow,lastColumn).getValues();
var numberGroups
var outputArray = []; //to store output from search
var positiveList = [[],[]]; //array to store name and folder-ID of consultants matching
var numberPositive = 0; //number of consultants matching
function doGet() {
var app = UiApp.createApplication().setTitle('Find Consultant');
var panel = app.createVerticalPanel();
var leftPanel = app.createVerticalPanel().setWidth(450).setId('leftPanel');
var rightPanel = app.createVerticalPanel().setWidth(450).setId('rightPanel');;
var grid = app.createGrid(1, 2).setId('myGrid')
buildGroupsArray(app); // in this function get app as parameter or use UiApp.getActiveApplication();
addCheckBoxesToUI(app);// in this function get app as parameter or use UiApp.getActiveApplication();
var scrollPanel = app.createScrollPanel().setHeight(460);
//...
//...
return app;
}
function respondToSearch(e){
//...
//...
var app = UiApp.getActiveApplication();
var rightPanel = app.getElementById('rightPanel');
for(j in positiveList[0]){
var name = positiveList[0][j];
var id = positiveList[1][j];
Logger.log(name);
Logger.log(id)
var anchor = app.createAnchor(name,'https://ww......folderviewid='+id);
rightPanel.add(anchor)
}
return app;
}
I want to schedule multiple Tile Notifications while my app is running, so that when my app is in background, my schedule Tile notifications appear one by one using respective occurrence time.
But somehow when I schedule multiple (3) notifications only last one appears.
String message = "";
String key = "FamilyFarm" + count;
if (String.IsNullOrEmpty(duration) || String.IsNullOrEmpty(name))
return;
IsolatedStorageSettings setting = IsolatedStorageSettings.ApplicationSettings;
if (setting.Contains(key))
{
setting.Remove(key);
}
setting.Add(key, name);
count++;
ShellTileSchedule SampleTileSchedule = new ShellTileSchedule();
bool TileScheduleRunning = false;
// Update will happen one time.
SampleTileSchedule.Recurrence = UpdateRecurrence.Onetime;
// Start the update schedule now.
SampleTileSchedule.StartTime = DateTime.Now;
SampleTileSchedule.RemoteImageUri = new Uri(#"http://www.weather.gov/forecasts/graphical/images/conus/MaxT1_conus.png");
SampleTileSchedule.Start();
TileScheduleRunning = true;
ShellTile oTile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("flip".ToString()));
if (oTile != null && oTile.NavigationUri.ToString().Contains("flip"))
{
FlipTileData oFliptile = new FlipTileData();
oFliptile.Title = name;
oFliptile.Count = 11;
oFliptile.BackTitle = key;
oFliptile.BackContent = name;
oFliptile.WideBackContent = name;
oFliptile.SmallBackgroundImage = new Uri("Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative);
oFliptile.BackgroundImage = new Uri("Assets/Tiles/FlipCycleTileLarge.png", UriKind.Relative);
oFliptile.WideBackgroundImage = new Uri("Assets/Tiles/Flip/FlipCycleTileLarge.png", UriKind.Relative);
oFliptile.BackBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative);
oFliptile.WideBackBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative);
oTile.Update(oFliptile);
// MessageBox.Show("Flip Tile Data successfully update.");
//return true;
}
else
{
// once it is created flip tile
Uri tileUri = new Uri("/MainPage.xaml?tile=flip", UriKind.Relative);
ShellTileData tileData = new FlipTileData()
{
Title = "Hello FamilyFarm",
BackTitle = key,
BackContent = name,
WideBackContent = name,
Count = 8,
SmallBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative),
BackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative),
WideBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative),
};
ShellTile.Create(tileUri, tileData, true);
}
If you want to see the Tile Cycle, you should use
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207036(v=vs.105).aspx
or
Creating CycleTile with remote images
Otherwise if you want to see the Update taking place you should put a Thread.Sleep or Task.Wait between updates to be able to see them.
When you want some cycling in WP7.8 you can use MangoPollo.