您好,欢迎来到锐游网。
搜索
您的当前位置:首页WebKit_DisplayWebContent

WebKit_DisplayWebContent

来源:锐游网
WebKitObjective-CProgrammingGuide

Networking,Internet,&Web:WebClient

2009-07-28

AppleInc.

©2003,2009AppleInc.Allrightsreserved.

Nopartofthispublicationmaybereproduced,storedinaretrievalsystem,ortransmitted,inanyformorbyanymeans,mechanical,electronic,photocopying,recording,or

otherwise,withoutpriorwrittenpermissionofAppleInc.,withthefollowingexceptions:Anypersonisherebyauthorizedtostoredocumentationonasinglecomputerforpersonaluseonlyandtoprintcopiesof

documentationforpersonaluseprovidedthatthedocumentationcontainsApple’scopyrightnotice.

TheApplelogoisatrademarkofAppleInc.Useofthe“keyboard”Applelogo

(Option-Shift-K)forcommercialpurposeswithoutthepriorwrittenconsentofApplemayconstitutetrademarkinfringementandunfaircompetitioninviolationoffederalandstatelaws.

Nolicenses,expressorimplied,aregrantedwithrespecttoanyofthetechnologydescribedinthisdocument.Appleretainsallintellectualpropertyrightsassociatedwiththetechnologydescribedinthisdocument.ThisdocumentisintendedtoassistapplicationdeveloperstodevelopapplicationsonlyforApple-labeledcomputers.

Everyefforthasbeenmadetoensurethattheinformationinthisdocumentisaccurate.Appleisnotresponsiblefortypographicalerrors.AppleInc.1InfiniteLoop

Cupertino,CA95014408-996-1010

Apple,theApplelogo,Carbon,Cocoa,Mac,MacOS,Objective-C,Pages,QuickTime,Safari,andXcodearetrademarksofAppleInc.,registeredintheUnitedStatesandothercountries.

WebScriptisatrademarkofAppleInc.JavaisaregisteredtrademarkofOracleand/oritsaffiliates

SimultaneouslypublishedintheUnitedStatesandCanada.

EventhoughApplehasreviewedthisdocument,APPLEMAKESNOWARRANTYORREPRESENTATION,EITHEREXPRESSORIMPLIED,WITHRESPECTTOTHISDOCUMENT,ITSQUALITY,ACCURACY,

MERCHANTABILITY,ORFITNESSFORAPARTICULARPURPOSE.ASARESULT,THISDOCUMENTIS

PROVIDED“ASIS,”ANDYOU,THEREADER,AREASSUMINGTHEENTIRERISKASTOITSQUALITYANDACCURACY.

INNOEVENTWILLAPPLEBELIABLEFORDIRECT,INDIRECT,SPECIAL,INCIDENTAL,OR

CONSEQUENTIALDAMAGESRESULTINGFROMANYDEFECTORINACCURACYINTHISDOCUMENT,evenifadvisedofthepossibilityofsuchdamages.THEWARRANTYANDREMEDIESSETFORTHABOVEAREEXCLUSIVEANDINLIEUOFALLOTHERS,ORALORWRITTEN,EXPRESSORIMPLIED.NoAppledealer,agent,oremployeeisauthorizedtomakeanymodification,extension,oradditiontothiswarranty.

Somestatesdonotallowtheexclusionorlimitationofimpliedwarrantiesorliabilityforincidentalorconsequentialdamages,sotheabovelimitationorexclusionmaynotapplytoyou.Thiswarrantygivesyouspecificlegalrights,andyoumayalsohaveotherrightswhichvaryfromstatetostate.

Contents

IntroductiontoWebKitObjective-CProgrammingGuide9

WhoShouldReadThisDocument?9OrganizationofThisDocument10SeeAlso11

WhyUsetheWebKit?13CoreWebKitClasses15

FrameModelandViewClasses15DataModelandViewClasses16

Provisionalvs.CommittedDataSources17WebViewDelegates18

SimpleBrowsing21MultipleWindows23

OpeningWindows23EnteringURLs23

HandlingNewWindowRequests24

LoadingPages27

SequenceofFrameLoadDelegateMessages27TestingfortheMainFrame28DisplayingtheCurrentURL28DisplayingthePageTitle28DisplayingLoadStatus29

LoadingResources31

SequenceofResourceLoadDelegateMessages31IdentifyingResources31

TrackingResourceLoadProgress32

PagingBackandForward35

EnablingandDisablingtheBack-ForwardList35AddingBackandForwardButtons35SettingthePageCache35

3

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

SettingtheCapacity36TheCurrentItem36ManagingState36

ManagingHistory37

SharingHistoryObjects37

AddingandRemovingHistoryItems37LoadingaHistoryItem38

SavingandLoadingHistoryObjects38

MakingPolicyDecisions39EnablingEditing41

SavingandLoadingWebContent43ModifyingtheCurrentSelection45ChangingEditingBehavior47

ShouldMethods47DidMethods47

UsingUndoWhenEditing49

UsingtheDocumentObjectModelfromObjective-C51

InterpretingtheDOMSpecification51HandlingExceptions53

UsingtheDocumentObjectModelExtensions55UsingJavaScriptFromObjective-C57Spoofing59

AccessingtheWebKitFromCarbonApplications61DeterminingWebKitAvailability63

TestingforURLLoadingSystemAvailability63TestingforWebKitAvailability63

4

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

IsolatingYourWebKitandURLLoadingSystemSymbolsConditionallyLoadingCodeWeakLinkingSymbols

DocumentRevisionHistory67

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

5

6

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

FiguresandListings

CoreWebKitClasses15

Figure1Figure2Figure3

WebViewandWebFrameViewobjects16WebFrameandWebDataSourceobjects17Typicalwebsite18

DeterminingWebKitAvailability63

Listing1Listing2Listing3

DeterminingiftheURLLoadingsystemisavailable.63DeterminingiftheWebKitframeworkisavailable63

LoadingWebKitconstantsdynamicallyusingCFBundle65

7

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

8

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

IntroductiontoWebKitObjective-CProgrammingGuide

Concurrency Note: TheWebKitframeworkisnotthreadsafe.Ifyoucallfunctionsormethodsinthisframework,youmustdosoexclusivelyonthemainprogramthread.

WhatIstheWebKit?

TheWebKitprovidesasetofcoreclassestodisplaywebcontentinwindows,andbydefault,implementsfeaturessuchasfollowinglinksclickedbytheuser.TheWebKitgreatlysimplifiesthecomplicatedprocessofloadingwebpages—thatis,asynchronouslyrequestingwebcontentfromanHTTPserveroverthenetworkwheretheresponsemayarriveincrementally,inrandomorder,orpartiallyduetonetworkerrors.TheWebKitalsosimplifiestheprocessofdisplayingcontentthatcancontainvariousMIMEtypes,andmultipleframeseachwiththeirownsetofscrollbars.

YouusetheWebKittodisplaywebcontentinawindowofyourapplication.It’sassimpleascreatingaview,placingitinawindow,andsendingaURLloadrequestmessage.Bydefault,yourWebKitapplicationbehavesasyouwouldexpectwithouterror.TheWebKitconvenientlycreatesandmanagesalltheviewsneededtohandledifferentMIMEtypes.Whentheuserclicksonalinkinapage,theWebKitautomaticallycreatestheviewsneededtodisplaythenextpage.

However,theWebKitdoesn’timplementacompletesetofwebbrowserfeatures.Youcan,however,extendtheWebKitbyimplementingcustomdelegate,view,andmodelobjects.Forexample,youcanimplementadelegatetodisplayloadstatus,andthecurrentURL.

TheWebKitalsoofferswebcontentediting.IfyouenableeditinginyourWebView,userscaneditthewebcontentitdisplays.YoucanprogrammaticallycontrolthecurrentselectionandcontroleditingbehaviorusingaWebViewdelegate.YoucanalsomodifytheDocumentObjectModeldirectlyusinganObjective-CAPI.

YoucanalsoaccessJavaScriptfromObjective-Candviceversa.

WhoShouldReadThisDocument?

TheWebKitObjective-CAPIisspecificallydesignedforembeddingwebcontentinyourCocoaorCarbonapplications—developingwebclientapplicationsnotwebserverapplicationsorwebcontent.Itisalsonotsuitableforimplementingnon-GUIapplicationssuchaswebcrawlers.IfyouareawebcontentcreatororJavaScriptprogrammer,refertoWebKitDOMProgrammingTopics.

WhatIstheWebKit?

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

9

IntroductiontoWebKitObjective-CProgrammingGuide

Important: Currently,thisAPIisavailableinObjective-Conly.AminimalCAPIisprovidedforembeddingwebbrowserviewsinCarbonapplications.YoucanuseObjective-CincombinationwithC.TheWebKitworkswithallversionsofMacOSX10.2thathaveSafari1.0installed.

OrganizationofThisDocument

ThefollowingarticlescoverkeyconceptsinunderstandinghowtheWebKitworks:

“WhyUsetheWebKit?” (page 13)describesthepurposeoftheWebKitandwhyyoumightwanttouseitinyourapplications.

“CoreWebKitClasses” (page 15)describesthecoreWebKitclassesandtheobject-orienteddesignthatisfundamentaltounderstandinghowtheWebKitworks.

Thefollowingarticlesexplainhowtodisplaywebcontentinviews:

“SimpleBrowsing” (page 21)showshowtoembedwebcontentinyourapplicationbyfollowingafewsimplesteps.

“MultipleWindows” (page 23)showshowtoaddsupportformultiplewindows,andopenwindowsautomatically.

“LoadingPages” (page 27)showshowtotracktheprogressofloadingframecontent.

“LoadingResources” (page 31)showshowtotracktheprogressofloadingindividualresourcesonapage.

“PagingBackandForward” (page 35)showshowtoimplementaback-forwardlistandaddBackandForwardbuttonstoyourapplication.

“ManagingHistory” (page 37)showshowtomaintainahistoryofallthevisitedpages,andallowtheusertogotoapreviouslyvisitedpage.

“Spoofing” (page 59)showshowtouseuser-agentstrings.

“AccessingtheWebKitFromCarbonApplications” (page 61)explainshowtoembedwebcontentinCarbonapplications.

“DeterminingWebKitAvailability” (page 63)explainshowtodetermineiftheWebKitisavailableonyoursystem.

■ ■

■ ■

Thefollowingarticlesexplainhowtoimplementwebcontentediting:

■ ■

“EnablingEditing” (page 41)showshowtoenableusereditinginaWebView.

“SavingandLoadingWebContent” (page 43)showshowtosaveandloadwebcontenteditedbytheuser.

“ModifyingtheCurrentSelection” (page 45)showshowtoprogrammaticallymodifythecurrentselection.“ChangingEditingBehavior” (page 47)explainshowtousetheWebVieweditingdelegatetocustomizeeditingbehavior.

