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
本站由北京市万商天勤律师事务所王兴未律师提供法律服务