Initial NSURLSession implementation
First incomplete implementation based on NSURLSession
This commit is contained in:
37
configure
vendored
37
configure
vendored
@@ -1139,6 +1139,7 @@ enable_ole
|
||||
enable_dataobj
|
||||
enable_webrequest
|
||||
enable_webrequestcurl
|
||||
enable_webrequesturlsession
|
||||
enable_ipc
|
||||
enable_baseevtloop
|
||||
enable_epollloop
|
||||
@@ -2083,6 +2084,7 @@ Optional Features:
|
||||
--enable-dataobj use data object classes
|
||||
--enable-webrequest use wxWebRequest
|
||||
--enable-webrequest-curl use libcurl with wxWebRequest
|
||||
--enable-webrequest-urlsession use NSURLSession with wxWebRequest
|
||||
--enable-ipc use interprocess communication (wxSocket etc.)
|
||||
--enable-baseevtloop use event loop in console programs too
|
||||
--enable-epollloop use wxEpollDispatcher class (Linux only)
|
||||
@@ -6580,7 +6582,37 @@ fi
|
||||
|
||||
eval "$wx_cv_use_webrequestcurl"
|
||||
|
||||
if test "$USE_DARWIN" = 1; then
|
||||
|
||||
enablestring=
|
||||
defaultval=$wxUSE_ALL_FEATURES
|
||||
if test -z "$defaultval"; then
|
||||
if test x"$enablestring" = xdisable; then
|
||||
defaultval=yes
|
||||
else
|
||||
defaultval=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check whether --enable-webrequesturlsession was given.
|
||||
if test "${enable_webrequesturlsession+set}" = set; then :
|
||||
enableval=$enable_webrequesturlsession;
|
||||
if test "$enableval" = yes; then
|
||||
wx_cv_use_webrequesturlsession='wxUSE_WEBREQUEST_URLSESSION=yes'
|
||||
else
|
||||
wx_cv_use_webrequesturlsession='wxUSE_WEBREQUEST_URLSESSION=no'
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
wx_cv_use_webrequesturlsession='wxUSE_WEBREQUEST_URLSESSION=${'DEFAULT_wxUSE_WEBREQUEST_URLSESSION":-$defaultval}"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
eval "$wx_cv_use_webrequesturlsession"
|
||||
|
||||
fi
|
||||
|
||||
enablestring=
|
||||
defaultval=$wxUSE_ALL_FEATURES
|
||||
@@ -36714,6 +36746,11 @@ if test "$wxUSE_WEBREQUEST" = "yes"; then
|
||||
$as_echo "#define wxUSE_WEBREQUEST 1" >>confdefs.h
|
||||
|
||||
|
||||
if test "$wxUSE_WEBREQUEST_URLSESSION" = "yes"; then
|
||||
$as_echo "#define wxUSE_WEBREQUEST_URLSESSION 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
if test "$wxUSE_MSW" = 1; then
|
||||
$as_echo "#define wxUSE_WEBREQUEST_WINHTTP 1" >>confdefs.h
|
||||
|
||||
|
@@ -700,6 +700,9 @@ WX_ARG_FEATURE(ole, [ --enable-ole use OLE classes (Win32
|
||||
WX_ARG_FEATURE(dataobj, [ --enable-dataobj use data object classes], wxUSE_DATAOBJ)
|
||||
WX_ARG_FEATURE(webrequest, [ --enable-webrequest use wxWebRequest], wxUSE_WEBREQUEST)
|
||||
WX_ARG_FEATURE(webrequestcurl, [ --enable-webrequest-curl use libcurl with wxWebRequest], wxUSE_WEBREQUEST_LIBCURL)
|
||||
if test "$USE_DARWIN" = 1; then
|
||||
WX_ARG_FEATURE(webrequesturlsession, [ --enable-webrequest-urlsession use NSURLSession with wxWebRequest], wxUSE_WEBREQUEST_URLSESSION)
|
||||
fi dnl USE_DARWIN
|
||||
|
||||
WX_ARG_FEATURE(ipc, [ --enable-ipc use interprocess communication (wxSocket etc.)], wxUSE_IPC)
|
||||
|
||||
@@ -6369,6 +6372,10 @@ fi
|
||||
if test "$wxUSE_WEBREQUEST" = "yes"; then
|
||||
AC_DEFINE(wxUSE_WEBREQUEST)
|
||||
|
||||
if test "$wxUSE_WEBREQUEST_URLSESSION" = "yes"; then
|
||||
AC_DEFINE(wxUSE_WEBREQUEST_URLSESSION)
|
||||
fi
|
||||
|
||||
if test "$wxUSE_MSW" = 1; then
|
||||
dnl TODO: Check for the required headers/libraries under Windows
|
||||
AC_DEFINE(wxUSE_WEBREQUEST_WINHTTP)
|
||||
|
@@ -13,28 +13,98 @@
|
||||
#if wxUSE_WEBREQUEST_URLSESSION
|
||||
|
||||
DECLARE_WXCOCOA_OBJC_CLASS(NSURLSession);
|
||||
DECLARE_WXCOCOA_OBJC_CLASS(NSURLTask);
|
||||
DECLARE_WXCOCOA_OBJC_CLASS(NSURLSessionTask);
|
||||
DECLARE_WXCOCOA_OBJC_CLASS(wxWebSessionDelegte);
|
||||
|
||||
class wxWebSessionURLSession;
|
||||
class wxWebResponseURLSession;
|
||||
|
||||
class WXDLLIMPEXP_NET wxWebResponseURLSession: public wxWebResponse
|
||||
{
|
||||
public:
|
||||
wxWebResponseURLSession(wxWebRequest& request, WX_NSURLSessionTask task);
|
||||
|
||||
~wxWebResponseURLSession();
|
||||
|
||||
wxInt64 GetContentLength() const wxOVERRIDE;
|
||||
|
||||
wxString GetURL() const wxOVERRIDE;
|
||||
|
||||
wxString GetHeader(const wxString& name) const wxOVERRIDE;
|
||||
|
||||
int GetStatus() const wxOVERRIDE;
|
||||
|
||||
wxString GetStatusText() const wxOVERRIDE;
|
||||
|
||||
wxString GetSuggestedFileName() const wxOVERRIDE;
|
||||
|
||||
void HandleData(WX_NSData data);
|
||||
|
||||
private:
|
||||
WX_NSURLSessionTask m_task;
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_NET wxWebRequestURLSession: public wxWebRequest
|
||||
{
|
||||
public:
|
||||
wxWebRequestURLSession(wxWebSessionURLSession& session, const wxString& url, int id);
|
||||
|
||||
~wxWebRequestURLSession();
|
||||
|
||||
void Start() wxOVERRIDE;
|
||||
|
||||
void Cancel() wxOVERRIDE;
|
||||
|
||||
wxWebResponse* GetResponse() const wxOVERRIDE
|
||||
{ return m_response.get(); }
|
||||
|
||||
wxWebAuthChallenge* GetAuthChallenge() const wxOVERRIDE;
|
||||
|
||||
wxFileOffset GetBytesSent() const wxOVERRIDE;
|
||||
|
||||
wxFileOffset GetBytesExpectedToSend() const wxOVERRIDE;
|
||||
|
||||
wxFileOffset GetBytesReceived() const wxOVERRIDE;
|
||||
|
||||
wxFileOffset GetBytesExpectedToReceive() const wxOVERRIDE;
|
||||
|
||||
void HandleCompletion();
|
||||
|
||||
private:
|
||||
wxString m_url;
|
||||
WX_NSURLSessionTask m_task;
|
||||
wxScopedPtr<wxWebResponseURLSession> m_response;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxWebRequestURLSession);
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_NET wxWebSessionURLSession: public wxWebSession
|
||||
{
|
||||
public:
|
||||
wxWebSessionURLSession();
|
||||
wxWebSessionURLSession();
|
||||
|
||||
~wxWebSessionURLSession();
|
||||
~wxWebSessionURLSession();
|
||||
|
||||
wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY) wxOVERRIDE;
|
||||
wxWebRequest* CreateRequest(const wxString& url, int id = wxID_ANY) wxOVERRIDE;
|
||||
|
||||
wxVersionInfo GetLibraryVersionInfo() wxOVERRIDE;
|
||||
|
||||
WX_NSURLSession GetSession() { return m_session; }
|
||||
|
||||
WX_wxWebSessionDelegte GetDelegate() { return m_delegate; }
|
||||
|
||||
private:
|
||||
WX_NSURLSession m_session;
|
||||
WX_NSURLSession m_session;
|
||||
WX_wxWebSessionDelegte m_delegate;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxWebSessionURLSession);
|
||||
wxDECLARE_NO_COPY_CLASS(wxWebSessionURLSession);
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_NET wxWebSessionFactoryURLSession: public wxWebSessionFactory
|
||||
{
|
||||
public:
|
||||
wxWebSession* Create() wxOVERRIDE
|
||||
{ return new wxWebSessionURLSession(); }
|
||||
wxWebSession* Create() wxOVERRIDE
|
||||
{ return new wxWebSessionURLSession(); }
|
||||
};
|
||||
|
||||
#endif // wxUSE_WEBREQUEST_URLSESSION
|
||||
|
@@ -21,22 +21,230 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "wx/osx/webrequest_urlsession.h"
|
||||
#include "wx/osx/private.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/log.h"
|
||||
#include "wx/utils.h"
|
||||
#endif
|
||||
|
||||
@interface wxWebSessionDelegte : NSObject <NSURLSessionDataDelegate>
|
||||
{
|
||||
wxWebSessionURLSession* m_session;
|
||||
NSMapTable* m_requests;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation wxWebSessionDelegte
|
||||
|
||||
- initWithSession:(wxWebSessionURLSession*)session
|
||||
{
|
||||
m_session = session;
|
||||
m_requests = [[NSMapTable weakToStrongObjectsMapTable] retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[m_requests release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)registerRequest:(wxWebRequestURLSession*)request task:(NSURLSessionTask*)task
|
||||
{
|
||||
[m_requests setObject:[NSValue valueWithPointer:request] forKey:task];
|
||||
}
|
||||
|
||||
- (wxWebRequestURLSession*)requestForTask:(NSURLSessionTask*)task
|
||||
{
|
||||
wxWebRequestURLSession* request = NULL;
|
||||
NSValue* val = [m_requests objectForKey:task];
|
||||
if (val)
|
||||
request = static_cast<wxWebRequestURLSession*>(val.pointerValue);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
|
||||
{
|
||||
wxWebRequestURLSession* request = [self requestForTask:dataTask];
|
||||
if (request)
|
||||
static_cast<wxWebResponseURLSession*>(request->GetResponse())->HandleData(data);
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
||||
{
|
||||
wxWebRequestURLSession* request = [self requestForTask:task];
|
||||
if (error)
|
||||
request->SetState(wxWebRequest::State_Failed, wxCFStringRef(error.localizedDescription).AsString());
|
||||
else
|
||||
request->HandleCompletion();
|
||||
|
||||
// After the task is completed it no longer needs to be mapped
|
||||
[m_requests removeObjectForKey:task];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
// wxWebRequestURLSession
|
||||
//
|
||||
wxWebRequestURLSession::wxWebRequestURLSession(wxWebSessionURLSession& session, const wxString& url, int id):
|
||||
wxWebRequest(session, id),
|
||||
m_url(url)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxWebRequestURLSession::~wxWebRequestURLSession()
|
||||
{
|
||||
[m_task release];
|
||||
}
|
||||
|
||||
void wxWebRequestURLSession::Start()
|
||||
{
|
||||
wxWebSessionURLSession& session = static_cast<wxWebSessionURLSession&>(GetSession());
|
||||
|
||||
m_task = [[session.GetSession() dataTaskWithURL:
|
||||
[NSURL URLWithString:wxCFStringRef(m_url).AsNSString()]] retain];
|
||||
|
||||
// The session delegate needs to know which task is wrapped in which request
|
||||
[session.GetDelegate() registerRequest:this task:m_task];
|
||||
|
||||
m_response.reset(new wxWebResponseURLSession(*this, m_task));
|
||||
m_response->Init();
|
||||
|
||||
SetState(State_Active);
|
||||
[m_task resume];
|
||||
}
|
||||
|
||||
void wxWebRequestURLSession::Cancel()
|
||||
{
|
||||
[m_task cancel];
|
||||
}
|
||||
|
||||
void wxWebRequestURLSession::HandleCompletion()
|
||||
{
|
||||
if ( CheckServerStatus() )
|
||||
SetState(State_Completed);
|
||||
}
|
||||
|
||||
wxWebAuthChallenge* wxWebRequestURLSession::GetAuthChallenge() const
|
||||
{
|
||||
wxFAIL_MSG("not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wxFileOffset wxWebRequestURLSession::GetBytesSent() const
|
||||
{
|
||||
return m_task.countOfBytesSent;
|
||||
}
|
||||
|
||||
wxFileOffset wxWebRequestURLSession::GetBytesExpectedToSend() const
|
||||
{
|
||||
return m_task.countOfBytesExpectedToSend;
|
||||
}
|
||||
|
||||
wxFileOffset wxWebRequestURLSession::GetBytesReceived() const
|
||||
{
|
||||
return m_task.countOfBytesReceived;
|
||||
}
|
||||
|
||||
wxFileOffset wxWebRequestURLSession::GetBytesExpectedToReceive() const
|
||||
{
|
||||
return m_task.countOfBytesExpectedToReceive;
|
||||
}
|
||||
|
||||
//
|
||||
// wxWebResponseURLSession
|
||||
//
|
||||
|
||||
wxWebResponseURLSession::wxWebResponseURLSession(wxWebRequest& request, WX_NSURLSessionTask task):
|
||||
wxWebResponse(request)
|
||||
{
|
||||
m_task = [task retain];
|
||||
}
|
||||
|
||||
wxWebResponseURLSession::~wxWebResponseURLSession()
|
||||
{
|
||||
[m_task release];
|
||||
}
|
||||
|
||||
void wxWebResponseURLSession::HandleData(WX_NSData data)
|
||||
{
|
||||
[data enumerateByteRangesUsingBlock:^(const void * _Nonnull bytes, NSRange byteRange, BOOL * _Nonnull stop) {
|
||||
void* buf = GetDataBuffer(byteRange.length);
|
||||
std::memcpy(buf, bytes, byteRange.length);
|
||||
ReportDataReceived(byteRange.length);
|
||||
}];
|
||||
}
|
||||
|
||||
wxInt64 wxWebResponseURLSession::GetContentLength() const
|
||||
{
|
||||
return m_task.response.expectedContentLength;
|
||||
}
|
||||
|
||||
wxString wxWebResponseURLSession::GetURL() const
|
||||
{
|
||||
return wxCFStringRef(m_task.response.URL.absoluteString).AsString();
|
||||
}
|
||||
|
||||
wxString wxWebResponseURLSession::GetHeader(const wxString& name) const
|
||||
{
|
||||
NSHTTPURLResponse* httpResp = (NSHTTPURLResponse*) m_task.response;
|
||||
NSString* value = [httpResp.allHeaderFields objectForKey:wxCFStringRef(name).AsNSString()];
|
||||
if (value)
|
||||
return wxCFStringRef(value).AsString();
|
||||
else
|
||||
return wxString();
|
||||
}
|
||||
|
||||
int wxWebResponseURLSession::GetStatus() const
|
||||
{
|
||||
NSHTTPURLResponse* httpResp = (NSHTTPURLResponse*) m_task.response;
|
||||
return httpResp.statusCode;
|
||||
}
|
||||
|
||||
wxString wxWebResponseURLSession::GetStatusText() const
|
||||
{
|
||||
return wxCFStringRef([NSHTTPURLResponse localizedStringForStatusCode:GetStatus()]).AsString();
|
||||
}
|
||||
|
||||
wxString wxWebResponseURLSession::GetSuggestedFileName() const
|
||||
{
|
||||
return wxCFStringRef(m_task.response.suggestedFilename).AsString();
|
||||
}
|
||||
|
||||
//
|
||||
// wxWebSessionURLSession
|
||||
//
|
||||
|
||||
wxWebSessionURLSession::wxWebSessionURLSession()
|
||||
{
|
||||
m_session = [NSURLSession sessionWithConfiguration:
|
||||
[NSURLSessionConfiguration defaultSessionConfiguration]];
|
||||
m_delegate = [[wxWebSessionDelegte alloc] initWithSession:this];
|
||||
|
||||
m_session = [[NSURLSession sessionWithConfiguration:
|
||||
[NSURLSessionConfiguration defaultSessionConfiguration]
|
||||
delegate:m_delegate delegateQueue:nil] retain];
|
||||
}
|
||||
|
||||
wxWebSessionURLSession::~wxWebSessionURLSession()
|
||||
{
|
||||
[m_session release];
|
||||
[m_session release];
|
||||
[m_delegate release];
|
||||
}
|
||||
|
||||
wxWebRequest* wxWebSessionURLSession::CreateRequest(const wxString& url, int id)
|
||||
{
|
||||
wxFAIL_MSG("not implemented");
|
||||
return NULL;
|
||||
return new wxWebRequestURLSession(*this, url, id);
|
||||
}
|
||||
|
||||
wxVersionInfo wxWebSessionURLSession::GetLibraryVersionInfo()
|
||||
{
|
||||
int verMaj, verMin, verMicro;
|
||||
wxGetOsVersion(&verMaj, &verMin, &verMicro);
|
||||
return wxVersionInfo("URLSession", verMaj, verMin, verMicro);
|
||||
}
|
||||
|
||||
#endif // wxUSE_WEBREQUEST_URLSESSION
|
||||
|
Reference in New Issue
Block a user