“UsingUndoWhenEditing” (page 49)showshowtoimplementundowheneditingwebcontent.

■ ■

ThefollowingarticlesexplainhowtousetheDocumentObjectModelObjective-CAPI:

10

OrganizationofThisDocument

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

IntroductiontoWebKitObjective-CProgrammingGuide

“UsingtheDocumentObjectModelfromObjective-C” (page 51)describestheDOMObjective-CAPIintermsofthespecification.

“UsingtheDocumentObjectModelExtensions” (page 55)describestheWebKitextensionstotheDOMAPI.

ReadthisarticleifyouwanttoaccessJavaScriptfromyourapplication:

“UsingJavaScriptFromObjective-C” (page 57)showshowtoaccessthescriptingenvironmentfromanObjective-Capplication.

YoubeginusingtheWebKitbyfirstembeddingwebcontentinyourapplication.Read“SimpleBrowsing” (page21),and,optionally,“LoadingPages” (page 27)and“LoadingResources” (page 31)toembedwebcontent.Ifyouwanttoaddmorebrowser-likefeaturesorimplementacustomuserinterface,read“CoreWebKitClasses” (page 15)firstandanyotherarticlesbasedonyourapplicationneeds.Ifyouwanttoeditwebcontent,read“EnablingEditing” (page 41).

SeeAlso

FormoredetailsontheObjective-CWebKitAPI,read:

■ ■ ■

WebKitObjective-CFrameworkReferenceWebKitPlug-InProgrammingTopicsWebKitDOMProgrammingTopics

Thereareothertechnologies,notcoveredinthistopic,thatcanbeusedinconjunctionwiththeWebKitorseparatelytosolverelatedproblems.

RefertothisdocumentformoredetailsontheURLloadingsystem:

URLLoadingSystemProgrammingGuide

IfyouareaccessingtheWebKitfromaCarbonapplication,refertothesedocuments:

■ ■

WebKitCReference

Carbon-CocoaIntegrationGuide

IfyouarecreatingwebcontentforSafariorDashboard,refertothesedocuments:

■ ■ ■ ■

WebKitDOMProgrammingTopicsWebKitDOMReferenceDashboardTutorialDashboardReference

The/Developer/Examples/WebKitfolderalsocontainsmorein-depthcodeexamples.Otherrelatedtextbookresourcesare:

SeeAlso

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

11

IntroductiontoWebKitObjective-CProgrammingGuide

■ ■ ■

HTMLandXHTML:TheDefinitiveGuide(O’Reilly)CascadingStyleSheets:TheDefinitiveGuide(O’Reilly)JavaScript:TheDefinitiveGuide(O’Reilly)

AlsorefertotheWorldWideWebConsortiumatwww.w3.orgforthelatestinformationonwebstandards.

12

SeeAlso

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

WhyUsetheWebKit?

Manyapplicationsneedtodisplaywebcontentinwindows,whetherit’slivecontentontheweb,orstaticfilesondisk.Someapplicationsarefull-featuredbrowsers,butmoreoftenapplicationsembedwebcontentasaconvenience,asinacustomdocumentsystem.HTMListhedefactostandardrepresentationofdocumentsontheinternet,soit’sonlynaturalthatyouwillwanttodisplaythatcontentwithouthavingtolaunchawebbrowserforeachfileorlinkclickedbytheuser.

Someapplicationsmightwanttodisplaywebcontentondemandbutdon’tnecessarilywanttoparseitorunderstanditsstructuretodisplayit.Applicationslikethismaynotwanttoopenmultiplewindowsorprovidebackandforwardbuttons.TheWebKitprovidesasetofclassestosupportavarietyofwebcontent—fromthemosttrivialembeddedwebcontentapplication(withwebcontentdisplayedinasinglewindow)toafull-featuredwebbrowsersuchasSafari.

TheWebKitdoesthisbyhidingthedetailsofthecomplextaskofloadinganddisplayingwebcontent.Thewebisbasedonaclient-serverarchitecture,inwhichclientsmakeasynchronousrequeststowebserversforpagecontent.Duringthisprocessanynumberofproblemscanoccurnotonlywhentransmittingtheserequestsandresponsesoverthenetworkbutalsowhendisplayingthecontentonceit’sreceivedbyyourapplication.Contentmaybecomplex.Itcancontainmultipleframeelements,multipleMIMEtypes,suchasimagesandmovies.SomeMIMEtypesrequirebrowserplug-instodisplaythem.

Bydefault,theWebKitcoreclassestransparentlyhandleprogrammaticandclientrequests.TheWebKitcreatesallthenecessarymodelandviewclassesusedtorepresentanddisplaytheincomingcontent.Whenauserclicksalink,theWebKitautomaticallyreleasestheoldobjectsandcreatesnewonestohandlethenewpage.TheWebKitviewsaredesignedtohandlemultipleframes,eachwiththeirownscrollbar,andmanyMIMEtypes.Youdonotneedtoimplementcustomviewsforyourapplicationtodisplaywebcontentinyourapplication.

Ontheotherhand,ifyouareimplementingacustom,full-featuredbrowserorotherinternetapplication,youcanextendtheWebKittohandlethedetailsofclientrequests,frameandresourceloading,windowoperations,anddownloading.Youdothisbyimplementingdelegateobjects.TheWebKitprovidesanumberof“hooks”allowingapplicationstocustomizetheuserinterface.Forexample,youcanspecifythemenuitemsthataredisplayedwhentheuserclicksaparticulartypeofresource.YoucanalsoimplementyourowndocumentmodelsandviewstohandlespecificMIMEtypes.Becauseofthisextensibility,theWebKitcanbeusedtodevelopsomeinnovativeinternetapplications.

13

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

WhyUsetheWebKit?

14

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

CoreWebKitClasses

Understandingtheobject-orienteddesignofthecoreWebKitclassesisfundamentaltounderstandinghowtheWebKitworks.Youcandisplaywebcontentinasinglewindowbyfollowingafewsimplesteps.Normally,toembedwebcontentinyourapplicationyousimplycreateaWebViewobject,placeitinawindow,andsendaloadrequestmessage.However,ifyouwanttodosomethingmorecomplex—forexample,customizetheuserinterface,usemultiplewindows,orimplementanyotherbrowser-likefeatures,suchasbackandforwardbuttons—youwillwanttounderstandbetterhowtheWebKitclassesworktogethertoloadanddisplaywebcontent.

Important: Theobject-orienteddesigndiagramsinthisarticlearemeanttoshowatahighlevelhowtheclassesrelatetoeachother.Thesediagramsarenotintendedtoshowinstancevariables.

FrameModelandViewClasses

TheWebKitlooselyfollowsamodel-view-controllerparadigm—someobjectsrepresentview-controllersthatdisplaywebcontent,andotherobjectsrepresentmodelsthatencapsulatewebcontent.

WebViewisthecoreviewclassintheWebKit.WebViewobjectsmanageinteractionsbetweenWebFrameViewobjectsandWebFrameobjects.Toembedwebcontentinyourapplication,youcreateaWebViewobject,attachittoawindow,andaskitsmainframetoloadaURL.ThemostcommonexampleofwebcontentisasingleframecontainingmultipleMIMEtypes.TheWebKitalsofullysupportsHTMLfilescontainingcompoundframes.

Forexample,supposeawebpagecontainsaframewithtwochildrenframes,asillustratedinFigure1 (page16).Toloadthispage,yousendarequesttothemainframeofaWebView,aninstanceofWebView.Themainframeinitiatesaclientrequest.Whileitreceivestheserverresponse(thatis,loadsthepagecontent),themainframecreatesWebFrameobjectstoencapsulatethecontentcontainedineachframeelement.AhierarchyofWebFrameobjectsisusedtomodelanentirewebpage,wheretherootiscalledthemainframe.

FrameModelandViewClasses

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

15

CoreWebKitClasses

Figure1WebViewandWebFrameViewobjects

ViewsaWebViewmainFrameModels

aWebFrameViewaWebFrameViewaWebFrameparentchildrenframeViewaWebFrameparentaWebFrameViewaWebFrameViewAsthecontentforeachWebFrameobjectisloaded,acorrespondingWebFrameViewobjectiscreatedto

displaythatcontent.TheseWebFrameViewobjectsareattachedtotheWebView’sviewhierarchy.Therefore,thereisaparallelhierarchyofWebFrameViewobjectsusedtorenderanentirepage.Inthishierarchy,theWebViewobjectisnotonlyacontrollerobjectbutalsotherootview.ThedetailsoftheviewhierarchyarenotshownbecausetheyareprivatetotheimplementationoftheWebKitandmaychangeinthefuture.Fortunately,youdonotneedtocreatethesemodelandviewobjectsdirectly.TheWebKitcreatestheseobjectsautomaticallywheneverpagesareloaded,eitherprogrammaticallyorwhentheuserclicksalink.

DataModelandViewClasses

Oncetheframehierarchiesarecreated,theactualcontentforeachframeneedstobeloadedanddisplayed.SincewebpagescancontaindifferentMIMEtypes,theWebKitimplementsdifferentmodelsandviewstodisplaythem.TheWebKitautomaticallyloadsanddisplaysmostofthecommondocumenttypes(forexample,HTML,XML,plaintext,images,andQuickTimemovies).TheWebKitselectstheappropriatedatamodelandviewobjectbasedonthedocument’sMIMEtype.Infact,theWebKitdesignisextensible,allowingyoutocreateyourowndatamodelsandviewsforspecificMIMEtypes.

Figure2 (page 17)illustratestherelationshipbetweenWebFrame,WebDataSource,documentrepresentation,anddocumentviewobjects.ForeachWebFrameobject,there’soneWebDataSourceobjectthatloadsthecontentforthatframe.ForeachWebDataSourceobject,there’sonedocumentrepresentationobject,conformingtotheWebDocumentRepresentationprotocol,thatencapsulatesthedataforaspecificMIMEtype.Foreachdocumentationrepresentationobject,there’sadocumentviewobject,conformingtothe

16

DataModelandViewClasses

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

CoreWebKitClasses

WebDocumentViewprotocol,thathandlesthedisplayofthatdata.ThedocumentviewobjectiscontainedinthecorrespondingWebFrameViewobject(forexample,thedocumentviewofascrollviewcontainedinaWebFrameViewobject).Again,thedetailsoftheviewhierarchyarenotshownbecausetheyareprivatetotheimplementationoftheWebKit.Figure2

ViewsaWebViewmainFrameWebFrameandWebDataSourceobjects

Models

