How do you encode and decode a CGPoint struct using NSCoder?
            Asked
            
        
        
            Active
            
        
            Viewed 6,418 times
        
    16
            
            
        
        Paulo Mattos
        
- 18,845
 - 10
 - 77
 - 85
 
        mikechambers
        
- 3,047
 - 3
 - 24
 - 31
 
- 
                    Just leaving this here for others. In Swift on MacOSX CGPoint is the same as NSPoint: public func encodeWithCoder(coder: NSCoder) { coder.encodePoint(myNSPoint, forKey: "someKeyName") } – Jubei Mar 09 '16 at 12:42
 
3 Answers
26
            
            
        To encode:
CGPoint point = /* point from somewhere */
NSValue *pointValue = [NSValue value:&point withObjCType:@encode(CGPoint)];
[coder encodeObject:pointValue forKey:@"point"];
To decode:
NSValue *decodedValue = [decoder decodeObjectForKey:@"point"];
CGPoint point;
[decodedValue getValue:&point];
        sbooth
        
- 16,646
 - 2
 - 55
 - 81
 
- 
                    1+1 This seems like a much better, less hackish general-purpose solution. – Quinn Taylor Mar 08 '10 at 22:50
 - 
                    4+1 BTW, you can use `(NSValue *)valueWithCGPoint:(CGPoint)point` class method. – Rudolf Adamkovič Aug 14 '13 at 18:27
 
17
            
            
        Just an update for iOS developers. You can do the following in Cocoa Touch (but not in Cocoa):
[coder encodeCGPoint:myPoint forKey:@"myPoint"];
        Cody Gray - on strike
        
- 239,200
 - 50
 - 490
 - 574
 
        Eric G
        
- 1,429
 - 18
 - 26
 
- 
                    1And you can decode with [aDecoder decodeCGPointForKey:@"myPoint"]; – Chuck Krutsinger Jan 14 '14 at 21:53
 
10
            CGPoints and NSPoints are both structures composed of two CGFloat values, so you can freely pass them around as each other.  The quick and dirty way would be:
NSCoder *myNSCoder;
CGPoint myPoint;
[myNSCoder encodePoint:*(NSPoint *)myPoint];
This will usually work, but it technically breaks the C99 strict aliasing rules. If you want to be 100% compatible with the standard, you'll have to do something like:
typedef union
{
  CGPoint cgPoint;
  NSPoint nsPoint;
} CGNSPoint;
CGNSPoint cgnsPoint = { .cgPoint = myPoint };
[myNSCoder encodePoint:cgnsPoint.nsPoint];
        Adam Rosenfield
        
- 390,455
 - 97
 - 512
 - 589
 
- 
                    2However, if you’re building for the 64-bit runtime, or have NS_BUILD_32_LIKE_64 defined to 1, NSPoint and CGPoint are typedefed to the same struct, so no casting or union shenanigans are required. – Jens Ayton Jan 15 '09 at 20:55
 - 
                    3Furthermore, Foundation provides two inline functions named NSPoint{To,From}CGPoint. No need for pointer casting or a union. – Peter Hosey Jan 16 '09 at 02:30