Slide 1

Slide 1 text

Building(iOS(Content(Blockers Kuba%Suder @kuba_suder+•+h.ps:/ /mackuba.eu

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Why$write$content$blockers? • sanity((hide(ads,(popups) • performance((loading(speed,(mobile(data(plan) • privacy((trackers(spying(on(you(via(cookies) • !((Crystal(<>($100K+)

Slide 4

Slide 4 text

How$to$build$a$content$blocker

Slide 5

Slide 5 text

Start%here: h"ps:/ /webkit.org/blog/3476/content8 blockers8first8look

Slide 6

Slide 6 text

How$to$build$a$content$blocker$app 1. Create(a(new(app. 2. Add(a("Content(Blocker(Extension"(target. 3. Provide(a(JSON(file(with(filter(definiCons. 4. Submit(to(the(App(Store. 5. ... 6. Get(rejected(!((at(least(I(did)

Slide 7

Slide 7 text

Rules&of&the&game 1. Can&block&resources&or&cookies 2. Can&hide&elements&with&CSS 3. Cannot&see&accessed&URLs&(good&for&user,&bad&for&you) 4. Can&be&updated&or&dynamically&generated 5. Runs&inside&Safari&process&(extension) 6. User&can&turn&it&on/off&I&disabled,by,default

Slide 8

Slide 8 text

Filter'format [ { "trigger": { ... }, "action": { ... } }, { "trigger": { ... }, "action": { ... } }, ... ]

Slide 9

Slide 9 text

Blocking)resources { "trigger": { "url-filter": "banner.*", "resource-type": ["image"], "if-domain": ["gazeta.pl"] }, "action": { "type": "block" } }

Slide 10

Slide 10 text

Blocking)elements { "trigger": { "url-filter": ".*", "if-domain": ["onet.pl"] }, "action": { "type": "css-display-none", "selector": "#banner, .cookie, div[title=Sport]" } }

Slide 11

Slide 11 text

Pro$%ps

Slide 12

Slide 12 text

Tips%#1:%Reloading%during%development • switch(it(off(&(on(in(Se/ngs • remember,(it's(off(by(default! • be=er: SFContentBlockerManager. reloadContentBlockerWithIdentifier(id) (from(SafariServices) • put(it(in( application:didFinishLaunchingWithOptions:

Slide 13

Slide 13 text

Tips%#2:%Debugging • use%Safari%inspector%to%find%things%to%block • launch%from%the%desktop%Safari,%Develop%menu • logs%from%the%extension%can%only%be%seen%in%the%system%log • for%device:%Xcode's%Devices%window • for%simulator:%find%the%right%system.log

Slide 14

Slide 14 text

Tips%#3:%Communica0ng%with%the%app • extension)and)main)app)don't)run)in)the)same)process • create)an)App)Group • shared)user)defaults)container • shared)folder)for)exchanging)files

Slide 15

Slide 15 text

Tips%#4:%UI • explain)what)the)app)does • show)how)to)enable)it)(with)screenshots) • beware)of)copyright)issues)9>)don't)use)screenshots)of)real)sites

Slide 16

Slide 16 text

Tips%#5:%Collec.ng%data • you%can%only%collect%new%URLs%if%users%submit%them%to%you • use%a%share%extension • NSExtensionJavaScriptPreprocessingFile%to%get%page% URL/;tle

Slide 17

Slide 17 text

Demo%&me !

Slide 18

Slide 18 text

More%&ps%here: h"ps:/ /gist.github.com/mackuba/ e81558926e9a09f06e58