aWebFrameViewaWebFramedataSourceframeViewaWebDataSourcerepresentationaWebDocumentViewaWebDocumentRep.Becausedocumentrepresentationandviewobjectsareseparate,youcanhavemultiplemodelsandviewsofaMIMEtype,andextendtheWebKitbydefiningyourown.Onceadatasourceiscommitted(thefirstbyteofdatahasarrived),theWebKitselectsanappropriatedocumentrepresentationanddocumentviewobjectbasedontheMIMEtypeofthedatasource.TheWebKitalreadysuppliesthemodelandviewobjectsformostofthecommonMIMEtypes.IfaMIMEtypeisnotsupported,youcansupplyyourownmodelandviewobjectstohandlethattype,andregisterthemwiththeWebViewclass.Youcanevenreplacethedefaultmodelandviewobjects,althoughthat’snotrecommended.

Again,youdonothavetocreateanyoftheseobjectsdirectly—theyareautomaticallycreatedwhenapageisloaded.

Provisionalvs.CommittedDataSources

Whenyousendarequesttoloadawebpage,youreceiveanasynchronousresponsebecausetherequestisbeingsenttoanotherprocessonanothermachineoverthenetwork.Becauseofthis,theWebKitneedstohandlethestateofitsobjectsbetweenthetimearequestisinitiatedandthefirstbyteofdataarrives.WhenusingtheWebKityoushouldbeawareofthetransitionalstateoftheWebKitdatasourceobjects.

Provisionalvs.CommittedDataSources

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

17

CoreWebKitClasses

Inadditiontorequestsbeingasynchronous,manyerrorscanresultfromrequestingwebcontentoverthenetwork.Forexample,therecanbenetworkfailures,badURLstrings,corruptedcontent,andnoavailableplug-ins.Or,youmayinitiatealoadrequestbutfindtheresponseslow,ordelayed(thecontenttricklesin).Forexample,atypicalstaticwebsitelookssomethingliketheoneinFigure3 (page 18).Clientrequests,conformingtotheHTTPprotocol,originateattheuser’swebbrowser.Theserequestsaresentoverthenetworktothewebserver,whichanalyzestherequestandselectstheappropriatewebpagetoreturntotheclientbrowser.ThiswebpageissimplyatextfilethatcontainsHTMLmarkup.UsingtheHTMLcommandsembeddedwithinthefilereceivedfromthewebserver,thebrowserrendersthepage.Figure3

Typicalwebsite

WebbrowserWebbrowserWebbrowserHTTPWeb serverHTMLpagesIntheWebKit,clientloadrequestsareasynchronous.Tohandlethestateofobjectsduringthetimearequestisinitiatedandcontentarrives,theWebKitcreateswhatiscalledaprovisionaldatasource.Thedatasourceisprovisionalbecauseitisn’tknownyetwhetherthepagewillloadsuccessfully.Anyexistingdatasourceforapageremainsvaliduntiltheprovisionaldatasourceisvalidated.ThefirsttimeaWebFrameobjectisloadedthere’snoexistingdatasourceandablankpageisdisplayed.

Adatasourcebecomescommittedassoonasthefirstbyteofdataarrives.Iftheprovisionaldatasourcebecomesinvalidduetosomeerror,itnevertransitionstoacommitteddatasource.Whenadatasourceiscommitted,anappropriateddocumentrepresentationanddocumentviewiscreatedfortheWebFrameobject.

NotethatthedefaultWebKitbehaviordoesnothingifaloadrequestfails.Therefore,youneedtoimplementWebViewdelegatestohandleloaderrors(forexample,todisplayorlogamessage).

WebViewDelegates

YoucustomizethebehavioroftheWebKitbyimplementingWebViewdelegatesthatinterceptrequestandresponsemessages,andmakepolicyanduserinterfacedecisions.WebViewusesamultipledelegatemodelbecausetherearesomanyaspectsoftheWebKitbehaviorthatyoucancustomize.Andforlargeapplications,itmakessensefordifferentobjectstohandlethedifferentsetsofdelegatemessages.Ofcourse,youcanalwaysimplementjustonedelegatetohandlealltheseareas.WebViewobjectshavefourdelegates:

Frameloaddelegate—interceptsframe-levelrequestandresponsemessagestotracktheprogressanderrorsthatmightresultinloadingawebpage(seetheWebFrameLoadDelegateinformalprotocol).

18

WebViewDelegates

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

CoreWebKitClasses

Resourceloaddelegate—interceptsresource-levelrequestandresponsemessagestotracktheprogressanderrorsthatmightresultinloadingaresource(seetheWebResourceLoadDelegateinformalprotocol).Userinterfacedelegate—controlstheopeningofnewwindows,augmentsthedefaultmenuitemsdisplayedwhentheuserclicksonelements,andmakesotherwindowandcontroluserinterfacedecisions(seetheWebUIDelegateinformalprotocol).

Policydelegate—modifiesthepolicydecisionsthataremadewhenhandlingURLsorthedatatheyrepresent(seetheWebPolicyDelegateinformalprotocol).

Becauseallthedelegatesuseinformalprotocols,youcansetthedelegatesandimplementthedelegatemethodsyouwant.Ifyoudon’timplementadelegatemethod,theWebKitusesadefaultimplementation.Forexample,bydefault,errormessagesarenotreported,andnewwindowsarenotopenedwhenalinkisclickedthatresultsinanewwindowrequest.IftheWebKitcannotreachaURL,yourapplicationwindowdisplaystheoldcontent,whichmaybeablankpage.Youtypicallyimplementaframeloaddelegatetohandlethesetypesoferrors.

WebViewDelegates

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

19

CoreWebKitClasses

20

WebViewDelegates

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

SimpleBrowsing

BywritingjustafewlinesofcodeusingtheWebKit,youcanembedwebcontentinyourapplicationandenableyouruserstonavigatetheweb.

ThecodeexamplebelowassumesyoualreadyhaveaWebViewobjectinsideawindowthatrepresentsthewebpage.YoucancreateaWebViewobjectandattachittoawindoweitherprogrammaticallyorbyusingInterfaceBuilder.UsingInterfaceBuilder,dragaWebViewfromtheLibraryintoawindow.YoushouldalsoconnecttheWebViewobjecttoanoutletsothatyoucansendmessagestoitprogrammatically.

Next,youloadawebpagebysendingaloadRequest:messagetothemainframeofyourWebViewobject,asinthisexample:

[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlText]]];

Here,webViewisaninstanceofWebViewandurlTextisavalidURLaddresssuchas

http://www.apple.com.Youcandothisafterthenibfileisloaded,sothatyourWebViewobjectdisplaysadefaultpage.

Whenyourunyourapplicationyou’llnoticethattheURL(ifitisvalid)issuccessfullydisplayedinthewindowandmostlinksarefollowedautomaticallywhenclicked.Contentthatcontainsmultipleframesisautomaticallyhandled.TheWebKitdoesthisbycreatingahierarchyofWebFrameViewandWebFrameobjectstohandleframecontent—evencontentthatcontainsQuickTimemovies,JavaScript,orFlashmoviesworks.

Eventhoughnavigatingworks,thissimpleexampledoesn’tcontainmanyofthefeaturesyouwouldexpectinawebbrowser—namely,atextfieldfortypinginURLs,backandforwardbuttons,ahistorymenu,multiplewindows,andstatusorerrormessages.YoucanaddsomeofthesefeaturesbyassigningdelegatestoyourWebViewobjectandimplementingdelegatemethods.Becausethedelegatemethodsareinformalprotocols,youcanchoosewhichmethodsyouwanttoimplement.

21

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

SimpleBrowsing

22

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

MultipleWindows

Ifyouarebuildingasimplebrowserapplication,you’llwanttoallowtheusertoopenmultiplewindowsandtypeinURLs.Youalsoneedtomakesomepolicydecisionsabouthowtohandlenewwindowrequests.

OpeningWindows

YoucanimplementmultiplewindowsinaWebKitapplicationeasilybybeginningwithaCocoadocument-basedarchitectureasfollows:1.

UsingXcode,createadocument-basedCocoaapplication.Yournewprojectfilewillalreadycontaintheneededclassesandinterfacefilestosupportmultiplewindows(namelyMyDocument.h,MyDocument.m,andMyDocument.nib).

AddtheWebKitframeworkstoyourproject.

OpenMyDocument.nibusingInterfaceBuilderanddragaWebViewfromtheCocoa—GraphicsViewspalettetoyourdocumentwindow.

CreateawebViewoutletinMyDocument.handreadthefileintoInterfaceBuilder.ConnectthewebViewoutletoftheFile’sOwnertotheWebViewobjectyoucreatedinthepreviousstep.AddcodetoMyDocument.mtoloadadefaultpage.YoucanaddthiscodefragmenttothewindowControllerDidLoadNib:method:

NSString *urlText = [NSString stringWithString:@\"http://www.apple.com\"];[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlText]]];

2.3.4.5.

6.Buildandrunyourapplication.

Whenyourunyourapplicationyoushouldseeawindowopendisplayingwebcontent.YoucanalsoopenmultiplewindowsbyselectingNewfromtheFilemenu.ThisexampledemonstratesmultipleWebViewobjectsindependentlydisplayingwebcontent.

EnteringURLs

IfyouwantausertotypeinherownURL,addatextfieldtothewindowandmakeanewloadrequesteverytimetheuserentersanewURL.Herearethestepsyoufollow:1.

AddatextfieldtothewindowinMyDocument.nib.

OpeningWindows

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

23

MultipleWindows

2.3.

AddatextFieldoutletandaconnectURL:actiontoMyDocument.h.ReadinthechangestoMyDocument.hfromInterfaceBuilder.

InInterfaceBuilder,makeaconnectionfromthetextfieldyoucreatedtothetextFieldoutletoftheFile’sOwnerandsettheactiontoconnectURL:.ThismethodisinvokedwhentheuserentersinanewURL.

ImplementtheconnectURL:methodtoloadtheURLtypedinbytheuser:

- (IBAction)connectURL:(id)sender{

[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[sender stringValue]]]];}

4.

5.Buildandrunyourapplication.

NowwhenyouenteranewURLinthetextfield,anewpageisloaded.

HandlingNewWindowRequests

Bydefault,ifyouclickalinkthatrequestsanewwindowbeopenedtodisplaythecontentofthatlink,nothinghappens.Ifyouwanttochangethisbehavior,yourapplicationneedstomakeapolicydecisionaboutnewwindowrequests.YouneedtoimplementaWebUIDelegateobjecttohandlethiscase.Again,implementthedelegatemethodsyouwant.Herearethestepstofollow:1.

SetthedelegateafterMyDocument.nibisloaded.IfyouhaveaCocoadocument-basedapplication,thenyoucanaddthiscodetoMyDocument’swindowControllerDidLoadNib:method:

[webView setUIDelegate:self];

2.

Itisgoodpracticeforbrowser-likeapplicationstosetthegroupnameofWebViewobjectsaftertheyareloadedfromanibfile.Otherwise,clickingonsomelinksmayresultinmultiplenewwindowrequestsbecausetheHTMLcodeforalinkmightnotusethesameframename.Thegroupnameisanarbitraryidentifierusedtogrouprelatedframes.Forexample,youcansetthegroupnameasfollows:

