Pull to refresh
0
DataArt
Технологический консалтинг и разработка ПО

Как победить Excluded Constraints с помощью RubyGem

Reading time 3 min
Views 4.7K


Во время разработки iOS/OSX-приложений непременно приходится использовать Interface Builder и Auto Layout. В приложениях со сложными интерфейсом и в приложениях, находящихся в разработке достаточно давно, часто появляется проблема с большим количеством «исключенных констрейнов». Storyboard грузится необоснованно долго, а во время перехода между сценами можно успеть сходить за кофе.

Но, казалось бы, интерфейс всех контроллеров такой же незамысловатый, как и в релизе полгода назад. Что же случилось? Тем, кто использовал Size Classes, сразу понятно, что интерфейс — не такая простая штука, как кажется. Он ведет себя по-разному в разных ориентациях и на разных дисплеях. Делает он это, потому что некоторые constraints применяются только в определенной ситуации.

Это значит, что в остальных ситуациях эти constraints не используются. У Xcode Interface Builder есть особенность, которая помогает при разработке сложных интерфейсов и мешает при разработке простых. Если добавить constraint к какому-то UIView и затем удалить его из Xcode Inspector (а чаще всего это — самый удобный путь), Xcode не удалит его, а лишь сложит в список неиспользуемых на случай, если понадобится для другого дисплея или ориентации.

Иногда, если развернуть все группы constraints, можно ужаснуться происходящему в storyboard-файле:


Не хотите наблюдать подобное? Добро пожаловать под кат!

Больше половины constraints лежат в «корзине» и ждут, пока их добавят к определенному дисплею или ориентации или удалят. А до тех пор — съедают драгоценные секунды загрузки файла и оставшиеся нервные клетки разработчика.

Что же делать?
Можно открывать по очереди все свои storyboard- и xib-файлы, в них открывать всех наследников UIView и, убедившись, что этот constraint не используется для Size Classes, удалить их, используя Document Outline

А можно предоставить эту скучную, не имеющую права на ошибку работу умному Ruby-скрипту. Итак, нам надо найти все storyboard- и xib-файлы в проекте:
```
files = Dir.glob("**/*.{storyboard,xib}") 
files.each{ |file|  cleanupConstraints(file)}
```


Готово, теперь в этих файлах надо найти исключенные constraints:

```
require 'nokogiri'

def cleanupConstraints(file)
	f = File.open(file)
	doc = Nokogiri::XML(f)
	f.close
	excluded = doc.xpath('//exclude')
end
```


Еще надо не забыть про Size Classes и оставить на местах все constraints, которые включены хоть в одну комбинацию «дисплей/ориентация».
```
require 'nokogiri'

def cleanupConstraints(file)
	f = File.open(file)
	doc = Nokogiri::XML(f)
	f.close
	excluded = doc.xpath('//exclude')
	included = doc.xpath('//include')
	
	result = [] 
	excluded.each do |node| 
		found = false
		for includedNode in included
			if node.attr('reference') == includedNode.attr('reference')
				found = true
				break
			end
		end
		if !found 
			result.push(node)
			nodeID = node.attr('reference')
			constraints = doc.xpath("//constraint[@id='#{nodeID}']")
			result += constraints
		end
	end
	if result.count > 0 
		f1 = File.open(file, 'w')
		result.each{ |node| node.remove }
		f1.write(doc.to_xml)	
		f1.close	
		p "removed #{result.count} constraint(s) from #{file}"
	end
end
```



Маленькая победа, но как использовать этот скрипт? Ответ прост — создать RubyGem.

Для создания Gem есть несколько путей, я использовал описанный здесь guides.rubygems.org/make-your-own-gem.

Теперь очистить проект (или даже все проекты разом!) можно, установив Gem
```
$ gem install constraintClean
```

В директории своего проекта (или в директории со всеми своими проектами) выполнив
```
$ constraintClean
```

И это прекрасно!

github.com/kohtenko/KOConstraintClean
Tags:
Hubs:
+8
Comments 4
Comments Comments 4

Articles

Information

Website
www.dataart.com
Registered
Founded
Employees
1,001–5,000 employees