There is an org-mode FAQ here that recommends using a command to generate a separate task for each day. That might seem heavyweight, but the FAQ suggests reading this blog post for the pros of this approach. The folding nature of org makes it easy to hide long lists.
If you prefer infinite recurrence, note that there are two kinds. There is an infinite task recurrence, like in the question, which uses SCHEDULED and the plus time increment syntax. This entry only shows up in the agenda once and is regenerated each time you mark it completed, leaving a completion log. A fairly simple solution would be to use this and schedule a task on the day that the recurrence should end, reminding you to end the recurrence.
An infinite calendar recurrence would be a case where, instead of a single timestamp, you can use an elisp expression to match multiple dates. These entries show up on the agenda on every matching date. There is an org-mode FAQ about using this, here. The thing about this approach is, you can't combine it with regeneration. I tried inserting one of these expressions into the SCHEDULED: field on a task and it works but still behaves like a recurring calendar entry, not a recurring task. I tried adding increments like +1d before the close angle bracket and it didn't seem to do anything. It's not apparently possible to get a task with this kind of customized scheduling to regenerate when it's marked as done. Even if it has a TODO keyword, it's a single task, that happens to show up multiple times, so if you mark it done it's done everywhere. You could use this method if you don't need to log completion times, or you could, for example, reset from DONE back to TODO when you review your agenda in the morning. Or submit a patch to make TODOs with elisp based recurrences regenerate :)
See also the manual node for repeated tasks.