[webView setGroupName:@\"MyDocument\"];

3.

ImplementthewebView:createWebViewWithRequest:delegatemethodtocreateawindowcontainingawebview,andloadtherequest:

- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request{

id myDocument = [[NSDocumentController sharedDocumentController] openUntitledDocumentOfType:@\"DocumentType\" display:YES]; [[[myDocument webView] mainFrame] loadRequest:request]; return [myDocument webView];}

4.

ImplementthewebViewShow:method,whichisinvokedimmediatelyafterwebView:createWebViewWithRequest:,todisplaythewindow:

- (void)webViewShow:(WebView *)sender

24

HandlingNewWindowRequests

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

MultipleWindows

{

id myDocument = [[NSDocumentController sharedDocumentController] documentForWindow:[sender window]]; [myDocument showWindows];}

5.Buildandrunyourapplication.

Now,whenyouclickalinkthatrequestsanewwindow,anewwindowiscreatedtodisplaythecontentofthatlink.Thisisjustoneexampleofmanydecisionsyourapplicationcanmakeaboutpoliciesandthebehavioroftheuserinterface.YouusetheotherWebUIDelegatemethodsandotherWebViewdelegatestomodifythebehavior.

HandlingNewWindowRequests

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

25

MultipleWindows

26

HandlingNewWindowRequests

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

LoadingPages

Astheusernavigatesfrompagetopageinyourembeddedbrowser,youmaywanttodisplaythecurrentURL,loadstatus,anderrormessages.Forexample,inawebbrowserapplication,youmightwanttodisplaythecurrentURLinatextfieldthattheusercanedit.

SequenceofFrameLoadDelegateMessages

Asawebpagegoesthroughtheprocessofloading,theWebKitsendsaseriesofmessagestotheframeloaddelegate.Theexactsequencedependsonthepagecontent.SinceWebFrameLoadDelegateisaninformalprotocolamessageisnotsenttothedelegateunlessitrespondstoit.Forexample,thesequenceofmessagesforasimplepagethatcontainsatitleandloadssuccessfullymightbe:1.2.3.4.

webView:didStartProvisionalLoadForFrame:—invokedatthestartofaload.

webView:willCloseFrame:—invokedwhentheWebViewisdonewiththeoldframeobjects(passed

asanargument)justbeforetheyarereleased.

webView:didCommitLoadForFrame:—invokedwhenadatasourcetransitionsfromprovisionalto

committed.

webView:didReceiveTitle:forFrame:—invokedwhentheframetitlehasarrivedwhichisanytime

afterthedatasourceiscommittedandbeforetheloadisfinished.Thismethodcanbeinvokedmultipletimes.5.

webView:didFinishLoadForFrame:—invokedwhenallthedatahasarrivedforadatasource

Mostly,youimplementtheabovedelegatemethodstodisplayinformationaboutthewebpageandloadstatus.YoumightimplementwebView:willCloseFrame:ifyourapplicationmaintainsreferencestothepreviouspagecontent.

However,loadingapageisacomplicatedprocess,soyouhavetoanticipatethatsomeclientrequestswillfail.Becauseaclientrequestisasynchronousoverthenetwork,thenewpagemaynotloadimmediatelyanderrorsmayoccurwhenloading.Typically,thedefaultimplementationdoesnothing(displaysablankview)ifanerroroccurs;therefore,yourapplicationmaywanttodisplayerrormessagesinstead.Thesedelegatemethodscanbeimplementedtohandleerrors:

webView:didFailProvisionalLoadWithError:forFrame:isinvokedwhenanerroroccurred

beforeanydatawasreceived.TypicallyinvokediftheURLisbadorthenetworkfailedtodelivertherequest.

webView:didFailLoadWithError:forFrame:isinvokedwhenacommitteddatasourcefailstoload.

SequenceofFrameLoadDelegateMessages

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

27

LoadingPages

Messageswillalsobesenttothedelegateifthepagecontentcontainsserverredirects,orthescrollpositionwithinaframechanges(thiscanoccurwhentheuserclicksananchorwithinaframe).SeeWebFrameLoadDelegateformoredetailsontheseandotherdelegatemethods.

TestingfortheMainFrame

TheframeloaddelegateisnotifiedifalocationchangesforanyframeintheWebFramehierarchy.Usually,youupdatethedisplayonlyforchangestothemainframe.Forthatreason,yourcodeshouldalwaystesttoseewhetherthewebframe,passedasanargumenttothedelegatemethod,isthemainframe,asinthisexample:

// Only report feedback for the main frame. if (frame == [sender mainFrame]){ [... }

DisplayingtheCurrentURL

Whenevertheuserclicksonalinkinawebpage,theURLchangesandanewpageisloaded.Bydefault,yourapplicationisnotnotifiedofthischange.Ifyouwanttokeeptrackofthecurrentpage,youneedtoimplementsomedelegatemethods,specificallyaframeloaddelegateforyourWebViewobject.Because

WebFrameLoadDelegateisaninformalprotocol,youneedtoimplementonlythedelegatemethodsyouwant.

Forexample,theuserclicksalinkandyouwanttoupdatethetextfieldtodisplaythecurrentURL.YoudothisbyimplementingthewebView:didStartProvisionalLoadForFrame:delegatemethodasinthisexample:

- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame{

// Only report feedback for the main frame. if (frame == [sender mainFrame]){

NSString *url = [[[[frame provisionalDataSource] request] URL] absoluteString];

[textField setStringValue:url]; }}

DisplayingthePageTitle

Ifyouwanttodisplaythepagetitle,implementthewebView:didReceiveTitle:forFrame:delegatemethod.Forexample,youcandisplaythepagetitleonthewindow,asinthisexample:

- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame{

28

TestingfortheMainFrame

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

LoadingPages

// Report feedback only for the main frame. if (frame == [sender mainFrame]){

[[sender window] setTitle:title]; }}

Similarly,youcanimplementthewebView:didReceiveIcon:forFrame:delegatemethodifyouwanttodisplaythepageicon.

DisplayingLoadStatus

BesidesimplementingthewebView:didStartProvisionalLoadForFrame:methodtodisplaythepagetitle,youcanalsouseittodisplaythestatus,forexample,“Loading.”Rememberthatatthispointthecontenthasonlybeenrequested,notloaded;therefore,thedatasourceisprovisional.Similarly,implementthewebView:didFinishLoadForFrame:,

webView:didFailProvisionalLoadWithError:forFrame:and

webView:didFailLoadWithError:forFrame:delegatemethodstoreceivenotificationwhenapage

hasbeenloadedsuccessfullyorunsuccessfully.Youmightwanttodisplayamessageifanerroroccurred.

DisplayingLoadStatus

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

29

LoadingPages

30

DisplayingLoadStatus

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

LoadingResources

Yourapplicationcanalsomonitortheprogressofloadingcontent—thatis,theprogressofloadingindividualresourcesonapage.Aresourceisanydataonapagethatisloadedseparately,suchasimages,scripts,stylesheetsandwebpagescontainedinframes.Awebpagecanincludemultipleresources,eachhavingtheirownrequestandresponsemessages.Onceapageisrequested,eachresourceforthatpagecanarrive

independentlyandinanyorder.Somemayloadsuccessfully,andothersmaynot.Ifyouwanttobenotifiedoftheprogress,successorfailureofloadingresources,youneedtoimplementaresourceloaddelegateforyourWebViewobject.

SequenceofResourceLoadDelegateMessages

Asaresourcegoesthroughtheprocessofloading,theWebKitsendsaseriesofmessagestotheresourceloaddelegate.Theexactsequencedependsontheresourceandifanerroroccurredduringtheload.SinceWebResourceLoadDelegateisaninformalprotocolamessageisnotsenttothedelegateunlessitrespondstoit.Forexample,thesequenceofmessagesforaresourcethatloadssuccessfullymightbe:1.2.3.4.5.

webView:identifierForInitialRequest:fromDataSource:—invokedbeforeotherdelegate

methodstoreturntheapplication-definedresourceidentifier.

webView:resource:willSendRequest:redirectResponse:fromDataSource:—invokedoneor

moretimesbeforearequesttoloadaresourceissent.

webView:resource:didReceiveResponse:fromDataSource:—invokedoncewhenthefirstbyte

ofdataarrives.

webView:resource:didReceiveContentLength:fromDataSource:—invokedzeroormultiple

timesperresourceuntilallthedataforthatresourceisloaded.

webView:resource:didFinishLoadingFromDataSource:—invokedwhenallthedataforthe

resourcehasarrived.

Iftheresourceloadfailed,thenwebView:resource:didFailLoadingWithError:fromDataSource:isinvokedinsteadofwebView:resource:didFinishLoadingFromDataSource:.Othermessagesperredirectscanarrive,too.SeeWebResourceLoadDelegateforacompletelistofdelegatemethods.

IdentifyingResources

Becauseresourceloaddelegatesmightneedtodistinguishbetweenthedifferentresourcesonapage,aresourceidentifierispassedasoneoftheargumentsofthemessagestodelegates.Theidentifierremainsthesameforeachloadeveniftherequestchanges.Forexample,arequestmaychangeifheadersareadded,theURLiscanonicalized,ortheURLisredirected.

SequenceofResourceLoadDelegateMessages

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

31

LoadingResources

Yourapplicationcanprovidethisidentifierbyimplementingthe

webView:identifierForInitialRequest:fromDataSource:methodtocreateandreturnaresource

identifier.Otherwise,theresourceidentifierpassedtosubsequentdelegatemessageswillnotbeunique.Forexample,thismethodcanreturnasequentialnumber:

- (id)webView:(WebView *)sender

identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource{

// Return some object that can be used to identify this resource return [NSNumber numberWithInt:resourceCount++];}

TrackingResourceLoadProgress

Onereasonforimplementingaresourceloaddelegateistotracktheprogressofindividualresourceloads.Forexample,youcankeeptrackofthenumberofresourcessuccessfullyandunsuccessfullyloadedperpagebyimplementingthefollowingdelegatemethods.Inthisexample,theresourcestatusisdisplayedas“LoadedXofYresources,Zresourceerrors.”EachdelegatemethodbelowincrementstheseX,YandZvalues.Followthesestepstodisplaytheresourceloadstatusmessages:1.

Addtheseinstancevariablestoyourdelegateclass:

int resourceCount;

int resourceFailedCount; int resourceCompletedCount;

2.

ImplementthewebView:resource:willSendRequest:redirectResponse:fromDataSource:methodtoupdatethedisplaywhentheWebKitbeginstoloadaresource.Notethatthismethodalsoallowsyoutoreturnamodifiedrequest.Normallyyoudon’tneedtomodifyit.

-(NSURLRequest *)webView:(WebView *)senderresource:(id)identifier

willSendRequest:(NSURLRequest *)request

redirectResponse:(NSURLResponse *)redirectResponsefromDataSource:(WebDataSource *)dataSource{

// Update the status message [self updateResourceStatus]; return request;}

3.

ImplementtheupdateResourceStatusmethod,invokedinthesamplecodeabove,tousethe

resourceCountinstancevariabletoupdatethedisplay.YouincrementtheresourceCountinstancevariableinthewebView:identifierForInitialRequest:fromDataSource:methodasshownin“IdentifyingResources.”

ImplementthewebView:resource:didFailLoadingWithError:fromDataSource:methodtoincrementthenumberoffailedresourceloadsandupdatethedisplayasin:

-(void)webView:(WebView *)sender resource:(id)identifierdidFailLoadingWithError:(NSError *)errorfromDataSource:(WebDataSource *)dataSource{

4.

32

TrackingResourceLoadProgress

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

LoadingResources

resourceFailedCount++;

// Update the status message [self updateResourceStatus];}

5.

ImplementthewebView:resource:didFinishLoadingFromDataSource:methodtoincrementthenumberofsuccessfulresourceloads,andupdatethedisplayasin:

-(void)webView:(WebView *)senderresource:(id)identifier

didFinishLoadingFromDataSource:(WebDataSource *)dataSource{

resourceCompletedCount++; // Update the status message [self updateResourceStatus];}

6.7.8.

ImplementtheupdateResourceStatusmethodtoupdateyourdisplay.

Also,implementtheframeloadwebView:didStartProvisionalLoadForFrame:delegatemethodtoresetthesevariablesto0whenanewpageloadstarts.Buildandrunyourapplication.

Whenyourunyourapplicationyoushouldseeaprogressmessageshowingthetotalnumberofresourcesperpage,andprogressivelyhowmanyresourcesareloadedsuccessfullyandunsuccessfully.

TrackingResourceLoadProgress

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

33

LoadingResources

34

TrackingResourceLoadProgress

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

PagingBackandForward

AWebViewobjectusesaWebBackForwardListobjecttomaintainalistofvisitedpagesusedtopagebackandforwardtothemostrecentpage.WebViewprovidesmethodstohandletheactionofgoingforwardorbackwardinthislist;therefore,youcaneasilyaddBackandForwardbuttonstoyourapplication.

EnablingandDisablingtheBack-ForwardList

Bydefault,everyWebViewobjectmaintainsitsownback-forwardlistobject.Thereissomeoverheadinmaintainingthislist.Ifyoudon'twanttousethisfeature,sendasetMaintainsBackForwardList:messagetoyourWebViewobjectasin:

[webView setMaintainsBackForwardList:NO];

Otherwise,historyitems,whichencapsulatevisitedpageinformation,areautomaticallyaddedandremovedfromtheback-forwardlistaswebpagesareloadedanddisplayedinaWebView.Ifyoumaintainaback-forwardlistinyourWebViewobject,thenyoushouldaddsomebuttonstoyouruserinterfacesothatuserscanusethisfeature.

AddingBackandForwardButtons

Youdon'thavetowriteasinglelineofcodetoimplementBackandForwardbuttonsinyourapplication.Followthesestepstoaddthesebuttons:1.2.3.

UsingInterfaceBuilder,addaBackandForwardbuttontoyourwindow.

UsingInterfaceBuilder,connecttheBackandForwardbuttonstotheWebViewobjectbyselecting,respectively,thegoBack:andgoForward:actions.Buildandrunyourapplication.

Whenrunningyourapplication,connecttoaURL,followafewlinks(togeneratesomehistoryitemsinyourback-forwardlist),andthenclicktheBackandForwardbuttons.TheWebKitmaintainstheback-forwardlistforyou,andtheactionmethodsinitiatenewpagerequests.

SettingthePageCache

Youcanuseback-forwardliststomaintainapagecachetoo.Becausepagesinthecachearerenderedquickly,usingthisfeatureimprovestheperformanceoftheback-forwardactionmethods.YoucanturnthisfeatureonoroffbysettingthecachesizeusingtheWebBackForwardListsetPageCacheSize:method.Ifyouset

EnablingandDisablingtheBack-ForwardList

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

35

PagingBackandForward

thepagecachesizeto0,thepagecacheisdisabled;otherwise,thesizeofthecacheislimitedtothenumberofpagesyouspecify.Thedefaultpagecachesizemayvarydependingonyourcomputer’sconfiguration.UsethepageCacheSizemethodtogetthecurrentsetting.

SettingtheCapacity

Youcanalsolimitthecapacityoftheback-forwardlistitselfusingthesetCapacity:method.Settingthecapacityaffectsonlythenumberofhistoryitemsallowedintheback-forwardlist.Itdoesn'taffectthepagecache.Usethecapacitymethodtogetthecurrentsetting.

TheCurrentItem

Ifyoumanipulateaback-forwardlistdirectly,youneedtobeawareofhowitworks.Aback-forwardlistislikeanarraythatcanexpandinboththenegativeandpositivedirections.Historyitemsaretypicallyinsertedintheorderinwhichtheyarevisited.Itemshaveindiceswhicharerelativetothecurrentitem.Thecurrentitemisalwaysatindex0,theprecedingitemisatindex-1,thefollowingitemisatindex1,andsoon.Whenmanipulatingthecontentsofaback-forwardlistbeawarethatsomemethodschangethecurrentitemandthereforetheindicesofallotheritems.ThegoBackandgoForwardmethods,theirequivalentactionmethods,andthegoToItem:methodallchangethecurrentitem.AllotherWebBackForwardListaccessormethodsdonoteffectthecurrentitem.

ManagingState

Iftherearenohistoryitems,ortherearenoitemsprecedingorfollowingthecurrentitem,thenabackorforwardactiondoesnothing.Thereforeyoumightwanttotrackthestateoftheback-forwardlistandenableordisabletheBackandForwardbuttonsaccordingly.

YoucandothisbyimplementingthewebView:didFinishLoadForFrame:delegatemethodtocheckthestateoftheback-forwardlist.SendingcanGoBackandcanGoForwardtotheWebViewobjectreturnsYESifyoucangointhatdirection.Therefore,youmightimplementthewebView:didFinishLoadForFrame:methodasfollows,wherebackButtonandforwardButtonareyourbuttonoutlets:

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame{

// Only report feedback for the main frame. if (frame == [sender mainFrame]){

[backButton setEnabled:[sender canGoBack]];

[forwardButton setEnabled:[sender canGoForward]]; }}

36

SettingtheCapacity

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

ManagingHistory

WebHistoryandWebHistoryItemobjectsareusedtomaintainahistoryofallthepagesauservisits.

WebHistoryItemencapsulatesalltheinformationaboutapagethathasbeenvisited,andWebHistorymaintainsanorderedcollectionofthesehistoryitems.WebHistorydoesn’tjustmaintainalinearlist.Italsokeepstrackofthedaysonwhichauservisitspages.Therefore,youcangroupandpresenthistoryitemstousersbyday.Forexample,youcanusesubmenustogrouphistoryitemsbythelastthreevisiteddays.

SharingHistoryObjects

WebHistoryobjectsarenotautomaticallycreatedbytheWebKit.YouenablethehistoryfeaturebycreatingaWebHistoryobjectandassigningittoyourWebViewobject.

YoucancreateWebHistoryobjectsinoneoftwoways.YoucanassigneachWebViewobjectitsown

WebHistoryobject,oryoucancreateoneWebHistoryobjectthatissharedbyallWebViewobjectsinyourapplicationasin:

// Create a shared WebHistory object

WebHistory *myHistory = [[WebHistory alloc] init]; [WebHistory setOptionalSharedHistory:myHistory];

AddingandRemovingHistoryItems

Likeback-forwardlists,historyitemsareautomaticallyaddedtotheWebHistoryobjectastheusernavigatestheweb.IfanitemwiththesameURLalreadyexistsinthelist,thenitisreplacedwiththeneweritemevenifthepreviousitemwasvisitedonadifferentday.Consequently,iftheuserrevisitsaURLitisalwaysmovedtothetopofthelist.Otherwise,itemsarenotremovedfromthehistorylistunlessyourapplicationexplicitlyremovesthem.

Forexample,youcouldimplementaclearhistoryactionbysendingremoveAllItemstoyourWebHistoryobjectasin:

// Removes all the history items- (IBAction)clearHistory:(id)sender{

[[WebHistory optionalSharedHistory] removeAllItems];}

Afterremovingalltheitems,theremoveAllItemsmethodpostsa

WebHistoryAllItemsRemovedNotificationnotification.TheaddItems:andremoveItems:methodspostsimilarnotifications.Youtypicallyobservethesenotificationstoupdateyourdisplayofhistoryitemsasfollows:

// Observe WebHistory notifications

SharingHistoryObjects

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

37

ManagingHistory

nc = [NSNotificationCenter defaultCenter];

[nc addObserver:self selector:@selector(historyDidRemoveAllItems:)

name:WebHistoryAllItemsRemovedNotification object:myHistory]; [nc addObserver:self selector:@selector(historyDidAddItems:)

name:WebHistoryItemsAddedNotification object:myHistory]; [nc addObserver:self selector:@selector(historyDidRemoveItems:)

name:WebHistoryItemsRemovedNotification object:myHistory];

TheuserInfoattributeofthesenotificationsisanarraycontainingtheaddedorremoveditems.Forexample,youmightimplementthehistoryDidAddItems:methodtoaddacorrespondingmenuitemtoyourHistorymenuforeachnewhistoryitemintheuserInfoarray.

LoadingaHistoryItem

Oncetheuserhastheabilitytoselectahistoryitemtoload,youneedtoimplementanactiontoperformtheload.YousendloadRequest:tothemainframeoftheappropriateWebViewobject,passingtheselectedWebHistoryItem’sURLstringastheargument.ThefollowingexampleassumeshistoryItemistheselectedWebHistoryItemobject:

- (void)goToHistoryItem:(id)historyItem{

// Load the history item in the main frame

[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[historyItem URLString]]]];}

SavingandLoadingHistoryObjects

UnlikeWebBackForwardListobjects,WebHistoryobjectscanbepersistent—thatis,theycanbeloadedfromandsavedtoawritableURL.YousendloadFromURL:error:toaWebHistoryobjecttoloadhistoryitemsfromareadableURL,andyousendsaveToURL:error:toaWebHistoryobjecttosavehistoryitemstoawritableURL.

38

LoadingaHistoryItem

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

MakingPolicyDecisions

YoucanmakedecisionsaboutwhatwebcontenttodisplayinaWebViewbyimplementingapolicydelegatethatconformstotheWebPolicyDelegateprotocol.

Theprotocolisveryflexible,allowingyoutomakeawiderangeofpolicydecisions.Forexample,youcanimplementapolicydelegatetologURLrequests,checkforpatternsyoumightnotpermit,blockcertainwebsites,blocktypesoffiles,andevenblockIPaddresses.Theprotocolprovidesthehooksforyoutointerceptrequests—youimplementtheactualpolicydecisions.

Forexample,followthesestepstomodifytheMiniBrowserapplicationlocatedin/Developer/Examples/WebKittoignoreselectedURLs:1.2.

OpenMyDocument.nibusingInterfaceBuilderandsettheWebView’spolicyDelegateoutlettoFile’s Owner(theMyDocumentinstance).

ImplementwebView:decidePolicyForNavigationAction:request:frame:decisionListener:tofiltertheURLrequests.Inthisexample,URLrequestswithhostnamesendingincompany.comareignored.

- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation

request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener {

NSString *host = [[request URL] host]; if ([host hasSuffix:@\"company.com\"]) [listener ignore]; else

[listener use];}

39

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

MakingPolicyDecisions

40

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

EnablingEditing

BysettingtheeditableattributeofaWebViewobjectyoucanmakeallthewebcontentdisplayedinthatvieweditable.EditingthecontentwillchangetheunderlyingDocumentObjectModel(DOM).However,settingtheeditableattributetoYESdoesnotmodifytheeditingattributesoftheDOMobjects—theWebViewattributesettingoverridestheDOMattributes.

Forexample,tomodifytheMiniBrowserapplicationlocatedin/Developer/Examples/WebKit,settheeditableattributetoYESafterthenibfileisloadedinMyDocument’swindowControllerDidLoadNib:methodasfollows:

- (void)windowControllerDidLoadNib:(NSWindowController *) aController{

[super windowControllerDidLoadNib:aController]; ...

// Set editable flag

[webView setEditable:YES];}

Nowwhenyoubuildandruntheapplication,youcanadd,delete,andmodifytheHTMLcontentdisplayedinaWebViewobject.See“SavingandLoadingWebContent” (page 43)forhowtogettheHTMLsourcefromtheDOM.

41

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

EnablingEditing

42

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

SavingandLoadingWebContent

AftertheusereditsthecontentofaWebView,youneedsomewaytoaccessthemodifieddocument.InaCocoadocument-basedapplication,youtypicallyallowtheusertosaveandloadthedocument.

Forexample,intheMiniBrowserapplicationlocatedin/Developer/Examples/WebKit,youwould

implementMyDocument’sdataRepresentationOfType:methodtoreturnanNSDatarepresentationoftheHTMLsource.ThenimplementMyDocument’sloadDataRepresentation:ofType:methodtotransformanNSDatarepresentationtoHTMLsourceandloaditintotheWebView.FollowthesestepstoaddsavingandloadingtotheMiniBrowserapplication.1.

FirstaddavariableandaccessorstoMyDocumenttostoretheHTMLsource.ModifyMyDocument.hasfollowsandimplementthecorrespondingaccessormethodsinMyDocument.m:

@interface MyDocument : NSDocument{

...

// Editing Support NSString *_source;}...

// Editing Support- (NSString *)source;

- (void)setSource:(NSString *)webContent;@end

2.

Next,implementMyDocument’sdataRepresentationOfType:methodtogettheHTMLsourcefromtheDOM,setthe_sourceinstancevariable,andconvertittoanNSDataobjectasfollows:

- (NSData *)dataRepresentationOfType:(NSString *)aType{

if (![aType isEqualToString:HTMLDocumentType]) return nil;

[self setSource:[(DOMHTMLElement *)[[[webView mainFrame] DOMDocument] documentElement] outerHTML]];

return [[self source] dataUsingEncoding:NSISOLatin1StringEncoding];}

3.

ThenimplementMyDocument’sloadDataRepresentation:ofType:methodtotransformtheNSDataobjecttoHTMLsourceasfollows:

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType{

if (![aType isEqualToString:HTMLDocumentType]) return NO;

[self setSource:[[[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding] autorelease]];

[[webView mainFrame] loadHTMLString:[self source] baseURL:nil];

43

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

SavingandLoadingWebContent

return YES;}

44

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

ModifyingtheCurrentSelection

ThereareanumberofWebVieweditingmethodsthatallowyoutomodifythecurrentselection.Forexample,youcanreplacethecurrentselectionwithplaintextasfollows:

[webView replaceSelectionWithText:@\"SomeString\"];

Youcanreplacethecurrentselectionwithastyledstringasfollows:

NSString *markupString = [NSString stringWithFormat:

@\"%@\ @\"SomeString\"];

[webView replaceSelectionWithMarkupString:markupString];

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

45

ModifyingtheCurrentSelection

46

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

ChangingEditingBehavior

YoucancontroloraugmentusereditingbyimplementingaWebVieweditingdelegate,anobjectthatconformstotheWebEditingDelegateprotocol.Aneditingdelegatemayreceiveshouldmessagesbeforeordidmessagesafteraneditingaction.Typically,youimplementaneditingdelegateifyouwanttochangethedefaulteditingbehavior.

ShouldMethods

Youimplementshouldmethodsifyouwanttocontrolusereditingactions—thesemessagesareinitiatedbyauseractionnotbysimplyinvokingWebVieweditingmethodsprogrammatically.TheshouldmethodsareoftheformwebView:should...andmayreturnYEStopermitanactionorNOtodisallowanaction.Optionally,thedelegatecantakeanalternativeactionandreturnNOsothesenderdoesn’ttakeadditionalaction.

Forexample,youcancontroltheinsertionoftextbyimplementingthe

webView:shouldInsertText:replacingDOMRange:givenAction:method.Inthisexample,theuser

mayusetheShiftkeytoalteraninsertion:

- (BOOL)webView:(WebView *)webView shouldInsertText:(NSString *)text

replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action{

if ([self shiftKeyIsDown]) {

NSString *string = [NSString stringWithFormat:@\"Big-%@\ [webView replaceSelectionWithText:string]; DOMRange *range = [webView selectedDOMRange]; [range collapse:NO];

[webView setSelectedDOMRange:range affinity:NSSelectionAffinityUpstream]; return NO; }

return YES;}

DidMethods

AWebVieweditingdelegateisautomaticallyregisteredtoreceivenotificationofeditingactions.TheWebVieweditingdelegateissentawebViewDid...notificationmessage—wheresenderisaWebViewobject—aftertheactiontakesplace.

ShouldMethods

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

47

ChangingEditingBehavior

48

DidMethods

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingUndoWhenEditing

Youcanundohigh-levelwebcontenteditingoperations—editsmadeprogrammaticallyandbythe

user—withoutwritinganyadditionalcode.However,ifyouprogrammaticallymodifytheDocumentObjectModel(DOM),youneedtowriteadditionalcodetomakethoseoperationsundoable.Forexample,youcanundohigh-leveloperationsprogrammaticallyasfollows:

// Delete content

[webView deleteSelection]; // Restore it

[[webView undoManager] undo];

However,it’snotassimpletoundoaDOMoperation.It’snotgoodenoughtoreturntheDOMtoanequivalentstate—itmustbeexactlyasitwasoriginally.Forexample,youcan’tjustundodeletedtextbycreatinganewnodeandinsertingitintheoldlocation.Thelinksbetweenthenodesneedtobeexactlyastheywerebeforedeletingthetext.

Oneapproachistoretainthedeletedobjectssothattheyarenotreleased.Forexample,youmightretainadeletedDOMnodebeforeremovingitfromthetreeasfollows:

DOMNode *containerNode = [self containerNode]; // Must retain before removing from the document deletedNode = [[containerNode lastChild] retain]; // Now remove

[containerNode removeChild:deletedNode];

// Make undoable

[[webView undoManager] registerUndoWithTarget:self selector:@selector(undoAction) object:self];

YoucanthenimplementundoActiontoreturntheDOMtoitsoriginalstate:

- (void)undoAction{

DOMNode *containerNode = [self containerNode]; // Put the node back

[containerNode appendChild:deletedNode];

// Make redoable

[[webView undoManager] registerUndoWithTarget:self selector:@selector(redoAction) object:self];}

TheredoActionsimplydeletestheretainednodeagainasfollows:

49

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingUndoWhenEditing

- (void)redoAction{

DOMNode *containerNode = [self containerNode]; // Take node out again

[containerNode removeChild:deletedNode];

// Make undoable

[[webView undoManager] registerUndoWithTarget:self selector:@selector(undoAction) object:self];}

50

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingtheDocumentObjectModelfromObjective-C

TheDocumentObjectModelAPIimplementstheLevel2DocumentObjectModel(DOM)specification,developedbytheWorldWideWebConsortium.Thisspecificationprovidesaplatformandlanguage-neutralinterfacethatallowsprogramsandscriptstodynamicallyaccessandchangethecontent,structureandstyleofadocument—usuallyHTMLorXML—byprovidingastructuredsetofobjectsthatcorrespondtothedocument’selements.

TheintentionoftheDOMObjective-CAPIistoconformto—ascloseastechnicallypossible—theW3CDOMspecification.Therefore,standardCocoaconventionssuchasmethodnaming,argumenttitling,andexceptionhandlingmaynotbereflectedinthisAPI.Followingafewconventionsdiscussedinthisarticle,youcanderivetheDOMObjective-CAPIfromthespecification.ThisarticlealsodiscussesthedifferencesbetweentheDOMspecificationandDOMObjective-CAPI.

TheWebKitextensionstotheDOMspecificationarecoveredin“UsingtheDocumentObjectModelExtensions” (page 55).RefertoWebKitDOMProgrammingTopicsformoreinformationontheDOMspecification.

InterpretingtheDOMSpecification

TheDOMspecificationiswritteninInterfaceDefinitionLanguage(IDL)filesavailableattheW3Cwebsite.Linkstothemhavebeenprovidedinthelistthatfollows.TheObjective-CDOMAPIisdefinedbyheaderfilesintheWebKitframework,locatedat:/System/Library/Frameworks/WebKit.framework.HereisalistoftheDOMspecification’sIDLfilesandtheirassociatedObjective-Cheaderfiles:W3CDOMIDLfileWebKitDOMheaderfiledom.idlviews.idlevents.idlhtml2.idlstylesheets.idlcss.idltraversal.idlranges.idl

DOMCore.hDOMViews.hDOMEvents.hDOMHTML.h

DOMStylesheets.hDOMCSS.hDOMTraversal.hDOMRange.h

InterpretingtheDOMSpecification

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

51

UsingtheDocumentObjectModelfromObjective-C

TwootherheaderfilesareincludedintheDocumentObjectModelAPI.DOM.hisaconvenienceheaderfilethatmerelyincludesalloftheotherDOMheaderfiles.DOMExtensions.hdefinesadditionsthatarenotspecifiedbytheDOMspecification.UsetheextensionstohelpyourDOMmethodsinteractwiththerestoftheWebKit,andtousesomeoftheWebKit’shigherabilitiessuchasHTMLediting.Moreinformationisavailableinthe“UsingtheDocumentObjectModelExtensions” (page 55)article.

TheinterfacesspecifiedbytheDOMIDLfilesaremappedtoObjective-Cclasses.ThenamesofinterfacesareunchangedwhenthespecificationdoesnotconflictwiththenamespacesofObjective-C,Java,orothercommonlanguages.Forexample,theDOMImplementationinterfaceintheDOMCoreIDLisreflectedbythesamenameintheObjective-CDOMCoreheaderfile.Wherenamespacesconflict,theAPIprefixestheconflictinginterfaceappropriately.Forexample,theDOMCoreIDL’sNodeinterfaceappearsasDOMNodeinitsObjective-Cmapping.

Thisnamingschemealsoextendstoconstants.TheAPIgroupsDOMconstantlistsintoObjective-Cenumtypes,andifanamespaceconflictispresent,theAPIprefixesthemwithanappropriateidentifier.Forexample,theELEMENT_NODEnodetypeconstantisreflectedasDOM_ELEMENT_NODEinObjective-C.

SomenamesspecifiedbytheDOMspecificationmayconflictwithkeywordsorotherreservedwordsinObjective-C.Whenthishappens,theyaregivencustommappingsandtheirObjective-Cnamesmustbeinferredfromtheheadersorfromdocumentation.TheAPIprovidesthecustommappingswithappropriatenames.Forexample,thetwoconflictingidentifiersidandname(bothObjective-Creservedwords)aremappedtoidNameandframeName,respectively,andaccuratelyreflecttheintentofthespecification.EachObjective-Cclassderives,directlyorindirectly,fromtheDOMrootobjectDOMObject.Thisisan

implementationdetailthataccommodatescrosstrafficbetweentheWebKitandtheDOM.ThehierarchyofinterfacesasdefinedbytheW3Cspecificationisalsomaintained.Forexample,DOMDocumentextendsfromDOMNodeinthespecificationaswellasintheAPI.

MethodnamesaremappedintoObjective-Cdirectlyfromthespecificationwithnonamespacetransition.However,methodswithmultipleargumentsintheDOMspecificationdonotspecifylabelsfortheir

arguments—thisbehaviorcarriesonintotheObjective-Cmethods.Forexample,thespecificationdeclaresthismethodprototype:

Node insertBefore(in Node newChild, in Node refChild);

TheObjective-Cversionisnot,asyoumightexpect,changedtosomethinglike:

- (DOMNode *)insertNewChild:(DOMNode *)newChild BeforeOld:(DOMNode *)refChild

TheactualObjective-Cprototypeis:

- (DOMNode *)insertBefore:(DOMNode *)newChild :(DOMNode *)refChild

Asyoucansee,thisvariesfromtypicalCocoamethod-namingconventions.Thisisdoneforanimportantreason—tomatchtheDocumentObjectModelspecificationascloselyaspossible.ButifyouareaCocoadevelopernewtotheDOM,youmayfindthenamingschemeconfusing.

TheAPImapsotherobjectstotheirappropriateequivalents.Forexample,itmapsDOMStringobjectstoNSString.Allothertypes(suchasvoid,boolean,float,andunsigned long)aremappedtotheirrespectiveObjective-Ctypes.AttributeswhicharebothreadableandwritablearealsogivenCocoa-styleget/setaccessormethods.Forexample,theDOMCoreIDLspecifiesthisattribute:

attribute DOMString nodeValue;

52

InterpretingtheDOMSpecification

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingtheDocumentObjectModelfromObjective-C

Objective-Caccessesthisattributeusingthesemethods:

- (NSString *)nodeValue;

- (void)setNodeValue:(NSString *)nodeValue;

HandlingExceptions

TheAPIalsomapsexceptionsfromtheDOMspecificationtoObjective-C.MethodsthatraiseDOMexceptionsalsoraiseObjective-Cexceptions(NSException),butbecauseObjective-CexceptionsarenotpartofamethodinterfaceastheyareintheDOMspecification,theexceptionclassnamesaremappedtostringconstants.ThemainexceptionclassesareraisedasDOMException,DOMEventException,and

DOMRangeException,andcanalertyouwithanynumberofexceptioncodes.SeeDOMCore.h,DOMEvents.h,andDOMRange.hforthecodes.

HandlingExceptions

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

53

UsingtheDocumentObjectModelfromObjective-C

HandlingExceptions

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingtheDocumentObjectModelExtensions

TheWebKitprovidesextensionstotheDocumentObjectModel(DOM)thatprovideadditionalfunctionalitynotspecifiedbytheW3Crecommendations.TheDOMextensionsarepartoftheDOMObjective-CAPIbutarenotpartoftheW3CDOMspecification(andnotimplementedinJavaScript).

TheextensionscurrentlyprovideadditionstoDOMHTMLElement,DOMDocument,andDOMRGBColor.AnadditionalDOMHTMLElementsubclass,DOMHTMLEmbedElement,providesanObjective-CDOMclassforHTMLembedelements.

Amongtheusefulfeaturesoftheextensionsaretheinner/outerHTMLandtextaccessormethods.GivenanelementblockofHTML(aDOMHTMLElement),youcandynamicallygetandsettheHTMLandtextfromthatblockusingthesemethods:innerTextgetstheinnercontentoftheblockwithoutitsHTMLtags;innerHTMLgetstheinnercontentoftheblock(withitsHTMLtags,butnotitsenclosingtags); outerHTMLgetstheentirecontentoftheblock.Forexample,giventhisHTMLblock:

Paragraph 1

Paragraph 2

TheinnerHTMLmethodwillreturn(asanNSString):

Paragraph 1

Paragraph 2

TheinnerTextmethodwillreturn(asanNSString):

Paragraph 1Paragraph 2

AndtheouterHTMLmethodwillreturn(asanNSString):

Paragraph 1

Paragraph 2

Eachofthosemethodshasacorrespondingsetmethod(setInnerHTML,setInnerText,setOuterHTML)andcanbeusedonanyelementcastasaDOMHTMLElementoranysubclassofit.

TheadditiontotheDOMRGBColorinterfaceisalsoveryuseful,asitallowsyoutousetheDOMtoaccesstheCSSLevel3alphachannelofanRGB(A)color,eventhoughtheDOMLevel2specificationdoesnotincludeit.

ForacompletelistofextensionsprovidedbytheObjective-CDOMAPI,seetheDOMExtensions.hheaderfile.

55

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingtheDocumentObjectModelExtensions

56

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingJavaScriptFromObjective-C

ThewebscriptingcapabilitiesoftheWebKitpermityoutoaccessJavaScriptattributesandcallJavaScriptfunctionsfromyourCocoaObjective-Capplications.RefertoWebKitDOMProgrammingTopicsifyouwanttoaccesstheObjective-CAPIfromJavaScript.

JavaScriptobjectsarerepresentedbyinstancesofWebScriptObjectinObjective-C.TheAPIusesinstancesofWebScriptObjecttowrapscriptobjectspassedfromthescriptingenvironmenttoObjective-C.YoucanusethemethodsofthisclasstocallJavaScriptfunctionsandget/setpropertiesoftheJavaScriptenvironment.YoushouldnotcreateWebScriptObjectinstancesexplicitly.Rather,usethewindowScriptObjectmethodfromWebViewtogainaccesstothescriptingenvironment.

Methodparametersmustbeobjectsorbasicdatatypeslikeintandfloat.Objective-CobjectswillbeconvertedtotheirJavaScriptequivalentsbytheWebKit:

■ ■ ■ ■ ■

NSNumberobjectswillbeconvertedtoJavaScriptnumbers.NSStringobjectswillbeconvertedtoJavaScriptstrings.NSArrayobjectswillbemappedtospecialread-onlyarrays.NSNullwillbeconvertedtoJavaScript’snull.

AllotherobjectswillbewrappedbytheWebKitintoappropriateobjectsfortheJavaScriptenvironment.

Let’slookatacoupleofexamples.YoumaywanttogettheURLofthecurrentWebViewfromJavaScript,ratherthanaccessingtheURLfromthedatasourceofyourWebView’sWebFrame.Youcandothiswithjustafewlinesofcode:

id win = [webView windowScriptObject];

id location = [win valueForKey:@\"location\"];

NSString *href = [location valueForKey:@\"href\"];

JavaScriptmakesiteasytoaccesstheattributesofawebpage’swindow.TheWebKitmakesiteasytogetthatinformationfromJavaScriptandpassittoObjective-C.Properties,suchaslocationandhref,areonlyavailablefromthescriptobjectiftheclassoverridesisKeyExcludedFromWebScript()toreturnNOforthegivenproperties.Thesameistrueforanyselectors.Butremember,akeyfeatureofthewebscriptingsystemintheWebKitistheabilitytocallJavaScriptfunctions.OneofJavaScript’sbuilt-infunctions,

location.href,returnstheURLofthewindowinonecall.Withthisinmind,youcanslimyourthree-lineURLaccessorintheexampleabovedowntoonesimpleline:

NSString *href = [[webView windowScriptObject] evaluateWebScript:@\"location.href\"];

YoucanalsocallJavaScriptfunctionswitharguments.AssumethatyouhavewrittenaJavaScriptfunctionwhichlookslikethis:

function addImage(image, width, height) { ... }

57

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

UsingJavaScriptFromObjective-C

Itspurposeistoaddanimagetoawebpage.Itiscalledwiththreearguments:image,theURLoftheimage;width,thescreenwidthoftheimage;andheight,thescreenheightoftheimage.YoucancallthismethodoneoftwowaysfromObjective-C.ThefirstcreatesthearrayofargumentspriortousingtheWebScriptObjectbridge:

id win = [webView windowScriptObject];

NSArray *args = [NSArray arrayWithObjects: @\"sample_graphic.jpg\

[NSNumber numberWithInt:320], [NSNumber numberWithInt:240], nil];

[win callWebScriptMethod:@\"addImage\" withArguments:args];

ThesecondversionsendstheargumentsrighttoJavaScript:

[win evaluateWebScript:

@\"addImage(’sample_graphic.jpg’, ‘320’, ‘240’)\"];

FormoreinformationonusingtheWebScriptObjecttoopenJavaScripttoObjective-C,readtheWebKitObjective-CFrameworkReference.

58

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

Spoofing

Somewebsiteswilldeliverdifferentcontenttodifferentprogramsthataskforthesamepage.Inextremecases,awebsitemaydenyaccesscompletelytosomeprograms.Whenthishappens,youcantrytogainaccesstothesiteby“spoofing”asanotherbrowser.

Aclientbrowsersendsaspecialstring,calledauseragent,towebsitestoidentifyitself.ThewebserverorJavaScriptinthedownloadedwebpage,detectstheclient’sidentityandmodifiesitsbehavioraccordingly.Inthesimplestcase,thestringincludesanapplicationname(forexample,“Navigator”)andversioninformation(forexample,4.7or6.0).Youcanusetheseuser-agentmethodsinWebViewtomaketheidentityofyourapplicationknownandinsomecases,tohidetheidentityofyourapplication,atechniquecalledspoofing:

■ ■

setCustomUserAgent:—setstheuser-agentstring.

setApplicationNameForUserAgent:—setstheapplicationnameusedintheuser-agentstring.

Notethatsomewebsitesusetheuser-agentstringtodeterminewhethertheysupportaclientbrowserornot.Iftheydon’t,theymaysenddumbed-downversionsofpagesordenyaccesstothewebsitetoo.Inthatcase,youcanmodifytheuser-agentstringtopretendtobeapopularbrowserandthenaccessthewebsite.Although,thismaynotworkifthewebsiteexpectsyourapplicationtoimplementbrowser-specificextensions.Forthisreason,youshouldonlyconsiderspoofingasalastresort.

59

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

Spoofing

60

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

AccessingtheWebKitFromCarbonApplications

ToaccesstheWebKitfromaCarbonapplication,youusetheCarbonWebKitAPItocreateaCarbonwebview.Onceyouhaveaddedtheviewtoawindow,youneedtoloadanddisplayURLcontentusingnativeCocoaclasses.

Beforeusinganywebviews,youneedtocalltheWebInitForCarbonfunction.DoingsoinitializesCocoasoyoucanaccesstheWebKitfromyourCarbonapplication.

Tocreateawebview,yousimplycalltheHIWebViewCreatefunction.ThisfunctionreturnsanHIViewreference,andassuchyoucanuseanyofthestandardHIViewmanipulationfunctionsonit.Forexample,youcanembedthewebviewwithinanotherwindoworview,resizeit,andsoon.Forexample,thefollowingcodefragmentcreatesawebviewandembedsitinawindow:

WindowRef window;

HIViewRef webView, contentView; HIRect bounds; CFURLRef url; // Create your window here …

// Get a URL here, as a CFURL …

WebInitForCarbon(); // initialize WebKit

HIWebViewCreate( &webView ); // create the web view

// Now obtain the content view associated with the window

HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID, &contentView );

// Set the bounds of the web view to be the same as the content view HIViewGetBounds( contentView, &bounds ); HIViewSetFrame( webView, &bounds );

// Embed the web view in the content view and make it visible HIViewAddSubview( contentView, webView ); HIViewSetVisible( webView, true ); // Make a call to load URL content */ LoadURL( webView, url );

Tomanipulatethecontentsofthewebview,youneedaccesstotheactualCocoaview.YouobtainareferencetotheCocoaWebViewobjectbycallingtheHIWebViewGetWebViewfunction.YoucanthenmakeObjective-CcallstotheWebKitusingthatobject.TheexamplefunctionLoadURLshowshowyoucoulddothis:

static void LoadURL( HIViewRef inView, CFURLRef inURL ){

61

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

AccessingtheWebKitFromCarbonApplications

WebView* nativeView; NSURLRequest* request; WebFrame* mainFrame;

nativeView = HIWebViewGetWebView( inView ); // get the Cocoa view // Use Objective-C calls to load the actual content request = [NSURLRequest requestWithURL:(NSURL*)inURL]; mainFrame = [nativeView mainFrame]; [mainFrame loadRequest:request];}

SeeWebKitCReferenceformoredetailsabouttheCarbonWebKitfunctions.

Note: FormoredetailedinformationaboutcallingCocoamethodsfromaCarbonapplication,seeCarbon-CocoaIntegrationGuide.

62

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

DeterminingWebKitAvailability

OnMacOSX10.2,theWebKitframeworkandtheURLLoadingsystemisonlyavailableonsystemsthathaveinstalledSafari1.0.ThisarticleexplainshowaMach-OapplicationthatusetheWebKitframeworkortheURLLoadingsystem,canruneffectivelyonversionsofMacOSXthatdon'thaveSafari1.0installed.

Ifauserrunsyourapplicationonasystemthatdoesnothavetheappropriateframeworksinstalleditwillfailtolaunch,orcrashatsomepointduringexecution.Inordertopreventthisyoumusttakesomeprecautionsinyourproject.

TestingforURLLoadingSystemAvailability

TheURLLoadingsystemisavailableasofversion462.6oftheFoundationframework.TodetermineiftheclassesareavailableyoucantesttheNSFoundationVersionNumberoftheinstalledFoundationframework.TheexamplecodeinListing1 (page 63)willreturnYESiftheURLLoadingsystemisavailable.Listing1

DeterminingiftheURLLoadingsystemisavailable.

+ (BOOL)isURLLoadingAvailable{

return (NSFoundationVersionNumber >= 462.6);}

TestingforWebKitAvailability

AnapplicationcantestfortheavailabilityoftheWebKitbyattemptingtocreateabundlefortheframeworkusingNSBundle.Iftheframeworkexists,theapplicationcanusetheloadmethodtodynamicallyloadtheframework.

TheexamplecodeinListing2 (page 63)willreturnYESiftheframeworkisinstalledandloadssuccessfully.Listing2

DeterminingiftheWebKitframeworkisavailable

+ (BOOL)isWebKitAvailable{

static BOOL _webkitAvailable=NO; static BOOL _initialized=NO; if (_initialized)

return _webkitAvailable; NSBundle* webKitBundle;

TestingforURLLoadingSystemAvailability

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

63

DeterminingWebKitAvailability

webKitBundle = [NSBundle

bundleWithPath:@\"/System/Library/Frameworks/WebKit.framework\"]; if (webKitBundle) {

_webkitAvailable = [webKitBundle load]; }

_initialized=YES;

return _webkitAvailable;}

IsolatingYourWebKitandURLLoadingSystemSymbols

SimplytestingtheversionoftheFoundationframeworkoriftheWebKitframeworkisinstalledisnotsufficient.IftheapplicationcontainsWebKitorURLLoadingsystemsymbolsitcanfailbeforeit'sabletoexecutethetestcodeandinformtheuseroftheproblem.

Theapplicationmustensurethatthemainbundledoesnotincludeanysymbolsthatmaynotbeavailableatlaunch.

ConditionallyLoadingCode

OnesolutionistoseparateyourWebKitdependentcodeintoabundleandloaditonlyafterdeterminingthattheframeworkisavailable.

YoustartbycreatinganewBundletargetinyourapplication'sXcodeproject.ThistargetshouldcontainallyourcodethatdirectlyreferencesWebKitclasses,globalsandtypesandisshouldbesettolinkagainsttheWebKit.framework.

YourmainapplicationtargetinProjectBuildershouldspecifythatitisdependentonthebundleandcopyittotheapplicationdirectoryatcompiletime.YourapplicationthencheckstheavailabilityoftheWebKitframeworkand,ifpresent,usesNSBundleorCFBundletodynamicallyloadthecode.

WeakLinkingSymbols

MacOSX10.2introducedsupportforweaklinkinginMach-Oapplications.ItworksinasimilarmannertothetraditionalMacOS'CodeFragmentManager’sweak,orsoftimports.

Thetechnicalnote“EnsuringBackwardsBinaryCompatibility-WeakLinkingandAvailabilityMacrosonMacOSX”describesthecurrentsupportforweaklinkingofCarbonsymbols.Currently,thesamelevelofsupportisnotavailableforObjective-Cclasses.

DuetothedynamicnatureofObjective-CitispossibletoavoidusinglinkedsymbolsforclassnamesbycreatinganinstanceofaclassusingtheNSClassFromString()function.

Class webDownloadClass=NSClassFromString(@\"WebDownload\");

WebDownload *download=[[webDownloadClass alloc] initWithRequest:theRequest delegate:self];

ThisisequivalenttothefollowingcodethatexplicitlyusestheWebDownloadclass.

IsolatingYourWebKitandURLLoadingSystemSymbols

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

DeterminingWebKitAvailability

WebDownload *download=[[WebDownload alloc] initWithRequest:theRequest delegate:self];

Dependingonyourusage,itmayalsobenecessarytodynamicallyloadWebKitconstantsusingCFBundleafterdeterminingthattheframeworkisavailable.TheexamplecodeinListing3 (page 65)demonstratestestingfortheframeworkandloadingaWebKitconstantusingCFBundle.Listing3

LoadingWebKitconstantsdynamicallyusingCFBundle

CFURLRef url = CFURLCreateWithFileSystemPath(NULL,

CFSTR(\"/System/Library/Frameworks/WebKit.framework\"), kCFURLPOSIXPathStyle, TRUE); CFBundleRef bundle = CFBundleCreate(NULL, url); if (bundle != NULL) {

NSString **WebHistoryItemsAddedNotificationPointer =

(NSString **)CFBundleGetDataPointerForName(bundle,

CFSTR(\"WebHistoryItemsAddedNotification\")); if (WebHistoryItemsAddedNotificationPointer != NULL) { NSLog(@\"looked up WebHistoryItemsAddedNotification\"); NSLog(@\"location is %x, value is %@\*WebHistoryItemsAddedNotificationPointer, *WebHistoryItemsAddedNotificationPointer); } else {

NSLog(@\"found WebKit, but couldn't get the pointer\"); } } else {

NSLog(@\"no WebKit installed\"); }

SeeAlso:TechnicalNoteTN20-Ensuringbackwardscompatibility-WeakLinkingandAvailabilityMacrosinMacOSX10.2

IsolatingYourWebKitandURLLoadingSystemSymbols

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

65

DeterminingWebKitAvailability

66

IsolatingYourWebKitandURLLoadingSystemSymbols

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

DocumentRevisionHistory

ThistabledescribesthechangestoWebKitObjective-CProgrammingGuide.Date2009-07-282008-10-152006-05-232006-03-082005-04-29

Notes

Addedconcurrencyinformation.Minoreditsthroughout.

AddedinformationaboutusingisKeyExcludedFromWebScript()toexposeselectorsorkeystoJavaScript.

Fixedcodeexamplein\"UsingJavaScriptFromObjective-C\"article,fixedmiscellaneousmethodlinks,andremovedreferencestoProjectBuilder.Changedavailabilityofv10.4featurestov10.3.9andlater.

Addedarticlesonediting,JavaScript,andDOM.Changedthetitlefrom\"DisplayingWebContent.\"

Addedtwonewarticles:“MakingPolicyDecisions” (page 39)and“UsingUndoWhenEditing” (page 49).

2003-06-112003-06-06

AddedCarboncodeexampleto“AccessingtheWebKitFromCarbonApplications” (page 61).

FirstreleaseofconceptualandtaskmaterialcoveringthecoreWebKitclassesandprotocolsavailableinMacOSX10.2withSafari1.0.

67

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

DocumentRevisionHistory

68

2009-07-28 | © 2003, 2009 Apple Inc. All Rights Reserved.

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- ryyc.cn 版权所有 湘ICP备2023022495号-3

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务