Python bindings for Apple's WebKit and JavaScriptCore frameworks on macOS, enabling web browser functionality and JavaScript execution in Python applications
—
URL loading, navigation management, browser history, and network request handling. Includes both modern WKNavigation system and legacy navigation approaches, providing comprehensive control over web content loading and user navigation.
Opaque object representing a navigation operation.
class WKNavigation:
# WKNavigation is an opaque object with no public methods
# It serves as an identifier for navigation operations
passInformation about a navigation action that is about to be performed.
class WKNavigationAction:
@property
def request(self) -> NSURLRequest: ...
@property
def sourceFrame(self) -> WKFrameInfo: ...
@property
def targetFrame(self) -> WKFrameInfo: ...
@property
def navigationType(self) -> WKNavigationType: ...
@property
def modifierFlags(self) -> int: ...
@property
def buttonNumber(self) -> int: ...
@property
def shouldPerformDownload(self) -> bool: ...Response information for a navigation operation.
class WKNavigationResponse:
@property
def response(self) -> NSURLResponse: ...
@property
def isForMainFrame(self) -> bool: ...
def canShowMIMEType(self) -> bool: ...Browser history management for web view navigation.
class WKBackForwardList:
@property
def currentItem(self) -> WKBackForwardListItem: ...
@property
def backItem(self) -> WKBackForwardListItem: ...
@property
def forwardItem(self) -> WKBackForwardListItem: ...
@property
def backList(self) -> list: ...
@property
def forwardList(self) -> list: ...
def itemAtIndex_(self, index: int) -> WKBackForwardListItem: ...Individual entries in the browser history.
class WKBackForwardListItem:
@property
def URL(self) -> NSURL: ...
@property
def title(self) -> str: ...
@property
def initialURL(self) -> NSURL: ...File download management and control.
class WKDownload:
@property
def originalRequest(self) -> NSURLRequest: ...
@property
def delegate(self) -> WKDownloadDelegate: ...
@property
def progress(self) -> NSProgress: ...
def cancel(self): ...Legacy WebView navigation functionality.
class WebView:
# Navigation control
def goBack(self) -> bool: ...
def goForward(self) -> bool: ...
def goToBackForwardItem_(self, item: WebHistoryItem) -> bool: ...
def reload_(self, sender: object): ...
def stopLoading_(self, sender: object): ...
# Navigation state
def canGoBack(self) -> bool: ...
def canGoForward(self) -> bool: ...
def isLoading(self) -> bool: ...
@property
def estimatedProgress(self) -> float: ...
# URL and content loading
@property
def mainFrameURL(self) -> str: ...
@property
def mainFrameDocument(self) -> DOMDocument: ...
@property
def mainFrameTitle(self) -> str: ...
@property
def mainFrame(self) -> WebFrame: ...
# History management
@property
def backForwardList(self) -> WebBackForwardList: ...
def setMaintainsBackForwardList_(self, flag: bool): ...
# Content type handling
@classmethod
def canShowMIMEType_(cls, MIMEType: str) -> bool: ...
@classmethod
def canShowMIMETypeAsHTML_(cls, MIMEType: str) -> bool: ...
@classmethod
def MIMETypesShownAsHTML(cls) -> list: ...
@classmethod
def setMIMETypesShownAsHTML_(cls, MIMETypes: list): ...
# Text encoding
def supportsTextEncoding(self) -> bool: ...
@property
def customTextEncodingName(self) -> str: ...
@property
def applicationNameForUserAgent(self) -> str: ...
@property
def customUserAgent(self) -> str: ...
# Page interaction
def stringByEvaluatingJavaScriptFromString_(self, script: str) -> str: ...
@property
def windowScriptObject(self) -> WebScriptObject: ...
# Search functionality
def searchFor_direction_caseSensitive_wrap_(self, string: str, forward: bool, caseFlag: bool, wrapFlag: bool) -> bool: ...Represents a frame within a web page.
class WebFrame:
# Frame properties
@property
def name(self) -> str: ...
@property
def webView(self) -> WebView: ...
@property
def frameView(self) -> WebFrameView: ...
@property
def DOMDocument(self) -> DOMDocument: ...
@property
def frameElement(self) -> DOMHTMLElement: ...
@property
def provisionalDataSource(self) -> WebDataSource: ...
@property
def dataSource(self) -> WebDataSource: ...
# Frame hierarchy
@property
def parentFrame(self) -> WebFrame: ...
@property
def childFrames(self) -> list: ...
def findFrameNamed_(self, name: str) -> WebFrame: ...
# Content loading
def loadRequest_(self, request: NSURLRequest): ...
def loadArchive_(self, archive: WebArchive): ...
def loadData_MIMEType_textEncodingName_baseURL_(self, data: NSData, MIMEType: str, encodingName: str, URL: NSURL): ...
def loadHTMLString_baseURL_(self, string: str, URL: NSURL): ...
def loadAlternateHTMLString_baseURL_forUnreachableURL_(self, string: str, baseURL: NSURL, unreachableURL: NSURL): ...
def stopLoading(self): ...
def reload(self): ...
# JavaScript execution
def windowObject(self) -> WebScriptObject: ...
@property
def globalContext(self) -> JSGlobalContextRef: ...
@property
def javaScriptContext(self) -> JSContext: ...Legacy browser history item.
class WebHistoryItem:
@property
def URLString(self) -> str: ...
@property
def originalURLString(self) -> str: ...
@property
def title(self) -> str: ...
@property
def lastVisitedTimeInterval(self) -> float: ...
@property
def icon(self) -> NSImage: ...
@property
def isTargetItem(self) -> bool: ...
@property
def visitCount(self) -> int: ...
@property
def children(self) -> list: ...
@property
def target(self) -> str: ...
@property
def alternateTitle(self) -> str: ...
@property
def scrollPoint(self) -> NSPoint: ...Legacy browser history list.
class WebBackForwardList:
def addItem_(self, item: WebHistoryItem): ...
def goBack(self): ...
def goForward(self): ...
def goToItem_(self, item: WebHistoryItem): ...
@property
def currentItem(self) -> WebHistoryItem: ...
@property
def backItem(self) -> WebHistoryItem: ...
@property
def forwardItem(self) -> WebHistoryItem: ...
@property
def backListWithLimit_(self, limit: int) -> list: ...
@property
def forwardListWithLimit_(self, limit: int) -> list: ...
@property
def capacity(self) -> int: ...
@property
def backListCount(self) -> int: ...
@property
def forwardListCount(self) -> int: ...
def containsItem_(self, item: WebHistoryItem) -> bool: ...
def itemAtIndex_(self, index: int) -> WebHistoryItem: ...Data source for web content.
class WebDataSource:
@property
def data(self) -> NSData: ...
@property
def representation(self) -> WebDocumentRepresentation: ...
@property
def webFrame(self) -> WebFrame: ...
@property
def initialRequest(self) -> NSURLRequest: ...
@property
def request(self) -> NSMutableURLRequest: ...
@property
def response(self) -> NSURLResponse: ...
@property
def textEncodingName(self) -> str: ...
@property
def isLoading(self) -> bool: ...
@property
def pageTitle(self) -> str: ...
@property
def unreachableURL(self) -> NSURL: ...
@property
def webArchive(self) -> WebArchive: ...
@property
def mainResource(self) -> WebResource: ...
@property
def subresources(self) -> list: ...
def subresourceForURL_(self, URL: NSURL) -> WebResource: ...
def addSubresource_(self, subresource: WebResource): ...Represents a web resource (file, image, etc.).
class WebResource:
def initWithData_URL_MIMEType_textEncodingName_frameName_(self, data: NSData, URL: NSURL, MIMEType: str, textEncodingName: str, frameName: str) -> WebResource: ...
@property
def data(self) -> NSData: ...
@property
def URL(self) -> NSURL: ...
@property
def MIMEType(self) -> str: ...
@property
def textEncodingName(self) -> str: ...
@property
def frameName(self) -> str: ...Custom URL scheme handling for WKWebView.
# WKURLSchemeHandler is a protocol - implement these methods in your handler class
def webView_startURLSchemeTask_(self, webView: WKWebView, urlSchemeTask: WKURLSchemeTask): ...
def webView_stopURLSchemeTask_(self, webView: WKWebView, urlSchemeTask: WKURLSchemeTask): ...Represents a URL scheme task.
class WKURLSchemeTask:
@property
def request(self) -> NSURLRequest: ...
def didReceiveResponse_(self, response: NSURLResponse): ...
def didReceiveData_(self, data: NSData): ...
def didFinish(self): ...
def didFailWithError_(self, error: NSError): ...# WKNavigationType values
WKNavigationTypeLinkActivated = 0
WKNavigationTypeFormSubmitted = 1
WKNavigationTypeBackForward = 2
WKNavigationTypeReload = 3
WKNavigationTypeFormResubmitted = 4
WKNavigationTypeOther = -1
# Legacy WebNavigationType values
WebNavigationTypeLinkClicked = 0
WebNavigationTypeFormSubmitted = 1
WebNavigationTypeBackForward = 2
WebNavigationTypeReload = 3
WebNavigationTypeFormResubmitted = 4
WebNavigationTypeOther = 5# WKNavigationActionPolicy values
WKNavigationActionPolicyCancel = 0
WKNavigationActionPolicyAllow = 1
WKNavigationActionPolicyDownload = 2
# WKNavigationResponsePolicy values
WKNavigationResponsePolicyCancel = 0
WKNavigationResponsePolicyAllow = 1
WKNavigationResponsePolicyDownload = 2
# WKDownloadRedirectPolicy values
WKDownloadRedirectPolicyCancel = 0
WKDownloadRedirectPolicyAllow = 1# Implement these methods in your navigation delegate class
def webView_decidePolicyForNavigationAction_decisionHandler_(self, webView: WKWebView, navigationAction: WKNavigationAction, decisionHandler: callable): ...
def webView_decidePolicyForNavigationAction_preferences_decisionHandler_(self, webView: WKWebView, navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: callable): ...
def webView_decidePolicyForNavigationResponse_decisionHandler_(self, webView: WKWebView, navigationResponse: WKNavigationResponse, decisionHandler: callable): ...
def webView_didStartProvisionalNavigation_(self, webView: WKWebView, navigation: WKNavigation): ...
def webView_didReceiveServerRedirectForProvisionalNavigation_(self, webView: WKWebView, navigation: WKNavigation): ...
def webView_didFailProvisionalNavigation_withError_(self, webView: WKWebView, navigation: WKNavigation, error: NSError): ...
def webView_didCommitNavigation_(self, webView: WKWebView, navigation: WKNavigation): ...
def webView_didFinishNavigation_(self, webView: WKWebView, navigation: WKNavigation): ...
def webView_didFailNavigation_withError_(self, webView: WKWebView, navigation: WKNavigation, error: NSError): ...
def webView_didReceiveAuthenticationChallenge_completionHandler_(self, webView: WKWebView, challenge: NSURLAuthenticationChallenge, completionHandler: callable): ...
def webViewWebContentProcessDidTerminate_(self, webView: WKWebView): ...
def webView_authenticationChallenge_shouldAllowDeprecatedTLS_(self, webView: WKWebView, challenge: NSURLAuthenticationChallenge, decisionHandler: callable): ...
def webView_navigationAction_didBecomeDownload_(self, webView: WKWebView, navigationAction: WKNavigationAction, download: WKDownload): ...
def webView_navigationResponse_didBecomeDownload_(self, webView: WKWebView, navigationResponse: WKNavigationResponse, download: WKDownload): ...# Implement these methods in your download delegate class
def download_decideDestinationUsingResponse_suggestedFilename_completionHandler_(self, download: WKDownload, response: NSURLResponse, suggestedFilename: str, completionHandler: callable): ...
def download_willPerformHTTPRedirection_newRequest_decisionHandler_(self, download: WKDownload, response: NSHTTPURLResponse, request: NSURLRequest, decisionHandler: callable): ...
def download_didReceiveAuthenticationChallenge_completionHandler_(self, download: WKDownload, challenge: NSURLAuthenticationChallenge, completionHandler: callable): ...
def download_didWriteData_totalBytesWritten_totalBytesExpectedToWrite_(self, download: WKDownload, bytesWritten: int, totalBytesWritten: int, totalBytesExpectedToWrite: int): ...
def downloadDidFinish_(self, download: WKDownload): ...
def download_didFailWithError_resumeData_(self, download: WKDownload, error: NSError, resumeData: NSData): ...import WebKit
from Foundation import NSURL, NSURLRequest
class NavigationDelegate:
def webView_decidePolicyForNavigationAction_decisionHandler_(self, web_view, navigation_action, decision_handler):
# Log navigation attempts
url = navigation_action.request().URL()
nav_type = navigation_action.navigationType()
print(f"Navigating to: {url.absoluteString()}, type: {nav_type}")
# Allow all navigation
decision_handler(WebKit.WKNavigationActionPolicyAllow)
def webView_didFinishNavigation_(self, web_view, navigation):
print(f"Finished loading: {web_view.title()}")
def webView_didFailNavigation_withError_(self, web_view, navigation, error):
print(f"Navigation failed: {error.localizedDescription()}")
# Create web view and set delegate
config = WebKit.WKWebViewConfiguration.alloc().init()
web_view = WebKit.WKWebView.alloc().initWithFrame_configuration_(
((0, 0), (800, 600)), config
)
nav_delegate = NavigationDelegate()
web_view.setNavigationDelegate_(nav_delegate)
# Navigate to URL
url = NSURL.URLWithString_("https://www.apple.com")
request = NSURLRequest.requestWithURL_(url)
web_view.loadRequest_(request)import WebKit
# Get back/forward list
back_forward_list = web_view.backForwardList()
# Check navigation availability
can_go_back = web_view.canGoBack()
can_go_forward = web_view.canGoForward()
print(f"Can go back: {can_go_back}")
print(f"Can go forward: {can_go_forward}")
# Get current item
current_item = back_forward_list.currentItem()
if current_item:
print(f"Current page: {current_item.title()}")
print(f"Current URL: {current_item.URL().absoluteString()}")
# Navigate history
if can_go_back:
web_view.goBack()
# Get history items
back_list = back_forward_list.backList()
for item in back_list:
print(f"Back item: {item.title()} - {item.URL().absoluteString()}")import WebKit
from Foundation import NSURLResponse, NSData, NSURL
class CustomSchemeHandler:
def webView_startURLSchemeTask_(self, web_view, url_scheme_task):
request = url_scheme_task.request()
url = request.URL()
# Handle custom:// URLs
if url.scheme() == "custom":
path = url.path()
if path == "/hello":
# Create response
response = NSURLResponse.alloc().initWithURL_MIMEType_expectedContentLength_textEncodingName_(
url, "text/html", -1, "utf-8"
)
url_scheme_task.didReceiveResponse_(response)
# Send HTML content
html = "<html><body><h1>Hello from custom scheme!</h1></body></html>"
data = html.encode('utf-8')
url_scheme_task.didReceiveData_(NSData.dataWithBytes_length_(data, len(data)))
url_scheme_task.didFinish()
else:
# Handle 404
error = NSError.errorWithDomain_code_userInfo_(
"CustomSchemeError", 404, {"description": "Not Found"}
)
url_scheme_task.didFailWithError_(error)
def webView_stopURLSchemeTask_(self, web_view, url_scheme_task):
# Clean up if needed
pass
# Register custom scheme handler
config = WebKit.WKWebViewConfiguration.alloc().init()
scheme_handler = CustomSchemeHandler()
config.setURLSchemeHandler_forURLScheme_(scheme_handler, "custom")
# Create web view with custom scheme support
web_view = WebKit.WKWebView.alloc().initWithFrame_configuration_(
((0, 0), (800, 600)), config
)
# Navigate to custom URL
custom_url = NSURL.URLWithString_("custom://hello")
request = NSURLRequest.requestWithURL_(custom_url)
web_view.loadRequest_(request)import WebKit
class DownloadDelegate:
def download_decideDestinationUsingResponse_suggestedFilename_completionHandler_(self, download, response, suggested_filename, completion_handler):
# Choose download location
downloads_dir = "~/Downloads"
file_path = f"{downloads_dir}/{suggested_filename}"
completion_handler(NSURL.fileURLWithPath_(file_path))
def download_didWriteData_totalBytesWritten_totalBytesExpectedToWrite_(self, download, bytes_written, total_written, total_expected):
# Update download progress
if total_expected > 0:
progress = (total_written / total_expected) * 100
print(f"Download progress: {progress:.1f}%")
def downloadDidFinish_(self, download):
print("Download completed successfully")
def download_didFailWithError_resumeData_(self, download, error, resume_data):
print(f"Download failed: {error.localizedDescription()}")
# Set up download delegate in your navigation delegate
class NavigationDelegate:
def webView_navigationResponse_didBecomeDownload_(self, web_view, navigation_response, download):
download_delegate = DownloadDelegate()
download.setDelegate_(download_delegate)
print("Download started")Install with Tessl CLI
npx tessl i tessl/pypi-pyobjc-framework-webkit