XIBObject* ObjectConverter::ConverterForObject(const char* className, pugi::xml_node node) {
    XIBObject* ret = NULL;

    // NOTE: Legacy XIBs (pre-XCode5) are not really under active expansion. Developers can upgrade their XIBs to modern XIB format using ibtool
    IS_CONVERTER(ret, className, "IBCocoaTouchEventConnection", UIRuntimeEventConnection)
    IS_CONVERTER(ret, className, "IBCocoaTouchOutletConnection", UIRuntimeOutletConnection)
    IS_CONVERTER(ret, className, "IBCocoaTouchOutletCollectionConnection", UIRuntimeOutletCollectionConnection)
    IS_CONVERTER(ret, className, "IBUICustomObject", ObjectConverterSwapper)
    IS_CONVERTER(ret, className, "IBProxyObject", UIProxyObject)
    IS_CONVERTER(ret, className, "IBUIView", UIView)
    IS_CONVERTER(ret, className, "IBUIViewController", UIViewController)
    IS_CONVERTER(ret, className, "NSColor", UIColor)
    IS_CONVERTER(ret, className, "IBUIFontDescription", UIFont)
    IS_CONVERTER(ret, className, "NSFont", UIFont)
    IS_CONVERTER(ret, className, "IBUIButton", UIButton)
    IS_CONVERTER(ret, className, "NSCustomResource", UICustomResource)
    IS_CONVERTER(ret, className, "NSImage", UICustomResource)
    IS_CONVERTER(ret, className, "IBUIWindow", UIWindow)
    IS_CONVERTER(ret, className, "IBUIScrollView", UIScrollView)
    IS_CONVERTER(ret, className, "IBUITableView", UITableView)
    IS_CONVERTER(ret, className, "IBUINavigationBar", UINavigationBar)
    IS_CONVERTER(ret, className, "IBUINavigationItem", UINavigationItem)
    IS_CONVERTER(ret, className, "IBUIBarButtonItem", UIBarButtonItem)
    IS_CONVERTER(ret, className, "IBUIImageView", UIImageView)
    IS_CONVERTER(ret, className, "IBUILabel", UILabel)
    IS_CONVERTER(ret, className, "IBUIAccessibilityConfiguration", UIRuntimeAccessibilityConfiguration)
    IS_CONVERTER(ret, className, "IBUITableViewCell", UITableViewCell)
    IS_CONVERTER(ret, className, "IBUITextField", UITextField)
    IS_CONVERTER(ret, className, "IBUITextView", UITextView)
    IS_CONVERTER(ret, className, "IBUIPickerView", UIPickerView)
    IS_CONVERTER(ret, className, "IBUIPageControl", UIPageControl)
    IS_CONVERTER(ret, className, "IBUIActivityIndicatorView", UIActivityIndicatorView)
    IS_CONVERTER(ret, className, "IBUISwitch", UISwitch)
    IS_CONVERTER(ret, className, "IBUIWebView", UIWebView)
    IS_CONVERTER(ret, className, "IBUITabBarController", UITabBarController)
    IS_CONVERTER(ret, className, "IBUINavigationController", UINavigationController)
    IS_CONVERTER(ret, className, "IBUITableViewController", UITableViewController)
    IS_CONVERTER(ret, className, "IBUITabBar", UITabBar)
    IS_CONVERTER(ret, className, "IBUITabBarItem", UITabBarItem)
    IS_CONVERTER(ret, className, "IBUIToolbar", UIToolbar)
    IS_CONVERTER(ret, className, "IBUISegmentedControl", UISegmentedControl)
    IS_CONVERTER(ret, className, "IBUIDatePicker", UIDatePicker)
    IS_CONVERTER(ret, className, "IBUISearchBar", UISearchBar)
    IS_CONVERTER(ret, className, "IBMKMapView", MKMapView)
    IS_CONVERTER(ret, className, "IBUISearchDisplayController", UISearchDisplayController)
    IS_CONVERTER(ret, className, "IBUISlider", UISlider)
    IS_CONVERTER(ret, className, "IBNSLayoutConstraint", NSLayoutConstraint)

    // Stubbed implementation
    IS_CONVERTER(ret, className, "IBUIProgressView", UIProgressView)
    IS_CONVERTER(ret, className, "IBUIPongPressGestureRecognizer", UIPongPressGestureRecognizer)

    if (ret == NULL) {
        ret = new XIBObject();
    }

    ret->ScanXIBNode(node);

    return ret;
}
Beispiel #2
0
XIBObject *ObjectConverter::ConverterForObject(const char *className, pugi::xml_node node)
{
    XIBObject *ret = NULL;

    IS_CONVERTER(ret, className, "IBCocoaTouchEventConnection", UIRuntimeEventConnection)
    IS_CONVERTER(ret, className, "IBCocoaTouchOutletConnection", UIRuntimeOutletConnection)
    IS_CONVERTER(ret, className, "IBCocoaTouchOutletCollectionConnection", UIRuntimeOutletCollectionConnection)
    IS_CONVERTER(ret, className, "IBUICustomObject", ObjectConverterSwapper)
    IS_CONVERTER(ret, className, "IBProxyObject", UIProxyObject)
    IS_CONVERTER(ret, className, "IBUIView", UIView)
    IS_CONVERTER(ret, className, "IBUIViewController", UIViewController)
    IS_CONVERTER(ret, className, "NSColor", UIColor)
    IS_CONVERTER(ret, className, "IBUIFontDescription", UIFont)
    IS_CONVERTER(ret, className, "NSFont", UIFont)
    IS_CONVERTER(ret, className, "IBUIButton", UIButton)
    IS_CONVERTER(ret, className, "NSCustomResource", UICustomResource)
    IS_CONVERTER(ret, className, "NSImage", UICustomResource)
    IS_CONVERTER(ret, className, "IBUIWindow", UIWindow)
    IS_CONVERTER(ret, className, "IBUIScrollView", UIScrollView)
    IS_CONVERTER(ret, className, "IBUITableView", UITableView)
    IS_CONVERTER(ret, className, "IBUINavigationBar", UINavigationBar)
    IS_CONVERTER(ret, className, "IBUINavigationItem", UINavigationItem)
    IS_CONVERTER(ret, className, "IBUIBarButtonItem", UIBarButtonItem)
    IS_CONVERTER(ret, className, "IBUIImageView", UIImageView)
    IS_CONVERTER(ret, className, "IBUILabel", UILabel)
    IS_CONVERTER(ret, className, "IBUIAccessibilityConfiguration", UIRuntimeAccessibilityConfiguration)
    IS_CONVERTER(ret, className, "IBUITableViewCell", UITableViewCell)
    IS_CONVERTER(ret, className, "IBUITextField", UITextField)
    IS_CONVERTER(ret, className, "IBUITextView", UITextView)
    IS_CONVERTER(ret, className, "IBUIPickerView", UIPickerView)
    IS_CONVERTER(ret, className, "IBUIPageControl", UIPageControl)
    IS_CONVERTER(ret, className, "IBUIActivityIndicatorView", UIActivityIndicatorView)
    IS_CONVERTER(ret, className, "IBUISwitch", UISwitch)
    IS_CONVERTER(ret, className, "IBUIWebView", UIWebView)
    IS_CONVERTER(ret, className, "IBUITabBarController", UITabBarController)
    IS_CONVERTER(ret, className, "IBUINavigationController", UINavigationController)
    IS_CONVERTER(ret, className, "IBUITableViewController", UITableViewController)
    IS_CONVERTER(ret, className, "IBUITabBar", UITabBar)
    IS_CONVERTER(ret, className, "IBUITabBarItem", UITabBarItem)
    IS_CONVERTER(ret, className, "IBUIToolbar", UIToolbar)
    IS_CONVERTER(ret, className, "IBUISegmentedControl", UISegmentedControl)
    IS_CONVERTER(ret, className, "IBUIDatePicker", UIDatePicker)
    IS_CONVERTER(ret, className, "IBUISearchBar", UISearchBar)
    IS_CONVERTER(ret, className, "IBMKMapView", MKMapView)
    IS_CONVERTER(ret, className, "IBUISearchDisplayController", UISearchDisplayController)
    IS_CONVERTER(ret, className, "IBUISlider", UISlider)
    IS_CONVERTER(ret, className, "IBNSLayoutConstraint", NSLayoutConstraint)

    if ( ret == NULL ) {
        ret = new XIBObject();
    }

    ret->ScanXIBNode(node);

    return ret;
}
void ConvertXIBToNib(FILE* fpOut, pugi::xml_document& doc) {
    pugi::xml_node dataNode = doc.first_element_by_path("/archive/data");

    XIBObject* root = new XIBObject();
    root->ScanXIBNode(dataNode);
    XIBObject::ParseAllXIBMembers();

    XIBObject* Objects = root->FindMember("IBDocument.Objects");
    XIBObject* objectRecords = Objects->FindMember("objectRecords");
    XIBDictionary* properties = (XIBDictionary*)Objects->FindMember("flattenedProperties");

    XIBObject* orderedObjects = objectRecords->FindMember("orderedObjects");

    //  Go through each ordered object to find replacements
    for (memberList::iterator cur = orderedObjects->_members.begin(); cur != orderedObjects->_members.end(); cur++) {
        XIBMember* curMember = *cur;
        XIBObject* curObject = curMember->_obj;

        if (strcmp(curObject->ClassName(), "IBObjectRecord") == 0) {
            XIBObject* obj = curObject->FindMember("object");

            if (obj) {
                XIBObject* objectId = curObject->FindMember("objectID");
                if (!objectId) {
                    objectId = curObject->FindMember("id");
                }
                int objId = objectId->intValue();

                //  Attempt to find any associated custom class name
                char szPropName[255];
                sprintf(szPropName, "%d.CustomClassName", objId);
                const char* pClassName = obj->ClassName();

                XIBObject* customName = properties->ObjectForKey(szPropName);
                if (customName) {
                    const char* pCustomName = customName->stringValue();
                    obj->SetSwappedClassName(pCustomName);
                }

                for (memberList::iterator prop = properties->_members.begin(); prop != properties->_members.end(); prop++) {
                    char szMeta[255];
                    sprintf(szMeta, "%d.", objId);
                    if (strncmp(szMeta, (*prop)->_name, strlen(szMeta)) == 0) {
                        obj->AddMember(&(*prop)->_name[strlen(szMeta)], (*prop)->_obj);
                    }
                }
            }
        }
    }

    //  Create connections list
    XIBArray* connections = new XIBArray();
    XIBObject* connectionrecords = Objects->FindMember("connectionRecords");

    for (memberList::iterator cur = connectionrecords->_members.begin(); cur != connectionrecords->_members.end(); cur++) {
        XIBMember* curMember = *cur;
        XIBObject* curObject = curMember->_obj;

        if (strcmp(curObject->ClassName(), "IBConnectionRecord") == 0) {
            XIBObject* obj = curObject->FindMember("connection");

            if (obj) {
                connections->AddMember(NULL, obj);
            }
        }
    }

    //  Sort connection records alphabetically using stable, uh, bubble sort
    for (;;) {
        bool didSwap = false;

        for (memberList::iterator cur = connections->_members.begin(); cur != connections->_members.end(); cur++) {
            if ((cur + 1) == connections->_members.end())
                break;
            XIBMember* curMember = (*cur);
            XIBMember* nextMember = (*(cur + 1));

            if (curMember->_name != NULL)
                continue;

            //  Event connections first
            if (strcmp(curMember->_obj->_className, "IBCocoaTouchOutletConnection") == 0 &&
                strcmp(nextMember->_obj->_className, "IBCocoaTouchEventConnection") == 0) {
                *cur = nextMember;
                *(cur + 1) = curMember;
                didSwap = true;
                continue;
            }

            if (strcmp(curMember->_obj->_className, nextMember->_obj->_className) == 0) {
                const char* label1 = curMember->_obj->FindMember("label")->stringValue();
                const char* label2 = nextMember->_obj->FindMember("label")->stringValue();

                if (strcmp(label1, label2) > 0) {
                    *cur = nextMember;
                    *(cur + 1) = curMember;
                    didSwap = true;
                }
            }
        }

        if (!didSwap)
            break;
    }

    //  Construct root object
    XIBObject* rootObjects = root->FindMember("IBDocument.RootObjects");
    rootObjects->_className = "NSArray";
    connections->_className = "NSArray";

    XIBArray* allObjects = new XIBArray();
    XIBArray* accessibilityObjects = new XIBAccessibilityArray();
    XIBArray* visibleWindows = new XIBArray();

    XIBObject* nibRoot = new XIBArray();
    nibRoot->_className = "NSObject";
    nibRoot->_members.clear();
    nibRoot->AddMember("UINibTopLevelObjectsKey", rootObjects);
    nibRoot->AddMember("UINibObjectsKey", allObjects);
    nibRoot->AddMember("UINibConnectionsKey", connections);
    nibRoot->AddMember("UINibVisibleWindowsKey", visibleWindows);
    nibRoot->AddMember("UINibAccessibilityConfigurationsKey", accessibilityObjects);
    nibRoot->AddMember("UINibKeyValuePairsKey", new XIBArray());

    NIBWriter* writer = new NIBWriter(fpOut);
    writer->_allUIObjects = allObjects;
    writer->_visibleWindows = visibleWindows;
    writer->AddOutputObject(nibRoot);
    writer->WriteData();
}