Applescript-objc - accessing class properties - applescript-objc

If I have a class BFLocation and I pass an array of those objects into my applescript-objc, how do I access the class properties?
BFLocation.h
#property NSString *url;
BFManager.h
#import "BFLocation.h"
#interface script : NSObject
- (void)processLocations:(NSArray *)locations;
#end
BFManager.applescript
script BFManager
property parent : class "NSObject"
on processLocations_(locations)
repeat with location in locations
log location's url
end repeat
end processLocations
I get
<NSAppleEventDescriptor: 'obj '{ 'form':'prop', 'want':'prop', 'seld':'url ', 'from':'obj '{ 'form':'ID ', 'want':'ocid', 'seld':'optr'($C0FF060080610000$), 'from':null() } }>
Do I need to cast location so it knows it's a BFLocation object? Why am I getting an NSAppleEventDescriptor instead of the expected string?

Did not have the syntax correct, should be
location's |url|()

Related

Can I name a type in Crystal for convenience?

In my new crystal project, I have a class which is storing its data in a couple of different ways that are useful to me later, both as hashes.
getter isometry_cardinality : Hash(IsometryKind, Int8)
getter axis_cardinality : Hash(Directions::Orientation, Array(IsometryKind))
I'd like to overload my methods now based on which hash its using:
private def has_min_cardinality?(parent_cardinality : Hash(IsometryKind, Int8))
...
end
private def has_min_cardinality?(parent_cardinality : Hash(Directions::Orientation, Array(IsometryKind))
...
end
as you can see, that declaration is getting pretty long. Is there some convenient way to shorten it? For example, can I use the getter as an alias for its type?
private def has_min_cardinality?(parent_cardinality : isometry_cardinality)
...
end
private def has_min_cardinality?(parent_cardinality : axis_cardinality)
...
end
The answer is 'no' to that specific example, so my question is: am I missing the right way to do this?
Yes, there is a better way: alias to the rescue!
You can alias complex types like in this example and use the alias, the compiler just replaces it outright so there's no performance penalty.
alias IsometryCardinality = Hash(IsometryKind, Int8)
alias AxisCardinality = Hash(Directions::Orientation, Array(IsometryKind))
getter isometry_cardinality : IsometryCardinality
getter axis_cardinality : AxisCardinality
...
private def has_min_cardinality?(parent_cardinality : IsometryCardinality)
...
end
private def has_min_cardinality?(parent_cardinality : AxisCardinality)
...
end
Here's a demo: https://play.crystal-lang.org/#/r/4hoh

Is there any way to convert JSON to model easier in C++?

I have a JSON string that I need to map into a Model in C++. My current practice is define data type of the variable and get the value of JSON via key then assign to model one by one. Here is the code:
auto code = BaseModel::intValue(data, "code");
int BaseModel::intValue( const std::unordered_map<std::string, Value>& value, const std::string& key )
{
return (value.find( key ) != value.end() && BaseModel::isBasicType(value.at(key))) ? value.at(key).asInt() : 0;
}
Is there any easy way to convert JSON to model? Maybe I just need define a header file with the model‘s data type, then it can help me convert JSON to model object.Instead of creating a model object, assign value to the model object from JSON one by one. I know there is a way in Objective-C:
// JSON:
{
"uid":123456,
"name":"Harry",
"created":"1965-07-31T00:00:00+0000"
}
// Model:
#interface User : NSObject
#property UInt64 uid;
#property NSString *name;
#property NSDate *created;
#end
#implementation User
#end
// Convert json to model:
User *user = [User yy_modelWithJSON:json];
// Convert model to json:
NSDictionary *json = [user yy_modelToJSONObject];
I've had great success with the Nlohmann Json library, which allows you to define a single set of serialization and deserialization functions, and then freely convert from your chosen structure to json and back.

Swift 3.0 : Ambiguous reference to member 'Subscript' issue

I have got an unusual problem in swift 2.3 to Swift 3.0. Once I convert the code from 2.3 to 3.0, i am getting this issue:'Ambiguous reference to member 'Subscript',
Code are :
dynamic func onDataNotification(notification: NSNotification) {
var data = notification.userInfo as! Dictionary<NSString, ARoutedMessage>
if let packet = data[AEnginePacketDataKey] as? AEngineMessage,
currentDevice = self.currentDevice() {
if packet.messageId == MessageId.message && currentDevice.isDevice() {
// Some code
}
}
}
Getting error on let packet = data[AEnginePacketDataKey] as Ambiguous reference to member 'Subscript', I don't understand why?. Other:
// String
extern NSString *AEnginePacketDataKey;
//ARoutedMessage Class
#interface ARoutedMessage : NSObject
#property NSMutableArray *payloadParameters;
#end
//AEngineMessage Class
#interface AEngineMessage : ARoutedMessage
#property (readonly)MessageId messageId;
- (id) initWithMessageId:(MessageId) mId;
#end
Please help me out.
The "ambiguous reference" error is telling you that the variable you're trying to use as a subscript is the wrong type.
In this case data is a dictionary that is expecting an NSString subscript. It looks like AEnginePacketDataKey is defined as a pointer to an NSString in your Objective C code, but you don't show where (if) anything is assigned to it. Make sure you assign an actual NSString to it before you try to use it as a subscript of data.

Complex class hierarchies in Objective-C++

Consider the following base classes:
#interface ViewBase : UIView
#property (readonly) LayerBase *myLayer;
+ (Class)myLayerClass; // _myLayer = [[[self class] myLayerClass] new];
#end
#interface LayerBase : CALayer
#property AbstractGrid *grid;
#end
class AbstractGrid
{
public:
int rows, columns;
virtual someMethod() = 0;
}
I have a template Grid class that uses different cell types (AbstractGrid is needed because it's not possible to create template Objective-C classes):
template <class Cell>
class Grid : public AbstractGrid
{
public:
Cell **cells;
virtual someMethod() {}
}
Now I want to create a subclass of ViewBase that has type of myLayer also subclass of LayerBase (the +myLayerClass method is also redefined) and use different template parameter for the model class, for example:
#interface AView : ViewBase
#property (readonly) ALayer *myLayer;
#end
#interface ALayer : LayerBase
#property Grid<GridCell> *grid;
#end
class GridCell
{
public:
int row, column;
}
The application works fine with this approach, but compiler gives me warnings about incompatible property types:
property type 'ALayer *' is incompatible with type 'LayerBase *' inherited from 'ViewBase'
property type 'Grid *' is incompatible with type 'AbstractGrid *' inherited from 'LayerBase'
While I can silence the first warning by declaring layer property with type id (which isn't the best solution as I can't use dot syntax without type casting, and I may make mistakes which compiler won't be able to catch):
#property (readonly) id myLayer;
I can't do the same with C++ type. Declaring the grid property as void * also doesn't help.
So is there a proper way to handle such situation? Or I should simply silence the warnings using pragmas since I know what I'm doing?
Please refrain from advising not to use C++ classes because it's not an option (I'm creating a set of cross-platform model classes to ease porting in future).
Yes. Don't alter the return type. For example:
#interface LayerBase : CALayer
- (AbstractGrid *)grid;
#end
#interface ALayer : LayerBase
// ALayer's local storage and typed interface:
#property Grid<GridCell>* grid_GridCell; // << use unique selector names
// ALayer's abstract interface/overrides:
- (AbstractGrid *)grid; // << returns self.grid_GridCell
#end
Well, I decided to remove the grid #property (since I don't need any property features like KVO in this case) in favor of good old getter/setter and simply cast return type in subclasses. clang is clever enough to allow dot syntax for arbitrary getters, so now I'm getting no warnings.
#interface LayerBase : CALayer {
AbstractGrid *_grid;
}
- (AbstractGrid *)grid;
- (void)setGrid:(AbstractGrid *)grid;
#end
#implementation LayerBase
- (AbstractGrid *)grid {
return _grid;
}
- (void)setGrid:(AbstractGrid *)grid {
_grid = grid;
}
#end
#interface ALayer : LayerBase
- (Grid<GridCell> *)grid;
#end
#implementation ALayer
- (Grid<GridCell> *)grid {
return (Grid<GridCell> *)[super grid];
}
#end

Add a css class for Ajax Action link

How I can add a class for Ajax.ActionLink?
#Ajax.ActionLink("Remove this photo","RemovePhoto","Admin",new{Id=Model.filename, #class="ActionClass"},new AjaxOptions{OnSuccess = "RemoveSuccess"})
but this method don't create css class for this ActionLink.
My class is added to the url:
AdminTools/RemovePhoto/ffff.JPG?class=RemovePhoto
You can use the (AjaxHelper, String, String, Object, AjaxOptions, Object) method signature for this.
public static MvcHtmlString ActionLink(
this AjaxHelper ajaxHelper,
string linkText,
string actionName,
Object routeValues,
AjaxOptions ajaxOptions,
Object htmlAttributes
)
As you can see, the final parameter is a collection of HTML attributes.
Source: http://msdn.microsoft.com/en-us/library/dd470546.aspx
Should be use like this:
#Ajax.ActionLink("Remove this photo","RemovePhoto","Admin",new{Id=Model.filename },new AjaxOptions{OnSuccess = "RemoveSuccess"} , new {#class="Action Class"})