void ConvertStoryboard(pugi::xml_document& doc) { pugi::xml_node curNode = doc.first_child(); // Storyboard XIB file - get topmost controller, then export it const char* initialController = curNode.attribute("initialViewController").value(); for (; curNode; curNode = curNode.next_sibling()) { if (curNode.type() == pugi::xml_node_type::node_element) { XIBArray* root = new XIBArray(); root->ScanStoryObjects(curNode); } } XIBObject::ParseAllStoryMembers(); // Print which XML nodes we did not handle during the parse for diagnostic purpose. XIBObject::getDocumentCoverage(doc); NIBWriter::ExportController(initialController); Plist::dictionary_type viewControllerInfo; viewControllerInfo[std::string("UIStoryboardDesignatedEntryPointIdentifier")] = std::string("UIViewController-") + std::string(initialController); viewControllerInfo[std::string("UIStoryboardVersion")] = (int)1; Plist::dictionary_type viewControllerMappings; for (auto curController : _g_exportedControllers) { viewControllerMappings[curController.first] = curController.second; } viewControllerInfo[std::string("UIViewControllerIdentifiersToNibNames")] = viewControllerMappings; printf("Writing %s\n", GetOutputFilename("Info.plist").c_str()); Plist::writePlistBinary(GetOutputFilename("Info.plist").c_str(), viewControllerInfo); }
void NIBWriter::ExportController(const char *controllerId) { char szFilename[255]; XIBObject* controller = XIBObject::findReference(controllerId); UIViewController* uiViewController = dynamic_cast<UIViewController*>(controller); if (!uiViewController) { //object isn't really a controller printf("Object %s is not a controller\n", controller->stringValue()); return; } const char* controllerIdentifier = uiViewController->_storyboardIdentifier; if (controllerIdentifier == NULL) { //not all viewcontrollers will have a storyboard identifier. If they don't use the controller Id for the key. controllerIdentifier = controllerId; } // Check if we've already written out the controller if (_g_exportedControllers.find(controllerId) != _g_exportedControllers.end()) { return; } sprintf(szFilename, "%s.nib", controllerIdentifier); _g_exportedControllers[controllerIdentifier] = controllerIdentifier; XIBArray *objects = (XIBArray *) controller->_parent; printf("Writing %s\n", GetOutputFilename(szFilename).c_str()); FILE *fpOut = fopen(GetOutputFilename(szFilename).c_str(), "wb"); NIBWriter *writer = new NIBWriter(fpOut, NULL, NULL); XIBObject *firstResponderProxy = writer->AddProxy("IBFirstResponder"); XIBObject *ownerProxy = writer->AddProxy("IBFilesOwner"); XIBObject *storyboard = writer->AddProxy("UIStoryboardPlaceholder"); XIBArray *arr = (XIBArray *) objects; for ( int i = 0; i < arr->count(); i ++ ) { XIBObject *curObj = arr->objectAtIndex(i); writer->ExportObject(curObj); if ( curObj->getAttrib("sceneMemberID") ) { if ( strcmp(curObj->getAttrib("sceneMemberID"), "viewController") == 0 ) { writer->AddOutletConnection(ownerProxy, curObj, "sceneViewController"); } } } writer->WriteObjects(); fclose(fpOut); }
void UIViewController::InitFromXIB(XIBObject *obj) { ObjectConverterSwapper::InitFromXIB(obj); _view = (UIView *) obj->FindMember("IBUIView"); _tabBarItem = (UITabBarItem *) obj->FindMember("IBUITabBarItem"); _navigationItem = (UINavigationItem *) obj->FindMember("IBUINavigationItem"); _resizesToFullSize = obj->GetBool("IBUIAutoresizesArchivedViewToFullSize", true); XIBArray *viewControllers = (XIBArray *) obj->FindMember("IBUIViewControllers"); if ( viewControllers ) { for ( int i = 0; i < viewControllers->count(); i ++ ) { XIBObject *curObj = viewControllers->objectAtIndex(i); ((UIViewController *) curObj)->_parentViewController = this; _childViewControllers->AddMember(NULL, curObj); _viewControllers->AddMember(NULL, curObj); } } _outputClassName = "UIViewController"; }
void NIBWriter::ExportController(const char *controllerId) { static std::vector<char *> _exportedControllers; for ( std::vector<char *>::iterator cur = _exportedControllers.begin(); cur != _exportedControllers.end(); cur ++ ) { if ( strcmp(*cur, controllerId) == 0 ) { return; } } _exportedControllers.push_back(strdup(controllerId)); XIBObject *controller = XIBObject::findReference(controllerId); XIBArray *objects = (XIBArray *) controller->_parent; char szFilename[255]; sprintf(szFilename, "UIViewController-%s.nib", controllerId); printf("Writing %s\n", szFilename); FILE *fpOut = fopen(szFilename, "wb"); NIBWriter *writer = new NIBWriter(fpOut, NULL, NULL); XIBObject *firstResponderProxy = writer->AddProxy("IBFirstResponder"); XIBObject *ownerProxy = writer->AddProxy("IBFilesOwner"); XIBObject *storyboard = writer->AddProxy("UIStoryboardPlaceholder"); XIBArray *arr = (XIBArray *) objects; for ( int i = 0; i < arr->count(); i ++ ) { XIBObject *curObj = arr->objectAtIndex(i); writer->ExportObject(curObj); if ( curObj->getAttrib("sceneMemberID") ) { if ( strcmp(curObj->getAttrib("sceneMemberID"), "viewController") == 0 ) { writer->AddOutletConnection(ownerProxy, curObj, "sceneViewController"); } } } writer->WriteObjects(); fclose(fpOut); }
void ConvertXIB3ToNib(FILE* fpOut, pugi::xml_document& doc) { pugi::xml_node curNode = doc.first_child(); // XIB3 file XIBDocument* rootDocument = new XIBDocument(curNode); XIBObject::ParseAllStoryMembers(); XIBObject::getDocumentCoverage(doc); XIBArray* viewObjects = rootDocument->Objects(); if (viewObjects) { NIBWriter* writer = new NIBWriter(fpOut, NULL, NULL); XIBArray* arr = (XIBArray*)viewObjects; for (int i = 0; i < arr->count(); i++) { XIBObject* curObj = arr->objectAtIndex(i); writer->ExportObject(curObj); } writer->WriteObjects(); } }
void _UILayoutGuide::Awaken() { UIView::Awaken(); UIView *controllerView = (UIView*)_parent->_parent->FindMemberClass("view"); if (!controllerView) { assert(0); } XIBArray *subviews = (XIBArray *)controllerView->_subviews; XIBArray *constraints = (XIBArray *)controllerView->_constraints; if (!subviews || !constraints) { assert(0); } NSLayoutConstraint* supportConstraintHeight = new NSLayoutConstraint(); NSLayoutConstraint* supportConstraintPos = new NSLayoutConstraint(); // Height supportConstraintHeight->_firstItem = this; supportConstraintHeight->_firstAttribute = NSLayoutAttributeHeight; supportConstraintHeight->_outputClassName = "_UILayoutSupportConstraint"; // Edges supportConstraintPos->_firstItem = this; supportConstraintPos->_firstAttribute = _attribute; supportConstraintPos->_secondItem = controllerView; supportConstraintPos->_secondAttribute = _attribute; supportConstraintPos->_outputClassName = "_UILayoutSupportConstraint"; // I think how this is supposed to work is as the nav/tab/status bar heights change, we update the height // of the top and bottom constraints. This appears to be just to get around the views not being sibblings. subviews->AddMember(NULL, this); constraints->AddMember(NULL, supportConstraintHeight); constraints->AddMember(NULL, supportConstraintPos); }
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(); }
void UIViewController::ConvertStaticMappings(NIBWriter *writer, XIBObject *obj) { Map(writer, obj, propertyMappings, numPropertyMappings); XIBArray *segueTemplates = new XIBArray(); if ( _tabBarItem ) AddOutputMember(writer, "UITabBarItem", _tabBarItem); if ( _navigationItem ) AddOutputMember(writer, "UINavigationItem", _navigationItem); if ( !_resizesToFullSize ) AddBool(writer, "UIAutoresizesArchivedViewToFullSize", _resizesToFullSize); if ( _view ) { if ( !_isStory ) { AddOutputMember(writer, "UIView", _view); } else { ScanForSegues(segueTemplates, this); XIBDictionary *externalObjects = new XIBDictionary(); char szNibName[255]; sprintf(szNibName, "%s-view-%s", _id, _view->_id); AddString(writer, "UINibName", szNibName); char szOutputName[255]; sprintf(szOutputName, "%s.nib", szNibName); printf("Writing %s\n", GetOutputFilename(szOutputName).c_str()); FILE *fpOut = fopen(GetOutputFilename(szOutputName).c_str(), "wb"); NIBWriter *viewWriter = new NIBWriter(fpOut, externalObjects, _view); viewWriter->ExportObject(_view); XIBObject *ownerProxy = viewWriter->AddProxy("IBFilesOwner"); viewWriter->_topObjects->AddMember(NULL, ownerProxy); XIBObject *firstResponderProxy = viewWriter->AddProxy("IBFirstResponder"); viewWriter->_topObjects->AddMember(NULL, firstResponderProxy); // Add view connection viewWriter->AddOutletConnection(ownerProxy, _view, "view"); viewWriter->WriteObjects(); fclose(fpOut); if ( externalObjects->_members.size() > 1 ) AddOutputMember(writer, "UIExternalObjectsTableForViewLoading", externalObjects); } } if ( _parentViewController ) { AddOutputMember(writer, "UIParentViewController", _parentViewController); } if ( _isStory ) { XIBObject *storyboard = writer->AddProxy("UIStoryboardPlaceholder"); writer->AddOutletConnection(this, storyboard, "storyboard"); for ( int i = 0; i < segueTemplates->count(); i ++ ) { UIStoryboardSegue *curSegue = (UIStoryboardSegue *) segueTemplates->objectAtIndex(i); writer->AddOutletConnection(curSegue, this, "viewController"); } if ( segueTemplates->count() > 0 ) { AddOutputMember(writer, "UIStoryboardSegueTemplates", segueTemplates); for ( int i = 0; i < segueTemplates->count(); i ++ ) { UIStoryboardSegue *curSegue = (UIStoryboardSegue *) segueTemplates->objectAtIndex(i); NIBWriter::ExportController(curSegue->getAttrib("destination")); } } } if ( _childViewControllers->count() > 0 ) { AddOutputMember(writer, "UIChildViewControllers", _childViewControllers); } if ( _viewControllers->count() > 0 ) { AddOutputMember(writer, "UIViewControllers", _viewControllers); } ObjectConverterSwapper::ConvertStaticMappings(writer, obj); }