How to access an EKCalendar's `account` property - objective-c

Take a look at the documentation for EKCalendar. It's pretty simple, it has five properties, only one of which is a string called title. Now if you have multiple calendars on your iPhone and you open iCal's Calendar settings, you can see that all calendars are nicely grouped by another string called account.
What I can't figure out, is how to do the same, because although you can see the account when you NSLog a EKCalendar instance, you can't access it:
EKCalendar <0x1851b0> {title = Work; type = CalDAV; account = some#addr.ess; allowsModify = YES; color = 0.690196 0.152941 0.682353 1.000000}
There is no account property, and trying to access the valueForKey:#"account" isn't working either, unsurprisingly.
So how do I get to that account property? Such a simple thing, driving me nuts! Help is much appreciated.
Update: since iOS 5.0, EKCalendar has a source property.

If you use class-dump on the iOS 4.3 (Simulator) SDK, you'll see that there's a read-only method -(id)accountName. However, since it's not in the headers, it's unfortunately private API and you can't use it if you want your App to be accepted in the App Store.
I recommend that you file an enhancement request with Apple requesting that this method be made public.
Though thinking about it: If you're really desperate, why not parse the output of -[EKCalendar description]? It's very very very bad style and it'll probably break in the future, but you might make it through the App Store review ;) In particular if you only use it for grouping and write your code extremely defensive so it doesn't break but simply doesn't group, should the output of the description method be formatted differently.

This information is not available in the 4.0 SDK. Have you looked at the developer previews of the forthcoming SDK to see if that might contain more information?

And on iOS6? It seems the private property [EKCalendar accountName] vanished. And [EKCalendar description] does not contain account anymore. :
EKCalendar <0x200f50e0> {title = test#gmail.com; type = Exchange; allowsModify = YES; color = #44A703;}
The [EKCalendar source] provides a EKSource object, that has a title but this is not the name I typed when I created the account but seems to be a more generic name, e.g. Exchange, Other, CalDAV.

Related

AbilitySystemComp GetSet retrun null

I have been implementing GAS in a project of mine and something is bugging me to no end.
In this youtube video made by unreal, they use the function
AttributeSet = AbilitySystemComponent->GetSet<UGASAbilityDemoAttributeSet>();
Where according to the video and the doc, GetSet is supposed to return the set if it exists or creates it and then give the newly created set. However, when I use it, it always returns null and I can't find a difference in my implementation.
What is it that I am doing wrong?
Other Sources
In the docs, they also mention to do the same.
I also downloaded and look at the implementation for the new Lyra demo project where it's a lot more complex, but in the end, they, themself, do the same.
Note
I know I can just
MySet = CreateDefaultSubObject<UGASAbilityDemoAttributeSet>("My Set")
To create my set, but the fact that I'm unable to use it like they do bug me.
I had the same issue. I found out that you have to first set the "Default Starting Data" on you Ability System Component in the editor. After that the GetSet method returns an object.
screenshot

Convert AppleScript response to JSON

I have a Cocoa application, part of it takes AppleScript from the user in a web view. I currently can pass a single string from a command (e.g. the current iTunes song name), however, if I run a command that returns a record (I believe that's what it is based on my research, could be wrong) such as the below I get '(null)' as the stringValue.
tell application "iTunes"
get properties of current track
end tell
If I run this in Script Debugger I can get this as a table shown below, so it's clearly possible.
However, nothing I've tried seems to be working. Based on a number of SO answers I've tried different ways, such as looping over every descriptor index as in this question. However, this doesn't work anymore, as it seems the key is not included in the array.
So, basically, I need to be able to convert an AppleScript output to JSON. I have a serialiser so that's not the issue, as long as I can get them in to Cocoa objects I'm set. What's the best way to do this?
Thanks
Many months late as an answer, but in case you or anyone else cares, here is what I did with a similar problem.
Check out the (sadly defunct) AppScript framework. That combined with lightly modified SBJSON let me convert any AppleScript record into JSON via Cocoa objects.
I used it in JSON Helper which is free on the Mac AppStore. You can also see the source to an earlier version on Google code here, which might be useful if you want to use the modified version of SBJSON.
In my example below the AppleScript record is being supplied via a scripting command.
#implementation makeJSONFromRecord
- (id)performDefaultImplementation {
NSDictionary *asRecord;
NSString *result;
AEMCodecs *codecs = [[AEMCodecs alloc] init];
// Use appscript framework to unpack the event into an object we can use
asRecord =[codecs unpack:[self directParameter]];
[codecs release];
// Use the JSON framework to convert the object to JSON notation
result = [asRecord JSONRepresentation];
if (result==nil) {
//We failed to create any valid JSON so return nothing
NSLog(#"Failed to make JSON from: %#", asRecord);
result=#"";
}
// Return the result to the applescript
return result;
}
#end

Working with reference lists in canned workflows

I am experimenting with canned workflows and need to know if it's possible to work with lists of domain objects in a reference variable, i.e. reference lists. Here is some code to illustrate the concept...
public void Run(Workflow workflow)
{
ReferenceVariable variable = workflow.InputReferenceVariables.First();
WorkflowRunner runner = new WorkflowRunner(workflow);
List<PointSet> pointSets = PetrelProject.Inputs.Selected.OfType<PointSet>().ToList();
runner.SetInputVariableBinding(variable, pointSets);
runner.Run();
}
This following picture shows the basic workflow.
"Local reference variable 1" is the input variable to which I am assigning the reference list. I know the example is hacky, but I tried to simplify everything as much as possible.
Anyways, it doesn't seem to work by binding a list, but it also doesn't throw any exceptions. Nothing happens at all when I run it. Anyone have any ideas?
Official response from Schlumberger is that reference lists are not yet supported. There is a work item in their system to provide a reference list API, but it is not yet target for a release.

Another doGet() issue with Google Apps Script - "Unknown macro doGet" error

I'am obviously new to Google Apps Script, nevertheless I have some experience in coding in C, PHP and Java. Since we would like to create a small CRM in our company with Google Apps Script, we need to create an application with a form available on Google Sites. I've been searching an answer for this problem a long time, I haven't unfortunately found any answer. I have a code like this:
var klienci_id = new Array(100);
var klienci_nazwa = new Array(100);
var klienci_adres = new Array(100);
var klienci_osoba = new Array(100);
var klienci_telefon = new Array(100);
var klienci_email = new Array(100);
function doGet(e) {
var app = UiApp.createApplication();
// hello world label
var helloworldLabel = app.createLabel("I love Apps Script!").setStyleAttribute("fontSize","16px");
// add the label to the app container
app.add(helloworldLabel);
return app;
}
function main() {
var klienci = SpreadsheetApp.openById("0ArsOaWajjzv9dEdGTUZCWFc1NnFva05uWkxETVF6Q0E");
var kuchnia_polska = klienci.getSheetByName("Kuchnia polska");
var dane = kuchnia_polska.getRange("D7:F22");
doGet();
}
And everytime I try to publish it and enter the given link I get the error "Unknown macro doGet". I know this is a common problem when somebody doesn't use doGet() function but I do - and it still doesn't work. I also believe that Google should create a thorought documentation on Google Apps Script, which would work the way the Unix manual does, since I just cannot get through all these strange pages of goddamn help :) It's neither a Windows help, nor a good manual ;)
Regards,
Kamil
I have a suspicion that you made a "version" once, published the app, went to the "real" link and not the "development" link, and then added the doGet() function. When you make a version, it freezes the code at that time. The version that the app is published at is the version of the code that will run at the "real" link (what you give users), which allows you to keep editing the code without disturbing existing users of your app. There is a special "development" link given to you in the publish dialog that always refers to the most recent version of the code, but which will only work for you and no one else.
I'm affraid there is a little misunderstanding on your side concerning the use of the 'doGet()' function. When you want to run an application as a webapp, the doc says indeed that it must contain a doGet function but what it doesn't say explicitely is that this function is supposed to be the starting point of the whole app, ie the function that the url will call in the first place. So it doesn't make much sense to have the doGet function called from a so called "main" function since the "main" function is not the main function...
I cannot imagine right now a situation where some function calls the doGet function since every function in the script is called initially (directly or indirectly) from this doGet function.... in fact the 'end' of any other function in the script 'returns' to the doGet initial function. Well this is maybe not absolutely true in every case but it gives you the general idea about how it works.
I'm hoping this is clear enough and, to return to your code snippet, if you remove the doGet(e) call, it will ideed show a nice "I love Apps Script!" but it will never do anything else, certainly not see the "main" function.
I've copied your code here https://script.google.com/macros/d/MJ80AK8t7kbgDcC-NaLPYvH797_hv7HHb/edit?template=app&folder=0AKGkLMU9sHmLUk9PVA
and when deployed as a web app appears to work https://script.google.com/macros/s/AKfycbxOiaukLt7P4pIm7bms7aU16uEo6FuZ-MNOh0tSqUwr/dev
Only thing I can think of is there is something else in your code not copied into the snippet that is throwing the exception.
[Just before the GUI Builder was published I came up with Creating a framework for custom form interfaces using Google Apps Script which might help you with your project]
Thank you both for help. Serge, yes, it's really not obvious what the structure of Google Apps Scripts should be. They are based on JavaScript, however, due to lack of HTML in the code they have completely different flow - so naturally, there has to be a main function which is executed first. And of course in every programming environment it has to have a different name to make it more distinguishable ;-)
I created a new copy of my application, not changing the code completely - deployed it and it works beautifuly. Since I haven't changed anything in access options, it's quite strange that two applications with the same code and the same options don't give the same result. I think it may be a kind of the environment flaw, maybe someone from Google should look at this :)
Here's the link to the script, I've set access to "Anyone with the link".
https://script.google.com/a/macros/foodbroker.pl/s/AKfycbwk2IM-rIYLhQl6HOlbppwGOnw4Ik_kH7ixbaSNVxIE-QR7cq8/exec

Uniquely identify active window on OS X

I’m trying to patch an application that resizes windows using the accessibility API.
I need to maintain a dictionary with the previous sizes of windows. The key needs to identify the currently active window. At the moment, this active window is retrieved via NSAccessibilityFocusedWindowAttribute upon the press of a hotkey.
However, every time this method is called, the returned AXUIElementRef which identifies the window is different! This of course means that I cannot use it as a dictionary key – the dictionary won’t find the corresponding entry.
The following code reproduces the problem:
-(IBAction)testWindowIdentification:(id)sender{
AXUIElementRef focusedApp;
AXUIElementRef focusedWindow;
AXUIElementCopyAttributeValue(_systemWideElement,
(CFStringRef) kAXFocusedApplicationAttribute,
(CFTypeRef*) &focusedApp);
AXUIElementCopyAttributeValue((AXUIElementRef) focusedApp,
(CFStringRef) NSAccessibilityFocusedWindowAttribute,
(CFTypeRef*) &focusedWindow);
CFShow(focusedWindow);
}
_systemWideElement has been initialised in the init method using a call to AXUIElementCreateSystemWide().
The CFShow statement clearly shows different IDs every time the method is called (even though the same window is active), which is useless for me:
<AXUIElement 0x47e850> {pid=42463}
<AXUIElement 0x47e890> {pid=42463}
<AXUIElement 0x47e2c0> {pid=42463}
…
The documentation on AXUIElement shows no method that retrieves a unique attribute for the UI element, and neither does that of the NSAccessibility protocol.
The unique PID is not enough for me, since a process can have multiple windows.
How can I retrieve some unique identifier of the active window in Cocoa?
(By the way, the real code is checking the return codes in the above calls; there is no error, the calls succeed.)
Rob Keniger has the right strategy with his answer here. The only thing missing from this answer (and indeed, the reason for the bounty placement) is a workable implementation that takes the current active window and translates it into a unique key suitable for indexing in the context of the current working application.
Rob's solution sketches this out through use of the CGWindowID given in the context of Quartz Window Services. It is, of course, strongly implied that this window reference is only useful for your current application.
Getting this window reference is tricky, because no strong guarantees exist between the Accessibility API and Quartz Window Services. However, you can work around this in the following ways:
Use extern "C" AXError _AXUIElementGetWindow(AXUIElementRef, CGWindowID* out);, as documented here. This isn't guaranteed to work, but it works as a ground-floor test to get things started if it works in your version of OSX.
Get the CGWindowID directly, using, for example, HIWindowGetCGWindowID(). More details about selecting the active window and extracting the ID can be found in the reference manual for the Carbon Window Manager (warning: large PDF).
Catalog your CGWindowID set using something like CGWindowListCreateDescriptionFromArray, exactly as Rob suggested. The goal here is then to find some scheme for bridging the Accessibility API and Quartz, but this is conceivable by utilizing, for example, a callback bound to the context of your current active window. I honestly don't know an optimal example of this that's properly future-proofed, however.
Of the options, I recommend going with 2. for your current needs, if you're unable to create some other decorator for your windows to uniquely identify them. It's currently defined in the legacy code base, but it will do what you desire.
Best of luck with your application.
I think you might be able to use the Quartz Window Services functions, specifically CGWindowListCreateDescriptionFromArray to enumerate the currently active windows in a particular app.
This call is lower-level than AppKit and isn't going to tell you which is the active window, but it will give you window IDs that are unique for the current user session. It's not a great solution, but you could compare the window bounds information with what you receive from the accessibility APIs to associate windows with their real IDs.