Dailycode.info

Short solution for short problems

iOS: Make your app react to connectivity change (iOS6)

* iOS7 see note at the end of this post first!

When you have an enterprise app, used for production follow up or something, were being online is crucial, connectivity loss or even a short fall out can bring frustrations and loss of data.

Using web services, the app will keep on working when there is no connection, simply throws errors when trying to fetch data or save data. To make the app more responsive, I build in a simple connectivity check so only offline functionality will be available.

To check if there is a WIFI or 3G connection, you can use the Reachability class given by Apple. I attached the file to this post: 

Reachability.h (3.63 kb)

Reachability.m (9.26 kb) 

You can also find it here: https://developer.apple.com/Library/ios/samplecode/Reachability/Introduction/Intro.html

Now once you added the Reachability.h and .m file to your project, you can simply use this code to check for connectivity:

Add this variable to your view controller:

 Reachability *reachability;

Then in the view load initialise it and add a notifier to it, so your app is notified when there is a change in the connectivity:

 reachability = [ReachabilityreachabilityForInternetConnection];

 [reachabilitystartNotifier];

    

 [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(reachabilityDidChange:) name:kReachabilityChangedNotificationobject:reachability];

Now when the connectivity changes, the reachabilityDidChange is called:

- (void)reachabilityDidChange:(NSNotification *)notification

{

    [selfCheckInfo];

    NetworkStatus status = [reachabilitycurrentReachabilityStatus];

    

    if(status == NotReachable)

    {

        self.colVwDashBoard.backgroundColor = [UIColorredColor];

    }

    else if (status == ReachableViaWiFi || status == ReachableViaWWAN)

    {

        self.colVwDashBoard.backgroundColor = [UIColorcolorWithRed:204.0/255.0green:204.0/255.0blue:204.0/255.0alpha:1];

    }

 

}

What I'm doing, is check if there is WIFI or 3G and if not, I will make the collection view background red, you could disable all functionality that needs connection.

In fact thats all there is. Easy right?

 

After upgrading to iOS 7 on some devices, this implementation was not properly working, so I switched to AFNetworking class, I will post the easy implementation soon on this blog, I'll try to find time to work out a small and clear example.

When connection is lost, background turns red and only the camera icon will respond to clicks:

 

 

 

When connection is back, the background turns gray again:


The EntitySet name ‘ ' could not be found.

Frustrating error, easy to fix, hard to find!

Server Error in '/' Application.


The EntitySet name 'Entities.GP_MES_Complaint' could not be found. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The EntitySet name 'Entities.GP_MES_Complaint' could not be found.

Source Error: 

 

Line 104:        public ObjectSet<GP_MES_Complaint> GP_MES_Complaint

Line 105:        {

Line 106:            get { return _gP_MES_Complaint  ?? (_gP_MES_Complaint = CreateObjectSet<GP_MES_Complaint>("GP_MES_Complaint")); }

Line 107:        }

Line 108:        private ObjectSet<GP_MES_Complaint> _gP_MES_Complaint;


In my case I made a mistake in the entity connection string. Because I’m working with multiple edmx models on the same database, I just copied the connection string. But then the entity framework has troubles since it adds mapping stuff to the default connection string:

   <add key="GMConnectionString" value="metadata=res://*/GMModel.csdl|res://*/GMModel.ssdl|res://*/GMModel.msl;provider=System.Data.SqlClient;provider connection string='Data Source…

    <add key="GMSysConnectionString" value="metadata=res://*/SYS.GMSystemModel.csdl|res://*/SYS.GMSystemModel.ssdl|res://*/SYS.GMSystemModel.msl;provider=System.Data.SqlClient;provider connection string='Data Source…

 

 My mistake was I used the connection string of an existing edmx model, but I had to change it to map the edmx model. Haaa. Frustrating!

 

 <add key="GMViewsConnectionString" value="metadata=res://*/VIEWS.GMViewsModel.csdl|res://*/VIEWS.GMViewsModel.ssdl|res://*/VIEWS.GMViewsModel.msl;provider=System.Data.SqlClient;provider connection string='Data Source…


Entity Framework and There is already an open DataReader associated with this Command which must be closed first.

There is already an open DataReader associated with this Command which must be closed first.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

Source Error: 

When using the entity Framework I got that error. Got it when I was looping within a loop. Since there was no association between the objects, I had to do a loop en inner loop, it looks like this:

foreach (GP_PROJ_ProjectSteps step in Ents.GP_PROJ_ProjectSteps.Where(s=>s.ProjectID == project.ProjectID))

{

    foreach (GP_PROJ_ProjectTasks task in Ents.GP_PROJ_ProjectTasks.Where(d => d.StepID == step.StepID))

    {

        Ents.GP_PROJ_ProjectTasks.DeleteObject(task);

    }

    Ents.GP_PROJ_ProjectSteps.DeleteObject(step);

}

Ents.GP_PROJ_Projects.DeleteObject(project);

Ents.SaveChanges();

 

The solution to this problem was to allow or enable Multiple Active Result Sets (MARS). This is done in your connection string:

Data Source=DBServer;Initial Catalog=MyDB;Persist Security Info=True;User ID=DBUSER; Password=PWD;MultipleActiveResultSets=true;