public NSDictionary ParseArchivedDictionary(NSDictionary archivedDictionary)
        {
            var keys    = archivedDictionary.GetAs <NSArray>("NS.keys");
            var objects = archivedDictionary.GetAs <NSArray>("NS.objects");

            if (keys == null || objects == null)
            {
                throw new NSKeyedArchiveException("Invalid archived NSDictionary");
            }

            if (keys.Count != objects.Count)
            {
                throw new NSKeyedArchiveException("NSDictionary: Different number of keys and values");
            }

            var dict = new NSDictionary();

            for (var i = 0; i < keys.Count; ++i)
            {
                var stringKey = ResolveObject(keys[i]) as NSString;
                if (stringKey == null)
                {
                    throw new NSKeyedArchiveException("Non-string keys in archived NSDictionaries are not supported");
                }

                var value = ResolveObject(objects[i]);

                dict.Add((string)stringKey, value);
            }

            return(dict);
        }
        SketchStringAttribute ParseAttribute(NSDictionary attributeDict)
        {
            var fontDescriptorAttributes = attributeDict
                                           .GetAs <NSDictionary>("MSAttributedStringFontAttribute")
                                           .GetAs <NSDictionary>("NSFontDescriptorAttributes");

            var alignment = SketchTextAlignment.Left;

            if (attributeDict.ContainsKey("NSParagraphStyle"))
            {
                var paragraphStyle = attributeDict.GetAs <NSDictionary>("NSParagraphStyle");
                if (paragraphStyle.ContainsKey("NSAlignment"))
                {
                    alignment = ParseAlignment(paragraphStyle.GetAs <NSNumber>("NSAlignment"));
                }
            }

            // Looks like the color format of text objects in Sketch has changed between version 91 and 93
            // I've only found MSAttributedStringColorDictionaryAttribute in version 93. 2018-01-05 anette
            var sketchColor = SketchColor.Black;

            if (attributeDict.ContainsKey("NSColor"))
            {
                var nsDictionaryColor = attributeDict.GetAs <NSDictionary>("NSColor");
                sketchColor = ParseColor(nsDictionaryColor);
            }
            else if (attributeDict.ContainsKey("MSAttributedStringColorDictionaryAttribute"))
            {
                var components = attributeDict.GetAs <NSDictionary>("MSAttributedStringColorDictionaryAttribute");
                sketchColor = new SketchColor(
                    double.Parse(components["red"].ToString()),
                    double.Parse(components["green"].ToString()),
                    double.Parse(components["blue"].ToString()),
                    components.ContainsKey("alpha") ? double.Parse(components["alpha"].ToString()) : 1.0);
            }
            else
            {
                _log.Warning("Could not find color property for text object. Default to black.");
            }
            var fontSize = (double)fontDescriptorAttributes.GetAs <NSNumber>("NSFontSizeAttribute");

            return(new SketchStringAttribute
                   (
                       sketchColor,
                       fontSize,
                       alignment
                   ));
        }
        public NSKeyedArchive(NSDictionary archive)
        {
            _archive = archive;

            var archiverName = (string)_archive.GetAs <NSString>("$archiver");

            if (archiverName != "NSKeyedArchiver")
            {
                throw new ArgumentException("Invalid NSKeyedArchiver dictionary", nameof(archive));
            }

            var version = _archive.GetAs <NSNumber>("$version");

            if (version.ToInt() != 100000)
            {
                throw new ArgumentException("Unsupported NSKeyedArchiver version", nameof(archive));
            }
        }
        public NSArray ParseArchivedArray(NSDictionary archivedArray)
        {
            var objects = archivedArray.GetAs <NSArray>("NS.objects");

            var resolvedArray = new NSArray();

            foreach (var @object in objects)
            {
                resolvedArray.Add(ResolveObject(@object));
            }

            return(resolvedArray);
        }
        public NSObject ResolveObjectWithClassInfo(NSDictionary dict, NSDictionary classInfo)
        {
            var classes = classInfo.GetAs <NSArray>("$classes");

            if (classes.Contains("NSDictionary"))
            {
                return(ParseArchivedDictionary(dict));
            }
            if (classes.Contains("NSArray"))
            {
                return(ParseArchivedArray(dict));
            }
            if (classes.Contains("NSString"))
            {
                return(ParseArchivedString(dict));
            }

            return(dict);
        }
 public NSString ParseArchivedString(NSDictionary archivedString)
 {
     return(archivedString.GetAs <NSString>("NS.string"));
 }
 public int ParseObjectReferenceId(NSDictionary reference)
 {
     return((int)reference.GetAs <NSNumber>("CF$UID"));
 }