Date   

Re: Abstracting a group of commonly named Selectors

Jeff Laing
 

In the designated initialise of your Parser class, you can use class_addMethod to add whatever you like to your instance's class.

https://developer.apple.com/documentation/objectivec/1418901-class_addmethod?language=objc

The method implementation gets called with the selector as its second argument and you can cut the string up at runtime to then call your Parse. Here's a snippet from an app I did in the past that wanted to dynamically adjust to any entries that were added to a popup menu in Interface Builder. It iterates over the popup, and for every entry present, looks for then adds a dynamic method called _popup.

        IMP popup_imp = class_getMethodImplementation([self class], @selector(_popup00:));
...
        for (NSArray *item in popup) {
                // make sure that we implement the required method
                SEL sel = NSSelectorFromString([NSString stringWithFormat:@"_popup%02ld:",(long)[menuItems count]]);
                if (![self respondsToSelector:sel]) {
                        class_addMethod([self class], sel, popup_imp, "v@:@");  // -(void)method:(id)argument;
                }

The implementation of the method gets the name of the selector using set_getName, then punts across to the actual code.

- (void)_popup00:(id)sender {
//          01234567
        const char *name = sel_getName(_cmd);
        const int idx = atoi(name+6);
        id resp = [self.popupResponders objectAtIndex:idx];
        [resp callWithArrayOfArgs:self.popupArguments];
}

Extracting your specific token from the message is just name+. This example is using (void) but it should work just fine - you aren't using the "no such method" path, you are just binding the method really late in the compile/link/run process...


Re: Abstracting a group of commonly named Selectors

Sandor Szatmari
 

Jeff,

On Jul 20, 2020, at 17:14, Jeff Laing <jefflaing@...> wrote:



You really haven't provided enough information about the caller, and you've skipped over the C programmers favourite answer. Presumably you actually NEED all those seperate selectors and can't just change the caller to call a common handler. Second, what's wrong with:

#define IMPLEMENT(m) -(mytype)parse##m { return [self parse:m]; }
IMPLEMENT(XYZ)
IMPLEMENT(ABC)

Thanks for the idea… it might be a good choice… as for additional details.

The caller can be seen as a controller.  It dynamically allocates model (parser) classes based on context.  

The model classes define the -parse### that are available by implementing a protocol (for consistency).  So, all of these selectors are already accessible in an array of dictionaries returned by the model.

The controller then asks the model for it’s available parsers and the iterates over them -invoking each one, collects a cumulative Status, and provides an overall result.

So, the selectors are already defined In this array, then I have to implement each one as a method which is one line: red two nested calls, with a constant.  So, 99% the same, save the context (constant) of which parse method is being invoked.  Historically these methods were not one line.  But parsing newer data formats (XML) leaves less individualized code in each parse method.

Now, I can’t change this design, there’s no justifiable gains from that.  I do have the opportunity to rethink how the components of this design are stitched together for this new model, and would like less unnecessarily redundant code, if the cost of achieving this is not too great.

I hope these additional details are helpful…

Thanks,
Sandor


Re: Abstracting a group of commonly named Selectors

Jeff Laing
 

You really haven't provided enough information about the caller, and you've skipped over the C programmers favourite answer. Presumably you actually NEED all those seperate selectors and can't just change the caller to call a common handler. Second, what's wrong with:

#define IMPLEMENT(m) -(mytype)parse##m { return [self parse:m]; }
IMPLEMENT(XYZ)
IMPLEMENT(ABC)


Re: Abstracting a group of commonly named Selectors

Sandor Szatmari
 

Gary, 

On Jul 20, 2020, at 15:53, Gary L. Wade <garywade@...> wrote:

You might want to consider using valueForUndefinedKey:

interesting… 

and parse it to know which value you care about, and then return the value through NSValue, which can encapsulate any value, although a number/enum mapping might be sufficient.

I’ll have to see if Returning an NSValue wrapped scalar translates to the scalar result on the other side when I call -getReturnValue: 

Thanks!

Sandor


On Jul 20, 2020, at 12:47 PM, Sandor Szatmari <admin.szatmari.net@...> wrote:

Alex,

Thanks for the idea.  I not sure how that helps me get the return value back to the original caller.   Am I missing your point?

Here’s more details, in pseudo code

// Controller class
SEL aSel
do

aSel = lookUpSel (i.e. parseXYZ)
NSInvocation *n = // make invocation with aSel
[n setTarget: ModelClass]
[n invoke]
Status s = success // I’m an optimist
[n getReturnValue:&s]

while more_sels

… Meanwhile…

// ModelClass
-(Status)parseXYZ
{
 // do the same thing for each parse method
 return [self parse:XYZ]
}

-(Status)parseRST
{
 // do the same thing for each parse method
 return [self parse:RST]
}

————

I want to change model class to do this
// remove parse SELs  i.e. remove parse[A-Z]{3} methods

// replace with something like
-doesNotRespondToSelector:(SEL)aSel
{
 NSString *sel = NSStringFromSelector(aSel)

 if ( sel has prefix ‘parse’ )
 {
   NSString *selCmd = [sel subStringFromIndex:5] // remove prefix ‘parse’. e.g.  ‘RST’ remains
   Status s = [self parse:selCmd]

   // how do I return ‘s’ to the original caller??? The Controller

 }
 else
   [super doesNotRespondToSelector:aSel]
}


Sandor

On Jul 20, 2020, at 13:27, Alex Zavatone via groups.io <zav@...> wrote:

Would it be possible to put them in an array or dictionary as NSStrings and use performSelector on one of them if it is present within the array or dict?

On Jul 20, 2020, at 12:11 PM, Sandor Szatmari <admin.szatmari.net@...> wrote:

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface.  It should not be necessary, I hope.

I would like to abstract them using something like:
 -doesNotRecognizeSelector:
 or
 -forwardInvocation:
 or
 By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow.  Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor


Re: Abstracting a group of commonly named Selectors

Sandor Szatmari
 

Alex,

On Jul 20, 2020, at 15:51, Alex Zavatone via groups.io <zav=mac.com@groups.io> wrote:

Well, I’m guessing here, but can’t you construct the method and use a perform selector, get the result and return it?
I am proposing letting the runtime handle the fact the object does not respond to the selector. So, under this assumption I am inside one of two methods:

-doesNotRespondToSelector: or -forwardInvocation:

Both of which have a void return. So I don’t see how I can return data to the original caller… I’m not sure there’s a way to do it, but was hoping to be unaware of how to use these methods, or an alternate means of generically responding to selectors.


It seems like you are making methods, performing them, then need to perform methods within that, right? Can’t you simplify that?
Unfortunately, this is code (The controller) at the heart of a framework and many classes depend on it. I can’t justify changing that code. But I can consider writing a new model (one with lot’s of redundant selectors) in an new way.

Thanks for your ideas!

Sandor

Or somehow define what becomes parsed in the method?

It seems like this can be simplified.

On Jul 20, 2020, at 2:47 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

Alex,

Thanks for the idea. I not sure how that helps me get the return value back to the original caller. Am I missing your point?

Here’s more details, in pseudo code

// Controller class
SEL aSel
do

aSel = lookUpSel (i.e. parseXYZ)
NSInvocation *n = // make invocation with aSel
[n setTarget: ModelClass]
[n invoke]
Status s = success // I’m an optimist
[n getReturnValue:&s]

while more_sels

… Meanwhile…

// ModelClass
-(Status)parseXYZ
{
// do the same thing for each parse method
return [self parse:XYZ]
}

-(Status)parseRST
{
// do the same thing for each parse method
return [self parse:RST]
}

————

I want to change model class to do this
// remove parse SELs i.e. remove parse[A-Z]{3} methods

// replace with something like
-doesNotRespondToSelector:(SEL)aSel
{
NSString *sel = NSStringFromSelector(aSel)

if ( sel has prefix ‘parse’ )
{
NSString *selCmd = [sel subStringFromIndex:5] // remove prefix ‘parse’. e.g. ‘RST’ remains
Status s = [self parse:selCmd]

// how do I return ‘s’ to the original caller??? The Controller

}
else
[super doesNotRespondToSelector:aSel]
}


Sandor

On Jul 20, 2020, at 13:27, Alex Zavatone via groups.io <zav=mac.com@groups.io> wrote:
Would it be possible to put them in an array or dictionary as NSStrings and use performSelector on one of them if it is present within the array or dict?

On Jul 20, 2020, at 12:11 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface. It should not be necessary, I hope.

I would like to abstract them using something like:
-doesNotRecognizeSelector:
or
-forwardInvocation:
or
By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow. Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor







Re: Abstracting a group of commonly named Selectors

Gary L. Wade
 

You might want to consider using valueForUndefinedKey: and parse it to know which value you care about, and then return the value through NSValue, which can encapsulate any value, although a number/enum mapping might be sufficient.

On Jul 20, 2020, at 12:47 PM, Sandor Szatmari <admin.szatmari.net@...> wrote:

Alex,

Thanks for the idea.  I not sure how that helps me get the return value back to the original caller.   Am I missing your point?

Here’s more details, in pseudo code

// Controller class
SEL aSel
do

aSel = lookUpSel (i.e. parseXYZ)
NSInvocation *n = // make invocation with aSel
[n setTarget: ModelClass]
[n invoke]
Status s = success // I’m an optimist
[n getReturnValue:&s]

while more_sels

… Meanwhile…

// ModelClass
-(Status)parseXYZ
{
 // do the same thing for each parse method
 return [self parse:XYZ]
}

-(Status)parseRST
{
 // do the same thing for each parse method
 return [self parse:RST]
}

————

I want to change model class to do this
// remove parse SELs  i.e. remove parse[A-Z]{3} methods

// replace with something like
-doesNotRespondToSelector:(SEL)aSel
{
 NSString *sel = NSStringFromSelector(aSel)

 if ( sel has prefix ‘parse’ )
 {
   NSString *selCmd = [sel subStringFromIndex:5] // remove prefix ‘parse’. e.g.  ‘RST’ remains
   Status s = [self parse:selCmd]

   // how do I return ‘s’ to the original caller??? The Controller

 }
 else
   [super doesNotRespondToSelector:aSel]
}


Sandor

On Jul 20, 2020, at 13:27, Alex Zavatone via groups.io <zav@...> wrote:

Would it be possible to put them in an array or dictionary as NSStrings and use performSelector on one of them if it is present within the array or dict?

On Jul 20, 2020, at 12:11 PM, Sandor Szatmari <admin.szatmari.net@...> wrote:

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface.  It should not be necessary, I hope.

I would like to abstract them using something like:
 -doesNotRecognizeSelector:
 or
 -forwardInvocation:
 or
 By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow.  Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor


Re: Abstracting a group of commonly named Selectors

Alex Zavatone
 

Well, I’m guessing here, but can’t you construct the method and use a perform selector, get the result and return it?

It seems like you are making methods, performing them, then need to perform methods within that, right? Can’t you simplify that? Or somehow define what becomes parsed in the method?

It seems like this can be simplified.

On Jul 20, 2020, at 2:47 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

Alex,

Thanks for the idea. I not sure how that helps me get the return value back to the original caller. Am I missing your point?

Here’s more details, in pseudo code

// Controller class
SEL aSel
do

aSel = lookUpSel (i.e. parseXYZ)
NSInvocation *n = // make invocation with aSel
[n setTarget: ModelClass]
[n invoke]
Status s = success // I’m an optimist
[n getReturnValue:&s]

while more_sels

… Meanwhile…

// ModelClass
-(Status)parseXYZ
{
// do the same thing for each parse method
return [self parse:XYZ]
}

-(Status)parseRST
{
// do the same thing for each parse method
return [self parse:RST]
}

————

I want to change model class to do this
// remove parse SELs i.e. remove parse[A-Z]{3} methods

// replace with something like
-doesNotRespondToSelector:(SEL)aSel
{
NSString *sel = NSStringFromSelector(aSel)

if ( sel has prefix ‘parse’ )
{
NSString *selCmd = [sel subStringFromIndex:5] // remove prefix ‘parse’. e.g. ‘RST’ remains
Status s = [self parse:selCmd]

// how do I return ‘s’ to the original caller??? The Controller

}
else
[super doesNotRespondToSelector:aSel]
}


Sandor

On Jul 20, 2020, at 13:27, Alex Zavatone via groups.io <zav=mac.com@groups.io> wrote:

Would it be possible to put them in an array or dictionary as NSStrings and use performSelector on one of them if it is present within the array or dict?

On Jul 20, 2020, at 12:11 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface. It should not be necessary, I hope.

I would like to abstract them using something like:
-doesNotRecognizeSelector:
or
-forwardInvocation:
or
By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow. Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor





Re: Abstracting a group of commonly named Selectors

Sandor Szatmari
 

Alex,

Thanks for the idea. I not sure how that helps me get the return value back to the original caller. Am I missing your point?

Here’s more details, in pseudo code

// Controller class
SEL aSel
do

aSel = lookUpSel (i.e. parseXYZ)
NSInvocation *n = // make invocation with aSel
[n setTarget: ModelClass]
[n invoke]
Status s = success // I’m an optimist
[n getReturnValue:&s]

while more_sels

… Meanwhile…

// ModelClass
-(Status)parseXYZ
{
// do the same thing for each parse method
return [self parse:XYZ]
}

-(Status)parseRST
{
// do the same thing for each parse method
return [self parse:RST]
}

————

I want to change model class to do this
// remove parse SELs i.e. remove parse[A-Z]{3} methods

// replace with something like
-doesNotRespondToSelector:(SEL)aSel
{
NSString *sel = NSStringFromSelector(aSel)

if ( sel has prefix ‘parse’ )
{
NSString *selCmd = [sel subStringFromIndex:5] // remove prefix ‘parse’. e.g. ‘RST’ remains
Status s = [self parse:selCmd]

// how do I return ‘s’ to the original caller??? The Controller

}
else
[super doesNotRespondToSelector:aSel]
}


Sandor

On Jul 20, 2020, at 13:27, Alex Zavatone via groups.io <zav=mac.com@groups.io> wrote:

Would it be possible to put them in an array or dictionary as NSStrings and use performSelector on one of them if it is present within the array or dict?

On Jul 20, 2020, at 12:11 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface. It should not be necessary, I hope.

I would like to abstract them using something like:
-doesNotRecognizeSelector:
or
-forwardInvocation:
or
By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow. Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor




Re: Abstracting a group of commonly named Selectors

Alex Zavatone
 

Would it be possible to put them in an array or dictionary as NSStrings and use performSelector on one of them if it is present within the array or dict?

On Jul 20, 2020, at 12:11 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface. It should not be necessary, I hope.

I would like to abstract them using something like:
-doesNotRecognizeSelector:
or
-forwardInvocation:
or
By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow. Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor


Abstracting a group of commonly named Selectors

Sandor Szatmari
 

I have a certain group of selectors that all follow a strict naming convention,

-(Status)parseXYZ
-(Status)parseRST

All have one line that does the same thing and return a scalar (enum) as a result.
Each method would do something XYZ or RST and return their status

There are about 200 of these… it’s quite annoying to maintain and look at this boiler plate interface. It should not be necessary, I hope.

I would like to abstract them using something like:
-doesNotRecognizeSelector:
or
-forwardInvocation:
or
By some other means, which I cannot conceive of…

The issue I don’t understand is, how would I return the scalar to the original caller once one of the methods has received the program flow. Neither of these methods return anything.

Is what I want to do possible?
If so, what should I be looking at?

Sandor


Re: UndoManager setActionNames

Graham Cox
 

The action name is part of the “view” layer in model-controller-view architecture. But most of the actual undoable ’stuff’ is in the model.

So I usually set the action name at the top level action method that responds to the original command, even if that burrows down and changes a bunch of stuff in the model. That works fine, because the Undo Manager itself keeps the same action name across undo/redo actions even if it doesn’t directly invoke the original action method for redo. This works fine as long as your model doesn’t also try messing with the action name - just keep that in the view layer.

—Graham

On 5 Jul 2020, at 5:07 pm, Arved von Brasch via Cocoa-dev <cocoa-dev@lists.apple.com> wrote:

Hi list,

Where’s the best place to intercept undo/redo actions to edit the action name (’setActionName()’) for the UndoManager in a CoreData application? In particular, when a particular entity’s attribute's change. Obviously, I want to do this so that when the user edits something, the menu name is more descriptive than just “Undo”/“Redo”.

Easiest, in terms of implementation, seems to be in the NSManagedObject subclass by means of an observer on the attribute. However, conceptually, it would make more sense to handle it in the NSArrayController or, maybe the NSTableView or other NSView object where the attribute is edited directly.

Just wondering where others have settled for best practice.

Kind regards,
Arved
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/graham.cox%40bigpond.com

This email sent to graham.cox@bigpond.com


Re: Redrawing a view during a dragging session [SOLVED]

Graham Cox
 

As usual, the answer was staring me in the face.

The old code was synchronous, the new is asynchronous.

I was restoring the view after the call to -dragImage… because that used to keep control until the drag finished. But the replacement returns immediately, so restoring the view just undoes the hiding step, and with it not hidden, the stack animation has no “gap” to work with.

A small re-arrangement of where the clean-up of the drag is done restores full working visuals (and my sanity!).

Sory for the noise - but if anyone else has a similar issue, this might be of some help.

—Graham

On 3 Jul 2020, at 4:11 pm, Graham Cox <graham@mapdiva.com> wrote:

Hi all,

I’m updating some legacy code that currently uses the ‘classic’ way to drag stuff, namely

[NSView dragImage:at:offset:event:pasteboard:source:slideBack:];

This code has been deprecated forever (10.7+ anyway), so it’s about time it was updated to the modern dragging session API. However, the old code still works perfectly and has served faithfully for years.

The dragging session is created OK, and the dragging image drags as a semi-transparent image, so the drag is taking place alright. I can also see that the dragging destination methods are called as they should be.

The problem is that the source view needs to update while the drag is going on. The view is actually a stack of subviews, and the thing being dragged is one of them, to re-arrange the order of the views. So the first thing is that the view being dragged is hidden. This opens up a gap in the stack. As the drag proceeds, the remaining views animate their position to open up a gap where the view can be dropped.

In the old code, works great.

In the new code, nothing I do allows the view’s visual appearance to be updated during the drag. The view being dragged doesn’t hide (its ‘hidden’ state becomes YES, but it still shows), and the animation doesn’t happen, though once again the code that handles that is being called as expected. That calls -setAnimatedFrame: to reposition the other views to make space, but though its being called with sensible values, nothing actually gets drawn or redrawn.

It’s as if the run loop is suspended during the dragging session, so window updates are not processed. I’m not sure what to check to verify that guess.

SUrely normal updates should be allowed during a drag? How can the old code (that freely handles updates) be replaced if the new one doesn’t work the same way?

Anyone run into this problem, or knows what I should do here?

—Graham







Redrawing a view during a dragging session

Graham Cox
 

Hi all,

I’m updating some legacy code that currently uses the ‘classic’ way to drag stuff, namely

[NSView dragImage:at:offset:event:pasteboard:source:slideBack:];

This code has been deprecated forever (10.7+ anyway), so it’s about time it was updated to the modern dragging session API. However, the old code still works perfectly and has served faithfully for years.

The dragging session is created OK, and the dragging image drags as a semi-transparent image, so the drag is taking place alright. I can also see that the dragging destination methods are called as they should be.

The problem is that the source view needs to update while the drag is going on. The view is actually a stack of subviews, and the thing being dragged is one of them, to re-arrange the order of the views. So the first thing is that the view being dragged is hidden. This opens up a gap in the stack. As the drag proceeds, the remaining views animate their position to open up a gap where the view can be dropped.

In the old code, works great.

In the new code, nothing I do allows the view’s visual appearance to be updated during the drag. The view being dragged doesn’t hide (its ‘hidden’ state becomes YES, but it still shows), and the animation doesn’t happen, though once again the code that handles that is being called as expected. That calls -setAnimatedFrame: to reposition the other views to make space, but though its being called with sensible values, nothing actually gets drawn or redrawn.

It’s as if the run loop is suspended during the dragging session, so window updates are not processed. I’m not sure what to check to verify that guess.

SUrely normal updates should be allowed during a drag? How can the old code (that freely handles updates) be replaced if the new one doesn’t work the same way?

Anyone run into this problem, or knows what I should do here?

—Graham


Re: Determining CGContext type at runtime

Graham Cox
 

Thanks — it is a bit kludgey, but might do in a pinch, as you say.

In some cases I can set a flag on my drawing to tell it that the context should be a PDF at that time, since I am responsible for setting up that context in the first place — but at other times (such as printing), I may not get the chance. But I will explore the issue further and see if anything else comes to mind.

cheers, Graham






On 21 Jun 2020, at 5:28 am, Steve Christensen via groups.io <punster@...> wrote:

I played around with it and found that bitmap (easy to create) and PDF contexts have the same CFTypeID so no help there, and that there doesn’t appear to be a public context [sub-]type property. One thing I noticed in  run logging was that the context type is available in the description string, so if you’d like a fragile solution then you might do something like this. I’m not advocating for it, but if in a weak moment desperation overwhelms you...

NSString* pdfDescription = [[NSString alloc] initWithFormat:@"%@", pdfContext];
NSString* bitmapDescription = [[NSString alloc] initWithFormat:@"%@", bitmapContext];

NSLog(@"pdf = %@, isPDF = %@", pdfDescription, [pdfDescription containsString:@"PDF"] ? @"YES" : @"NO");
NSLog(@"bitmap = %@, isPDF = %@", bitmapDescription, [bitmapDescription containsString:@"PDF"] ? @"YES" : @"NO");


pdf = <CGContext 0x600001ae0840> (kCGContextTypePDF), isPDF = YES

bitmap = <CGContext 0x600001ae0b40> (kCGContextTypeBitmap)
<<CGColorSpace 0x600000be0c60> (kCGColorSpaceDeviceRGB)>
width = 100, height = 100, bpc = 8, bpp = 32, row bytes = 416 
kCGImageAlphaPremultipliedFirst | 0 (default byte order) | kCGImagePixelFormatPacked (default) , isPDF = NO



On Jun 19, 2020, at 10:23 PM, Graham Cox <graham@...> wrote:

I need to determine whether I am drawing into a CGPDFContext or a different context at runtime.

In AppKit, I can use [NSGraphicsContext currentContextDrawingToScreen], but this is code that is passed a CGContextRef only, so that higher-level API isn’t appropriate. CGPDFContext doesn’t appear to have an associated CGPDFContextGetTypeID() function to compare with the result of CFGetTypeID(), so it’s unclear how I can do this.

The reason I need to so this is that objects I am drawing can have different states according to whether they are selected in the UI or not, but when capturing the drawing into a PDF, the selection state needs to be ignored, so the drawing code needs to be able to detect what context type is so that it can do this.

—Graham



Re: Determining CGContext type at runtime

Steve Christensen
 

I played around with it and found that bitmap (easy to create) and PDF contexts have the same CFTypeID so no help there, and that there doesn’t appear to be a public context [sub-]type property. One thing I noticed in  run logging was that the context type is available in the description string, so if you’d like a fragile solution then you might do something like this. I’m not advocating for it, but if in a weak moment desperation overwhelms you...

NSString* pdfDescription = [[NSString alloc] initWithFormat:@"%@", pdfContext];
NSString* bitmapDescription = [[NSString alloc] initWithFormat:@"%@", bitmapContext];

NSLog(@"pdf = %@, isPDF = %@", pdfDescription, [pdfDescription containsString:@"PDF"] ? @"YES" : @"NO");
NSLog(@"bitmap = %@, isPDF = %@", bitmapDescription, [bitmapDescription containsString:@"PDF"] ? @"YES" : @"NO");


pdf = <CGContext 0x600001ae0840> (kCGContextTypePDF), isPDF = YES

bitmap = <CGContext 0x600001ae0b40> (kCGContextTypeBitmap)
<<CGColorSpace 0x600000be0c60> (kCGColorSpaceDeviceRGB)>
width = 100, height = 100, bpc = 8, bpp = 32, row bytes = 416 
kCGImageAlphaPremultipliedFirst | 0 (default byte order) | kCGImagePixelFormatPacked (default) , isPDF = NO



On Jun 19, 2020, at 10:23 PM, Graham Cox <graham@...> wrote:

I need to determine whether I am drawing into a CGPDFContext or a different context at runtime.

In AppKit, I can use [NSGraphicsContext currentContextDrawingToScreen], but this is code that is passed a CGContextRef only, so that higher-level API isn’t appropriate. CGPDFContext doesn’t appear to have an associated CGPDFContextGetTypeID() function to compare with the result of CFGetTypeID(), so it’s unclear how I can do this.

The reason I need to so this is that objects I am drawing can have different states according to whether they are selected in the UI or not, but when capturing the drawing into a PDF, the selection state needs to be ignored, so the drawing code needs to be able to detect what context type is so that it can do this.

—Graham


Determining CGContext type at runtime

Graham Cox
 

I need to determine whether I am drawing into a CGPDFContext or a different context at runtime.

In AppKit, I can use [NSGraphicsContext currentContextDrawingToScreen], but this is code that is passed a CGContextRef only, so that higher-level API isn’t appropriate. CGPDFContext doesn’t appear to have an associated CGPDFContextGetTypeID() function to compare with the result of CFGetTypeID(), so it’s unclear how I can do this.

The reason I need to so this is that objects I am drawing can have different states according to whether they are selected in the UI or not, but when capturing the drawing into a PDF, the selection state needs to be ignored, so the drawing code needs to be able to detect what context type is so that it can do this.

—Graham


iCloudKit - CoreData Integration: What am I doing wrong?

Rick Aurbach
 

I have a CoreData-based app where I am experimenting with inter-device synchronization using iCloudKit. At the moment, I am running in Development mode and am using an iPad and a MacCatalyst app as the two test devices. Bottom line - things aren't working. Looking at the generated logs, it appears that after getting everything set up, data requests are being cancelled because of pending requests. (I.e., it looks like a request is being LOST or maybe being UNANSWERED).

Both the Mac and the iPad use the same AppleID (but not the AppleID associated with the application).

I have put together a folder that may help explain the problem. It contains the code of my CoreDataStack class, the SceneDelegate that makes the call to open the database, the Xcode logs (from both the iPad and the iMac runs) showing the progression of messages, and printed images of information from my iCloudKit Dashboard.
(in case the folder attachment doesn't work, try this Dropbox download: https://www.dropbox.com/sh/vdeg9pcmy2fdo17/AABNuCdojZjr5tP6BEpu3T0ma?dl=0 ).


Re: Manually-shown palettes not showing during app restoration

Steve Mills
 

On May 18, 2020, at 10:29:13, Steve Mills via groups.io <sjmills=mac.com@groups.io> wrote:

I needed to add many attributes to my CoreData model. Filling in these attributes will happen during migration of old docs, which means loading all the files that each asset points to. Since it can take a while to do all this, I'm putting up a progress palette so the user knows something is happening. This works fine.

What does NOT work fine is when migration happens during app restoration. The palette says its window is loaded and the frame is correct, but it's just not appearing onscreen. Does app restoration do some kind of window manager voodoo that prevents windows NOT being restored from appearing? Maybe so it doesn't confuse the list of windows being restored?
Screw it. I've switched the migration progress window to a regular window and now present it modally. This kind of window WILL appear during state restoration, unlike a palette which has been sent orderFront.

--
Steve Mills
Drummer, Mac geek


Manually-shown palettes not showing during app restoration

Steve Mills
 

I needed to add many attributes to my CoreData model. Filling in these attributes will happen during migration of old docs, which means loading all the files that each asset points to. Since it can take a while to do all this, I'm putting up a progress palette so the user knows something is happening. This works fine.

What does NOT work fine is when migration happens during app restoration. The palette says its window is loaded and the frame is correct, but it's just not appearing onscreen. Does app restoration do some kind of window manager voodoo that prevents windows NOT being restored from appearing? Maybe so it doesn't confuse the list of windows being restored?

--
Steve Mills
Drummer, Mac geek


WkWebView with URLSchemeHandler

Gerriet M. Denkmann
 

macOS 15.4; Xcode Version 11.4 (11E146)

I have a window with a WkWebView.

This WkWebView should handle a special scheme.
The only way to do this that I know of, is:

@IBOutlet var wkWebView: WKWebView!
guard let webSuperView = wkWebView.superview else ...
let copiedConfiguration = wkWebView.configuration
copiedConfiguration.setURLSchemeHandler(self, forURLScheme: mySpecialScheme )
let newWebView = WKWebView(frame: wkWebView.frame, configuration: copiedConfiguration)
webSuperView.addSubview(newWebView)
wkWebView.removeFromSuperview()
wkWebView = newWebView

The problem: the old wkWebView had (done in IB) several layout constraints.

I tried to copy these constraints to the newWebView; but this crashes with:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION
(code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x00007fff2fcb5f13 AppKit`-[NSApplication _crashOnException:] + 106
frame #1: 0x00007fff2fa73c1c AppKit`__62+[CATransaction(NSCATransaction)
NS_setFlushesWithDisplayLink]_block_invoke + 805



• Is there a way to configure a URLSchemeHandler in IB?
• Is there a way to add a URLSchemeHandler to an existing WkWebView?

Gerriet.

161 - 180 of 1426