Reflection Swift 2.0 XCode 7 beta 5 - swift2

Apple has changed the Swift reflection in XCode 7 beta 5. The global reflect() function is gone, and you'll have to do this:
let mirror = Mirror(reflecting: object)
It gives more or less the same information in a nicer way (no more .1 og .2 for propertyname and value). But I can't find a way to explore if the mirrored item is an instance of a class.
The older implementation you could check the following:
reflectedProperty.1.objectIdentifier != nil || reflectedProperty.1.count > 0
But objectIdentifier seems to be gone and the count is always 2 regardless of type.
Help anyone?

Ok so I found a workaround. I was iterating over mirror.children.enumerate() which seemed to make all the properties of type String. Instead I dug into Apple preliminary documentation, and read that it could be a good idea to "upgrade" children to e.g. AnyRandomAccessCollection. Which made it possible to rely on the count of an objects children to determine if it's an object (after testing whether it's an array)
Currently I have a functioning Swift class to JSON Serializer working here on this gist if you are interested in the code:
https://gist.github.com/peheje/cc3618253d4f38ea4885

I am not sure if you are looking for this, but the output for the following is "Class"
mirror.displayStyle

Related

DMQL2 Query Syntax for PHRets v2 Seach() to include filter arguments?

(It's been a while since I've been here.)
I've been using the first version of PHRets v1 for years, and understood it well enough to get by, but now I'm trying to understand the advantages of v2.6.2. I've got it all installed and the basics are working fine. My issues are pretty much with comprehending fine points of query syntax that goes into the rets=>Search() statement. (I'm much more familiar with SQL statements). Specifically, I'd like to have a query return a list of properties, EXCLUDING those which already have the status of "Sold".
Here's where I am stuck: If I start with this
`$results = $rets->Search('Property', 'A','*',['Select' => 'LIST_8,LIST_105,LIST_15,LIST_19,listing_office_shortid']);`
That works well enough. BUT I'd like to fit in a filter like:
"LIST_15 != Sold", or "NOT LIST_15=Sold"...something like that. I don't get how to fit/type that into a PHRets Search().
I like PHRets but it is so hard to find well-organized/complete documentation about specific things like this. Thanks in advance.
As in my comment above I've figured out that the filter goes in the third argument position ('*', as in the original question). The tricky thing was having to find a specific "sold" code for each class of properties and placing it in that position like so: '(LIST_15=~B4ZIT1Y75TZ)', (notice the =~ combination of characters that means "does not equal" in this context). I've found the code strings for each of the property types (not clear WHY they would need to be unique for each type of property: "Sold" is Sold for any type, after all) but the correct code for a single-family residential property (type 'A' ...at least for the MLS in which I have to search is:
$results = $rets->Search('Property', 'A','(LIST_15=~B4ZIT1Y75TZ)',['Select' => 'LIST_8,LIST_105,LIST_15,LIST_19,listing_office_shortid']);
(again, the code to go with LIST_15 will be different for the different types of properties.) I think there is a better answer that involves more naturalistic language, but this works and I guess I will have to be satisfied with it for now. I hope this is of some use to anyone else struggling with this stuff.

How can I read and set the paper style (aka papername) in Firemonkey MacOS

Working in Delphi Firemonkey for Mac OS64.
Trying to read and then set the variable Apple calls the "paperName", which is the paper type (letter, legal, envelope, etc.) I know that it is accessed through NSPrinter.PaperName? but I do not understand how to code FMX to access it.
I'm using cookbooked code to get the paper rectangle:
FPrintInfo := TNSPrintInfo.Wrap(TNSPrintInfo.OCClass.sharedPrintInfo);
FPrintInfo.retain;
PMGetAdjustedPaperRect(FPrintInfo.PMPageFormat, #PaperRect);
FPrintInfo.release;
but I'm not experienced at all with Mac code so my attempts to plug-and-play off of this code to get papername have not been successful.
Thanks for your help.
Dave,
Thanks. Sorry, I didn't really give you enough info. The code I provided does work, to get the paper rectangle.
What I am trying to get, in addition, is the paper name, and I can't figure out what function will get me that.
I'm trying to use PMGetPageFormatPaper(FPrintInfo.PMPageFormat, #PaperTypeS); but I think I may not be declaring PaperTypeS correctly.
What I'm trying is:
function getPaperShape: string;
var
FPrintInfo: NSPrintInfo;
PaperRect: PMRect;
paperwidth,paperheight:double;
paperTypeS:string;
begin
FPrintInfo := TNSPrintInfo.Wrap(TNSPrintInfo.OCClass.sharedPrintInfo);
FPrintInfo.retain;
PMGetAdjustedPaperRect(FPrintInfo.PMPageFormat, #PaperRect);
PMGetPageFormatPaper(FPrintInfo.PMPageFormat, #PaperTypeS);
FPrintInfo.release;
paperwidth:= PaperRect.right-PaperRect.left;
paperheight:= PaperRect.bottom-PaperRect.top;
end;
That clearly is not correct, since I get nothing returned in paperTypeS. I've tried declaring paperTypeS as NSPrinter.PaperName, or just as PaperName, or as PMPaperName, but clearly I'm just guessing here and none of those are recognized by FMX as valid types.
Does that make more sense?
Again, thanks.
Scott

XCTest self measureBlock modification?

It appears that XCtest "self measureBlock" is limited to milliseconds and 10 runs of the test code. Are there any ways to modify the behavior of measureBlock for more runs and/or nano or microsecond accuracy?
TL;DR
Apple provides a way to modify the behavior of measureBlock: by providing extra string constants but they don't support any string constants other than the default.
Long explanation
measureBlock calls the following function
- (void)measureMetrics:(NSArray *)metrics automaticallyStartMeasuring:(BOOL)automaticallyStartMeasuring withBlock:(void (^)(void))block;
//The implementation looks something like this (I can't say 100% but i'm pretty sure):
- (void)measureBlock:(void (^)(void))block {
NSArray<NSString *> *metrics = [[self class] defaultPerformanceMetrics];
[self measureMetrics:metrics automaticallyStartMeasure:YES withBlock:block];
}
defaultPerformanceMetrics is a class function that returns an array of strings.
From the Xcode source
"Subclasses can override this to change the behavior of
-measureBlock:"
Lovely, that sounds promising; we have customization behavior right? Well, they don't give you any strings to return. The default is XCTPerformanceMetric_WallClockTime ("com.apple.XCTPerformanceMetric_WallClockTime")
It turns out there aren't any string constants to return besides that one.
See the slides for WWDC 2014 Session 414 Testing in Xcode 6 (link).
I quote from page 158:
Currently supports one metric: XCTPerformanceMetric_WallClockTime
Nothing else has been added in Xcode 7 so it seems you're out of luck trying to modify measureBlock, sorry.
I've never found measureBlock: very useful. Check out Tidbits.xcodeproj/TidbitsTestBase/TBTestHelpers/comparePerformance https://github.com/tipbit/tidbits if you'd like to look at an alternative.

Using termios in Swift

Now that we've reached Swift 2.0, I've decided to convert my, as yet unfinished, OS X app to Swift. Making progress but I've run into some issues with using termios and could use some clarification and advice.
The termios struct is treated as a struct in Swift, no surprise there, but what is surprising is that the array of control characters in the struct is now a tuple. I was expecting it to just be an array. As you might imagine it took me a while to figure this out. Working in a Playground if I do:
var settings:termios = termios()
print(settings)
then I get the correct details printed for the struct.
In Obj-C to set the control characters you would use, say,
cfmakeraw(&settings);
settings.c_cc[VMIN] = 1;
where VMIN is a #define equal to 16 in termios.h. In Swift I have to do
cfmakeraw(&settings)
settings.c_cc.16 = 1
which works, but is a bit more opaque. I would prefer to use something along the lines of
settings.c_cc.vim = 1
instead, but can't seem to find any documentation describing the Swift "version" of termios. Does anyone know if the tuple has pre-assigned names for it's elements, or if not, is there a way to assign names after the fact? Should I just create my own tuple with named elements and then assign it to settings.c_cc?
Interestingly, despite the fact that pre-processor directives are not supposed to work in Swift, if I do
print(VMIN)
print(VTIME)
then the correct values are printed and no compiler errors are produced. I'd be interested in any clarification or comments on that. Is it a bug?
The remaining issues have to do with further configuration of the termios.
The definition of cfsetspeed is given as
func cfsetspeed(_: UnsafeMutablePointer<termios>, _: speed_t) -> Int32
and speed_t is typedef'ed as an unsigned long. In Obj-C we'd do
cfsetspeed(&settings, B38400);
but since B38400 is a #define in termios.h we can no longer do that. Has Apple set up replacement global constants for things like this in Swift, and if so, can anyone tell me where they are documented. The alternative seems to be to just plug in the raw values and lose readability, or to create my own versions of the constants previously defined in termios.h. I'm happy to go that route if there isn't a better choice.
Let's start with your second problem, which is easier to solve.
B38400 is available in Swift, it just has the wrong type.
So you have to convert it explicitly:
var settings = termios()
cfsetspeed(&settings, speed_t(B38400))
Your first problem has no "nice" solution that I know of.
Fixed sized arrays are imported to Swift as tuples, and – as far as I know – you cannot address a tuple element with a variable.
However,Swift preserves the memory layout of structures imported from C, as
confirmed by Apple engineer Joe Groff:. Therefore you can take the address of the tuple and “rebind” it to a pointer to the element type:
var settings = termios()
withUnsafeMutablePointer(to: &settings.c_cc) { (tuplePtr) -> Void in
tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: settings.c_cc)) {
$0[Int(VMIN)] = 1
}
}
(Code updated for Swift 4+.)

How to force a raw value of 7 into a UIViewAnimationCurve enum?

The key UIKeyboardAnimationCurveUserInfoKey in the userInfo dictionary of a UIKeyboardWillShowNotification contains an Int with the value 7.
Now I need to pass this Int into UIView.setAnimationCurve(<here>). I tried to create the required UIViewAnimationCurve enum like this UIViewAnimationCurve(rawValue: 7). Because the raw value 7 is undocumented, the result is always nil.
It works fine this way in Objective-C. Any idea how to get this animation curve from the notification into a UIView animation using Swift?
Update:
As pointed out by Martin, this is no longer a problem since Xcode 6.3.
From the Xcode 6.3 Release Notes:
Imported NS_ENUM types with undocumented values, such as UIViewAnimationCurve, can now be converted from their raw integer values using the init(rawValue:) initializer without being reset to nil. Code that used unsafeBitCast as a workaround for this issue can be written to use the raw value initializer.
I think I figured it out, but I'm not sure if this is the way it's supposed to be done.
let animationCurve = unsafeBitCast(7, UIViewAnimationCurve.self)
UIView.setAnimationCurve(animationCurve)
Update: The solution contained in this question works as well.
var animationCurve = UIViewAnimationCurve.EaseInOut
NSNumber(integer: 7).getValue(&animationCurve)

Resources