summaryrefslogtreecommitdiff
path: root/objective-c/test/ios/controller/Classes/ViewController.m
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2016-12-16 15:56:18 +0100
committerBenoit Foucher <benoit@zeroc.com>2016-12-16 15:56:18 +0100
commit66e63999fd121114d27842f1bf3cd2121ccf320c (patch)
treecf20b42e13a4899f2182acc9a572cbae43987358 /objective-c/test/ios/controller/Classes/ViewController.m
parentRemove unused Makefile (diff)
downloadice-66e63999fd121114d27842f1bf3cd2121ccf320c.tar.bz2
ice-66e63999fd121114d27842f1bf3cd2121ccf320c.tar.xz
ice-66e63999fd121114d27842f1bf3cd2121ccf320c.zip
Added support for Objective-C controller
Diffstat (limited to 'objective-c/test/ios/controller/Classes/ViewController.m')
-rw-r--r--objective-c/test/ios/controller/Classes/ViewController.m626
1 files changed, 351 insertions, 275 deletions
diff --git a/objective-c/test/ios/controller/Classes/ViewController.m b/objective-c/test/ios/controller/Classes/ViewController.m
index 4807eeb9acc..6773a7f986e 100644
--- a/objective-c/test/ios/controller/Classes/ViewController.m
+++ b/objective-c/test/ios/controller/Classes/ViewController.m
@@ -8,377 +8,413 @@
// **********************************************************************
#import "ViewController.h"
-
-#import <objc/Ice/Ice.h>
#import <Controller.h>
+#import <TestCommon.h>
-@interface ViewController()
--(void) print:(NSString*)msg;
--(void) println:(NSString*)msg;
-@end
-
-namespace
-{
-
-typedef int (*MAIN_ENTRY_POINT)(int argc, char** argv, Test::MainHelper* helper);
-typedef int (*SHUTDOWN_ENTRY_POINT)();
+#include <ifaddrs.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <dlfcn.h>
-class MainHelperI : public Test::MainHelper, private IceUtil::Monitor<IceUtil::Mutex>, public IceUtil::Thread
+@interface MainHelper : NSThread
{
-public:
-
- MainHelperI(ViewController*, const string&, const StringSeq&);
- virtual ~MainHelperI();
-
- virtual void serverReady();
- virtual void shutdown();
- virtual void waitForCompleted() {}
- virtual bool redirect();
- virtual void print(const std::string&);
-
- virtual void run();
-
- void completed(int);
- void waitReady(int) const;
- int waitSuccess(int) const;
- string getOutput() const;
-
-private:
-
- ViewController* _controller;
- std::string _dll;
- StringSeq _args;
- CFBundleRef _handle;
- SHUTDOWN_ENTRY_POINT _dllTestShutdown;
- bool _ready;
- bool _completed;
+ id<ViewController> _controller;
+ void* _func;
+ NSArray* _args;
+ BOOL _ready;
+ BOOL _completed;
int _status;
- std::ostringstream _out;
-};
-
-class ProcessI : public Process
-{
-public:
-
- ProcessI(ViewController*, MainHelperI*);
- virtual ~ProcessI();
-
- void waitReady(int, const Ice::Current&);
- int waitSuccess(int, const Ice::Current&);
- string terminate(const Ice::Current&);
-
-private:
-
- ViewController* _controller;
- IceUtil::Handle<MainHelperI> _helper;
-};
-
-class ProcessControllerI : public ProcessController
-{
-public:
-
- ProcessControllerI(ViewController*);
-
-#ifdef ICE_CPP11_MAPPING
- virtual shared_ptr<ProcessPrx>
- start(string, string, StringSeq, const Ice::Current&);
-#else
- virtual ProcessPrx
- start(const string&, const string&, const StringSeq&, const Ice::Current&);
-#endif
-
-private:
-
- ViewController* _controller;
-};
+ NSMutableString* _out;
+ NSCondition* _cond;
+}
+-(void) serverReady;
+-(void) shutdown;
+-(void) print:(NSString*)str;
+-(void) completed:(int)status;
+-(void) waitReady:(int)timeout;
+-(int) waitSuccess:(int)timeout;
+-(NSString*)getOutput;
+@end
-class ControllerHelper
+@interface ProcessI : TestCommonProcess<TestCommonProcess>
{
-public:
-
- ControllerHelper(ViewController*);
- virtual ~ControllerHelper();
-
-private:
-
- Ice::CommunicatorPtr _communicator;
-};
-
+ id<ViewController> _controller;
+ MainHelper* _helper;
}
+-(void) waitReady:(int)timeout current:(ICECurrent*)current;
+-(int) waitSuccess:(int)timeout current:(ICECurrent*)current;
+-(NSString*) terminate:(ICECurrent*)current;
+@end
-MainHelperI::MainHelperI(ViewController* controller, const string& dll, const StringSeq& args) :
- _controller(controller),
- _dll(dll),
- _args(args),
- _ready(false),
- _completed(false),
- _status(0)
+@interface ProcessControllerI : TestCommonProcessController<TestCommonProcessController>
{
+ id<ViewController> _controller;
+ NSString* _ipv4;
+ NSString* _ipv6;
}
+-(id) init:(id<ViewController>) controller ipv4:(NSString*)ipv4 ipv6:(NSString*)ipv6;
+-(id<TestCommonProcessPrx>) start:(NSString*)testsuite exe:(NSString*)exe args:(NSArray*)args current:(ICECurrent*)current;
+-(NSString*) getHost:(NSString*)protocol ipv6:(BOOL)ipv6 current:(ICECurrent*)current;
+@end
-MainHelperI::~MainHelperI()
+@implementation MainHelper
+-(id) init:(id<ViewController>)controller func:(void*)func args:(NSArray*)args
{
- if(_handle)
+ self = [super init];
+ if(self == nil)
{
- CFBundleUnloadExecutable(_handle);
+ return nil;
}
+ _controller = ICE_RETAIN(controller);
+ _func = func;
+ _args = ICE_RETAIN(args);
+ _ready = FALSE;
+ _completed = FALSE;
+ _status = 0;
+ _out = ICE_RETAIN([NSMutableString string]);
+ _cond = [NSCondition new];
+ return self;
}
-
-void
-MainHelperI::serverReady()
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
{
- Lock sync(*this);
- _ready = true;
- notifyAll();
+ [_controller release];
+ [_args release];
+ [_cond release];
+ [_out release];
+ [super dealloc];
}
-
-void
-MainHelperI::shutdown()
+#endif
+-(void) serverReady
{
- Lock sync(*this);
- if(_completed)
+ [_cond lock];
+ @try
{
- return;
+ _ready = YES;
+ [_cond signal];
}
-
- if(_dllTestShutdown)
+ @finally
{
- _dllTestShutdown();
+ [_cond unlock];
}
}
-
-bool
-MainHelperI::redirect()
-{
- return _dll.find("client") != string::npos || _dll.find("collocated") != string::npos;
-}
-
-void
-
-MainHelperI::print(const std::string& msg)
-{
- _out << msg;
-}
-
-void
-MainHelperI::run()
+-(void) shutdown
{
- NSString* bundlePath = [[NSBundle mainBundle] privateFrameworksPath];
-
- bundlePath = [bundlePath stringByAppendingPathComponent:[NSString stringWithUTF8String:_dll.c_str()]];
-
- NSURL* bundleURL = [NSURL fileURLWithPath:bundlePath];
- _handle = CFBundleCreate(NULL, (CFURLRef)bundleURL);
- if(!_handle)
- {
- print([[NSString stringWithFormat:@"Could not find bundle %@", bundlePath] UTF8String]);
- completed(EXIT_FAILURE);
- return;
- }
-
- CFErrorRef error = nil;
- Boolean loaded = CFBundleLoadExecutableAndReturnError(_handle, &error);
- if(error != nil || !loaded)
+ [_cond lock];
+ @try
{
- print([[(__bridge NSError *)error description] UTF8String]);
- completed(EXIT_FAILURE);
- return;
+ if(_completed)
+ {
+ return;
+ }
+ serverStop();
}
-
- void* sym = dlsym(_handle, "dllTestShutdown");
- sym = CFBundleGetFunctionPointerForName(_handle, CFSTR("dllTestShutdown"));
- if(sym == 0)
+ @finally
{
- NSString* err = [NSString stringWithFormat:@"Could not get function pointer dllTestShutdown from bundle %@",
- bundlePath];
- print([err UTF8String]);
- completed(EXIT_FAILURE);
- return;
+ [_cond unlock];
}
- _dllTestShutdown = (SHUTDOWN_ENTRY_POINT)sym;
-
- sym = CFBundleGetFunctionPointerForName(_handle, CFSTR("dllMain"));
- if(sym == 0)
+}
+-(void) print:(NSString*)msg
+{
+ [_out appendString:msg];
+}
+-(void) main
+{
+ int (*mainEntryPoint)(int, char**) = (int (*)(int, char**))_func;
+ char** argv = malloc(sizeof(char*) * (_args.count + 1));
+ int i = 0;
+ for(NSString* arg in _args)
{
- NSString* err = [NSString stringWithFormat:@"Could not get function pointer dllMain from bundle %@",
- bundlePath];
- print([err UTF8String]);
- completed(EXIT_FAILURE);
- return;
+ argv[i++] = (char*)[arg UTF8String];
}
-
- MAIN_ENTRY_POINT dllMain = (MAIN_ENTRY_POINT)sym;
- char** argv = new char*[_args.size() + 1];
- for(unsigned int i = 0; i < _args.size(); ++i)
+ argv[_args.count] = 0;
+ @try
{
- argv[i] = const_cast<char*>(_args[i].c_str());
+ [self completed:mainEntryPoint((int)_args.count, argv)];
}
- argv[_args.size()] = 0;
- try
+ @catch(NSException* ex)
{
- completed(dllMain(static_cast<int>(_args.size()), argv, this));
+ [self print:[NSString stringWithFormat:@"unexpected exception while running `%s':%@\n", argv[0], ex]];
+ [self completed:EXIT_FAILURE];
}
- catch(const std::exception& ex)
+ free(argv);
+}
+-(void) completed:(int)status
+{
+ [_cond lock];
+ @try
{
- print("unexpected exception while running `" + _args[0] + "':\n" + ex.what());
+ _completed = YES;
+ _status = status;
+ [_cond signal];
}
- catch(...)
+ @finally
{
- print("unexpected unknown exception while running `" + _args[0] + "'");
+ [_cond unlock];
}
- delete[] argv;
}
-
-void
-MainHelperI::completed(int status)
+-(void) waitReady:(int)timeout
{
- Lock sync(*this);
- _completed = true;
- _status = status;
- notifyAll();
-}
-
-void
-MainHelperI::waitReady(int timeout) const
-{
- Lock sync(*this);
- while(!_ready && !_completed)
+ [_cond lock];
+ @try
{
- if(!timedWait(IceUtil::Time::seconds(timeout)))
+ while(!_ready && !_completed)
+ {
+ if(![_cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:timeout]])
+ {
+ @throw [TestCommonProcessFailedException
+ processFailedException:@"timed out waiting for the process to be ready"];
+ }
+ }
+ if(_completed && _status == EXIT_FAILURE)
{
- throw ProcessFailedException("timed out waiting for the process to be ready");
+ @throw [TestCommonProcessFailedException processFailedException:_out];
}
}
- if(_completed && _status == EXIT_FAILURE)
+ @finally
{
- throw ProcessFailedException(_out.str());
+ [_cond unlock];
}
}
-
-int
-MainHelperI::waitSuccess(int timeout) const
+-(int) waitSuccess:(int)timeout
{
- Lock sync(*this);
- while(!_completed)
+ [_cond lock];
+ @try
{
- if(!timedWait(IceUtil::Time::seconds(timeout)))
+ while(!_completed)
{
- throw ProcessFailedException("timed out waiting for the process to succeed");
+ if(timeout >= 0)
+ {
+ if(![_cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:timeout]])
+ {
+ @throw [TestCommonProcessFailedException
+ processFailedException:@"timed out waiting for the process to succeed"];
+ }
+ }
+ else
+ {
+ [_cond wait];
+ }
}
}
+ @finally
+ {
+ [_cond unlock];
+ }
return _status;
}
-
-string
-MainHelperI::getOutput() const
+-(NSString*) getOutput
{
- assert(_completed);
- return _out.str();
+ return _out;
}
+@end
-ProcessI::ProcessI(ViewController* controller, MainHelperI* helper) : _controller(controller), _helper(helper)
+@implementation ProcessI
+-(id) init:(id<ViewController>)controller helper:(MainHelper*)helper
{
+ self = [super init];
+ if(self == nil)
+ {
+ return nil;
+ }
+ _controller = ICE_RETAIN(controller);
+ _helper = ICE_RETAIN(helper);
+ return self;
}
-
-ProcessI::~ProcessI()
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
{
+ [_controller release];
+ [_helper release];
+ [super dealloc];
}
-
-void
-ProcessI::waitReady(int timeout, const Ice::Current&)
+#endif
+-(void) waitReady:(int)timeout current:(ICECurrent*)current
{
- _helper->waitReady(timeout);
+ [_helper waitReady:timeout];
}
-
-int
-ProcessI::waitSuccess(int timeout, const Ice::Current&)
+-(int) waitSuccess:(int)timeout current:(ICECurrent*)current
{
- return _helper->waitSuccess(timeout);
+ return [_helper waitSuccess:timeout];
}
-
-string
-ProcessI::terminate(const Ice::Current& current)
+-(NSString*) terminate:(ICECurrent*)current
{
- _helper->shutdown();
- current.adapter->remove(current.id);
- _helper->getThreadControl().join();
- return _helper->getOutput();
+ [_helper shutdown];
+ [current.adapter remove:current.id_];
+ [_helper waitSuccess:-1];
+ return [_helper getOutput];
}
+@end
-ProcessControllerI::ProcessControllerI(ViewController* controller) : _controller(controller)
+@implementation ProcessControllerI
+-(id) init:(id<ViewController>)controller ipv4:(NSString*)ipv4 ipv6:(NSString*)ipv6
{
+ self = [super init];
+ if(self == nil)
+ {
+ return nil;
+ }
+ _controller = ICE_RETAIN(controller);
+ _ipv4 = ICE_RETAIN(ipv4);
+ _ipv6 = ICE_RETAIN(ipv6);
+ return self;
}
-
-#ifdef ICE_CPP11_MAPPING
-shared_ptr<ProcessPrx>
-ProcessControllerI::start(string testSuite, string exe, StringSeq args, const Ice::Current& c)
-#else
-ProcessPrx
-ProcessControllerI::start(const string& testSuite, const string& exe, const StringSeq& args, const Ice::Current& c)
-#endif
+#if defined(__clang__) && !__has_feature(objc_arc)
+-(void) dealloc
{
- std::string prefix = std::string("test/") + testSuite;
- replace(prefix.begin(), prefix.end(), '/', '_');
- [_controller println:[NSString stringWithFormat:@"starting %s %s... ", testSuite.c_str(), exe.c_str()]];
- IceUtil::Handle<MainHelperI> helper = new MainHelperI(_controller, prefix + '/' + exe + ".bundle", args);
- helper->start();
- return ICE_UNCHECKED_CAST(ProcessPrx, c.adapter->addWithUUID(ICE_MAKE_SHARED(ProcessI, _controller, helper.get())));
+ [_controller release];
+ [_ipv4 release];
+ [_ipv6 release];
+ [super dealloc];
}
-
-ControllerHelper::ControllerHelper(ViewController* controller)
+#endif
+-(id<TestCommonProcessPrx>) start:(NSString*)testSuite exe:(NSString*)exe args:(NSArray*)args current:(ICECurrent*)c
{
- Ice::registerIceDiscovery();
+ [_controller println:[NSString stringWithFormat:@"starting %@ %@... ", testSuite, exe]];
- Ice::InitializationData initData = Ice::InitializationData();
- initData.properties = Ice::createProperties();
- initData.properties->setProperty("Ice.ThreadPool.Server.SizeMax", "10");
- initData.properties->setProperty("IceDiscovery.DomainId", "TestController");
- initData.properties->setProperty("IceDiscovery.Interface", "127.0.0.1");
- initData.properties->setProperty("Ice.Default.Host", "127.0.0.1");
- initData.properties->setProperty("ControllerAdapter.Endpoints", "tcp");
- //initData.properties->setProperty("Ice.Trace.Network", "2");
- //initData.properties->setProperty("Ice.Trace.Protocol", "2");
- initData.properties->setProperty("ControllerAdapter.AdapterId", Ice::generateUUID());
+ NSArray<NSString*>* components = [testSuite componentsSeparatedByString:@"/"];
+ components = [components arrayByAddingObject:exe];
+ NSMutableString* func = [NSMutableString string];
+ [func appendString:[components objectAtIndex:1]];
+ for(int i = 2; i < components.count; ++i)
+ {
+ NSString* comp = [components objectAtIndex:i];
+ [func appendString:[[comp substringToIndex:1] capitalizedString]];
+ [func appendString:[comp substringFromIndex:1]];
+ }
- _communicator = Ice::initialize(initData);
+ void* sym = dlsym(RTLD_SELF, [func UTF8String]);
+ if(!sym)
+ {
+ @throw [TestCommonProcessFailedException processFailedException:
+ [NSString stringWithFormat:@"couldn't find %@", func]];
+ }
+ MainHelper* helper = ICE_AUTORELEASE([[MainHelper alloc] init:_controller func:sym args:args]);
+ if([exe isEqualToString:@"client"] || [exe isEqualToString:@"collocated"])
+ {
+ TestCommonInit(helper, @selector(print:));
+ }
+ else
+ {
+ TestCommonInit(helper, @selector(print:));
+ TestCommonTestInit(helper, @selector(serverReady), @"", NO, NO);
+ }
+ [helper start];
+ id<ICEObjectPrx> prx = [c.adapter addWithUUID:ICE_AUTORELEASE([[ProcessI alloc] init:_controller helper:helper])];
+ return [TestCommonProcessPrx uncheckedCast:prx];
+}
+-(NSString*) getHost:(NSString*)protocol ipv6:(BOOL)ipv6 current:(ICECurrent*)c
+{
+ return ICE_AUTORELEASE(ICE_RETAIN(ipv6 ? _ipv6 : _ipv4));
+}
+@end
- Ice::ObjectAdapterPtr adapter = _communicator->createObjectAdapter("ControllerAdapter");
- Ice::Identity ident;
+@implementation ViewController
+- (void) startController
+{
+ NSString* ipv4 = [interfacesIPv4 objectAtIndex:[interfaceIPv4 selectedRowInComponent:0]];
+ NSString* ipv6 = [interfacesIPv6 objectAtIndex:[interfaceIPv6 selectedRowInComponent:0]];
+
+ ICEInitializationData* initData = [ICEInitializationData initializationData];
+ initData.properties = [ICEUtil createProperties];
+ [initData.properties setProperty:@"Ice.ThreadPool.Server.SizeMax" value:@"10"];
+ [initData.properties setProperty:@"Ice.Plugin.IceDiscovery" value:@"1"];
+ [initData.properties setProperty:@"IceDiscovery.DomainId" value:@"TestController"];
+ [initData.properties setProperty:@"IceDiscovery.Interface" value:ipv4];
+ [initData.properties setProperty:@"Ice.Default.Host" value:ipv4];
+ [initData.properties setProperty:@"ControllerAdapter.Endpoints" value:@"tcp"];
+ //[initData.properties setProperty:@"Ice.Trace.Network", @"2");
+ //[initData.properties setProperty:@"Ice.Trace.Protocol", @"2");
+ [initData.properties setProperty:@"ControllerAdapter.AdapterId" value:[ICEUtil generateUUID]];
+
+ communicator = ICE_RETAIN([ICEUtil createCommunicator:initData]);
+
+ id<ICEObjectAdapter> adapter = [communicator createObjectAdapter:@"ControllerAdapter"];
+ ICEIdentity* ident = [ICEIdentity identity];
#if TARGET_IPHONE_SIMULATOR != 0
- ident.category = "iPhoneSimulator";
+ ident.category = @"iPhoneSimulator";
#else
- ident.category = "iPhoneOS";
+ ident.category = @"iPhoneOS";
#endif
- ident.name = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
- adapter->add(ICE_MAKE_SHARED(ProcessControllerI, controller), ident);
- adapter->activate();
+ ident.name = [[NSBundle mainBundle] bundleIdentifier];
+ [adapter add:[[ProcessControllerI alloc] init:self ipv4:ipv4 ipv6:ipv6] identity:ident];
+ [adapter activate];
}
-
-ControllerHelper::~ControllerHelper()
+- (void) stopController
{
- _communicator->destroy();
- _communicator = 0;
+ [communicator destroy];
+ ICE_RELEASE(communicator);
+ communicator = nil;
}
-
-static ControllerHelper* controllerHelper = 0;
-
-@implementation ViewController
-
- (void)viewDidLoad
{
[super viewDidLoad];
- controllerHelper = new ControllerHelper(self);
+ ICEregisterIceDiscovery(NO);
+
+ //
+ // Search for local network interfaces
+ //
+ interfacesIPv4 = ICE_RETAIN([NSMutableArray array]);
+ [interfacesIPv4 addObject:@"127.0.0.1"];
+ interfacesIPv6 = ICE_RETAIN([NSMutableArray array]);
+ [interfacesIPv6 addObject:@"::1"];
+ struct ifaddrs* ifap;
+ if(getifaddrs(&ifap) == 0)
+ {
+ struct ifaddrs* curr = ifap;
+ while(curr != 0)
+ {
+ if(curr->ifa_addr && curr->ifa_flags & IFF_UP && !(curr->ifa_flags & IFF_LOOPBACK))
+ {
+ if(curr->ifa_addr->sa_family == AF_INET)
+ {
+ char buf[INET_ADDRSTRLEN];
+ const struct sockaddr_in *addr = (const struct sockaddr_in*)curr->ifa_addr;
+ if(inet_ntop(AF_INET, &addr->sin_addr, buf, INET_ADDRSTRLEN))
+ {
+ [interfacesIPv4 addObject:[NSString stringWithUTF8String:buf]];
+ }
+ }
+ else if(curr->ifa_addr->sa_family == AF_INET6)
+ {
+ char buf[INET6_ADDRSTRLEN];
+ const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)curr->ifa_addr;
+ if(inet_ntop(AF_INET6, &addr6->sin6_addr, buf, INET6_ADDRSTRLEN))
+ {
+ [interfacesIPv6 addObject:[NSString stringWithUTF8String:buf]];
+ }
+ }
+ }
+ curr = curr->ifa_next;
+ }
+ freeifaddrs(ifap);
+ }
+
+ // By default, use the loopback
+ [interfaceIPv4 selectRow:0 inComponent:0 animated:NO];
+ [interfaceIPv6 selectRow:0 inComponent:0 animated:NO];
+ [self startController];
}
+
- (void) dealloc
{
- delete controllerHelper;
+ [self stopController];
+#if defined(__clang__) && !__has_feature(objc_arc)
+ [interfacesIPv4 release];
+ [interfacesIPv6 release];
+ [super dealloc];
+#endif
}
+
-(void) write:(NSString*)msg
{
[output insertText:msg];
[output layoutIfNeeded];
[output scrollRangeToVisible:NSMakeRange([output.text length] - 1, 1)];
}
+
+#pragma mark ViewController
+
-(void) print:(NSString*)msg
{
[self performSelectorOnMainThread:@selector(write:) withObject:msg waitUntilDone:NO];
@@ -387,4 +423,44 @@ static ControllerHelper* controllerHelper = 0;
{
[self print:[msg stringByAppendingString:@"\n"]];
}
+
+#pragma mark UIPickerViewDelegate
+
+- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
+{
+ if(pickerView == interfaceIPv4)
+ {
+ return [interfacesIPv4 objectAtIndex:row];
+ }
+ else
+ {
+ return [interfacesIPv6 objectAtIndex:row];
+ }
+}
+
+- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
+{
+ [self stopController];
+ [self startController];
+}
+
+#pragma mark UIPickerViewDataSource
+
+- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
+{
+ return 1;
+}
+
+- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
+{
+ if(pickerView == interfaceIPv4)
+ {
+ return interfacesIPv4.count;
+ }
+ else
+ {
+ return interfacesIPv6.count;
+ }
+}
+
@end